1/*
2 * Copyright (c) 2008-2023 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29/* $FreeBSD: src/sys/netkey/key.c,v 1.16.2.13 2002/07/24 18:17:40 ume Exp $ */
30/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 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 * This code is referd to RFC 2367
63 */
64
65#include <machine/endian.h>
66#include <sys/types.h>
67#include <sys/param.h>
68#include <sys/systm.h>
69#include <sys/kernel.h>
70#include <sys/mbuf.h>
71#include <sys/domain.h>
72#include <sys/protosw.h>
73#include <sys/malloc.h>
74#include <sys/socket.h>
75#include <sys/socketvar.h>
76#include <sys/sysctl.h>
77#include <sys/errno.h>
78#include <sys/proc.h>
79#include <sys/queue.h>
80#include <sys/syslog.h>
81#include <sys/mcache.h>
82
83#include <kern/clock.h>
84#include <kern/locks.h>
85
86#include <net/if.h>
87#include <net/route.h>
88#include <net/raw_cb.h>
89
90#include <netinet/in.h>
91#include <netinet/in_systm.h>
92#include <netinet/ip.h>
93#include <netinet/in_var.h>
94
95#include <netinet/ip6.h>
96#include <netinet6/in6_var.h>
97#include <netinet6/ip6_var.h>
98
99#include <net/pfkeyv2.h>
100#include <netkey/keydb.h>
101#include <netkey/key.h>
102#include <netkey/keysock.h>
103#include <netkey/key_debug.h>
104#include <stdarg.h>
105#include <libkern/crypto/rand.h>
106
107#include <netinet6/ipsec.h>
108#include <netinet6/ipsec6.h>
109#include <netinet6/ah.h>
110#include <netinet6/ah6.h>
111#if IPSEC_ESP
112#include <netinet6/esp.h>
113#include <netinet6/esp6.h>
114#endif
115
116
117/* randomness */
118#include <sys/random.h>
119
120#include <net/net_osdep.h>
121
122#if SKYWALK
123#include <skywalk/namespace/flowidns.h>
124#endif /* SKYWALK */
125
126#define FULLMASK 0xff
127
128static LCK_GRP_DECLARE(sadb_mutex_grp, "sadb");
129LCK_MTX_DECLARE(sadb_mutex_data, &sadb_mutex_grp);
130
131/*
132 * Note on SA reference counting:
133 * - SAs that are not in DEAD state will have (total external reference + 1)
134 * following value in reference count field. they cannot be freed and are
135 * referenced from SA header.
136 * - SAs that are in DEAD state will have (total external reference)
137 * in reference count field. they are ready to be freed. reference from
138 * SA header will be removed in key_delsav(), when the reference count
139 * field hits 0 (= no external reference other than from SA header.
140 */
141
142u_int32_t key_debug_level = 0; //### our sysctl is not dynamic
143static int key_timehandler_running = 0;
144static u_int key_spi_trycnt = 1000;
145static u_int32_t key_spi_minval = 0x100;
146static u_int32_t key_spi_maxval = 0x0fffffff; /* XXX */
147static u_int32_t policy_id = 0;
148static u_int32_t key_int_random = 60; /*interval to initialize randseed,1(m)*/
149static u_int32_t key_larval_lifetime = 30; /* interval to expire acquiring, 30(s)*/
150static u_int32_t key_blockacq_count = 10; /* counter for blocking SADB_ACQUIRE.*/
151static u_int32_t key_blockacq_lifetime = 20; /* lifetime for blocking SADB_ACQUIRE.*/
152static int key_preferred_oldsa = 0; /* preferred old sa rather than new sa.*/
153__private_extern__ int natt_keepalive_interval = 20; /* interval between natt keepalives.*/
154static u_int32_t ipsec_policy_count = 0;
155static u_int32_t ipsec_sav_count = 0;
156
157static u_int32_t acq_seq = 0;
158static int key_tick_init_random = 0;
159static u_int64_t up_time = 0;
160__private_extern__ u_int64_t natt_now = 0;
161
162static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD */
163static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */
164static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1];
165static LIST_HEAD(_custom_sahtree, secashead) custom_sahtree;
166/* registed list */
167
168#define SPIHASHSIZE 128
169#define SPIHASH(x) (((x) ^ ((x) >> 16)) % SPIHASHSIZE)
170static LIST_HEAD(_spihash, secasvar) spihash[SPIHASHSIZE];
171
172#ifndef IPSEC_NONBLOCK_ACQUIRE
173static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */
174#endif
175static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */
176
177struct key_cb key_cb;
178
179/* search order for SAs */
180static const u_int saorder_state_valid_prefer_old[] = {
181 SADB_SASTATE_DYING, SADB_SASTATE_MATURE,
182};
183static const u_int saorder_state_valid_prefer_new[] = {
184 SADB_SASTATE_MATURE, SADB_SASTATE_DYING,
185};
186static const u_int saorder_state_alive[] = {
187 /* except DEAD */
188 SADB_SASTATE_MATURE, SADB_SASTATE_DYING, SADB_SASTATE_LARVAL
189};
190static const u_int saorder_state_any[] = {
191 SADB_SASTATE_MATURE, SADB_SASTATE_DYING,
192 SADB_SASTATE_LARVAL, SADB_SASTATE_DEAD
193};
194
195static const int minsize[] = {
196 sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */
197 sizeof(struct sadb_sa), /* SADB_EXT_SA */
198 sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_CURRENT */
199 sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_HARD */
200 sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_SOFT */
201 sizeof(struct sadb_address), /* SADB_EXT_ADDRESS_SRC */
202 sizeof(struct sadb_address), /* SADB_EXT_ADDRESS_DST */
203 sizeof(struct sadb_address), /* SADB_EXT_ADDRESS_PROXY */
204 sizeof(struct sadb_key), /* SADB_EXT_KEY_AUTH */
205 sizeof(struct sadb_key), /* SADB_EXT_KEY_ENCRYPT */
206 sizeof(struct sadb_ident), /* SADB_EXT_IDENTITY_SRC */
207 sizeof(struct sadb_ident), /* SADB_EXT_IDENTITY_DST */
208 sizeof(struct sadb_sens), /* SADB_EXT_SENSITIVITY */
209 sizeof(struct sadb_prop), /* SADB_EXT_PROPOSAL */
210 sizeof(struct sadb_supported), /* SADB_EXT_SUPPORTED_AUTH */
211 sizeof(struct sadb_supported), /* SADB_EXT_SUPPORTED_ENCRYPT */
212 sizeof(struct sadb_spirange), /* SADB_EXT_SPIRANGE */
213 0, /* SADB_X_EXT_KMPRIVATE */
214 sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */
215 sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */
216 sizeof(struct sadb_session_id), /* SADB_EXT_SESSION_ID */
217 sizeof(struct sadb_sastat), /* SADB_EXT_SASTAT */
218 sizeof(struct sadb_x_ipsecif), /* SADB_X_EXT_IPSECIF */
219 sizeof(struct sadb_address), /* SADB_X_EXT_ADDR_RANGE_SRC_START */
220 sizeof(struct sadb_address), /* SADB_X_EXT_ADDR_RANGE_SRC_END */
221 sizeof(struct sadb_address), /* SADB_X_EXT_ADDR_RANGE_DST_START */
222 sizeof(struct sadb_address), /* SADB_X_EXT_ADDR_RANGE_DST_END */
223 sizeof(struct sadb_address), /* SADB_EXT_MIGRATE_ADDRESS_SRC */
224 sizeof(struct sadb_address), /* SADB_EXT_MIGRATE_ADDRESS_DST */
225 sizeof(struct sadb_x_ipsecif), /* SADB_X_EXT_MIGRATE_IPSECIF */
226};
227static const int maxsize[] = {
228 sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */
229 sizeof(struct sadb_sa_2), /* SADB_EXT_SA */
230 sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_CURRENT */
231 sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_HARD */
232 sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_SOFT */
233 0, /* SADB_EXT_ADDRESS_SRC */
234 0, /* SADB_EXT_ADDRESS_DST */
235 0, /* SADB_EXT_ADDRESS_PROXY */
236 0, /* SADB_EXT_KEY_AUTH */
237 0, /* SADB_EXT_KEY_ENCRYPT */
238 0, /* SADB_EXT_IDENTITY_SRC */
239 0, /* SADB_EXT_IDENTITY_DST */
240 0, /* SADB_EXT_SENSITIVITY */
241 0, /* SADB_EXT_PROPOSAL */
242 0, /* SADB_EXT_SUPPORTED_AUTH */
243 0, /* SADB_EXT_SUPPORTED_ENCRYPT */
244 sizeof(struct sadb_spirange), /* SADB_EXT_SPIRANGE */
245 0, /* SADB_X_EXT_KMPRIVATE */
246 0, /* SADB_X_EXT_POLICY */
247 sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */
248 0, /* SADB_EXT_SESSION_ID */
249 0, /* SADB_EXT_SASTAT */
250 sizeof(struct sadb_x_ipsecif), /* SADB_X_EXT_IPSECIF */
251 0, /* SADB_X_EXT_ADDR_RANGE_SRC_START */
252 0, /* SADB_X_EXT_ADDR_RANGE_SRC_END */
253 0, /* SADB_X_EXT_ADDR_RANGE_DST_START */
254 0, /* SADB_X_EXT_ADDR_RANGE_DST_END */
255 0, /* SADB_EXT_MIGRATE_ADDRESS_SRC */
256 0, /* SADB_EXT_MIGRATE_ADDRESS_DST */
257 sizeof(struct sadb_x_ipsecif), /* SADB_X_EXT_MIGRATE_IPSECIF */
258};
259
260static int ipsec_esp_keymin = 256;
261static int ipsec_esp_auth = 0;
262static int ipsec_ah_keymin = 128;
263
264SYSCTL_DECL(_net_key);
265/* Thread safe: no accumulated state */
266SYSCTL_INT(_net_key, KEYCTL_DEBUG_LEVEL, debug, CTLFLAG_RW | CTLFLAG_LOCKED, \
267 &key_debug_level, 0, "");
268
269
270/* max count of trial for the decision of spi value */
271SYSCTL_INT(_net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW | CTLFLAG_LOCKED, \
272 &key_spi_trycnt, 0, "");
273
274/* minimum spi value to allocate automatically. */
275SYSCTL_INT(_net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW | CTLFLAG_LOCKED, \
276 &key_spi_minval, 0, "");
277
278/* maximun spi value to allocate automatically. */
279SYSCTL_INT(_net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW | CTLFLAG_LOCKED, \
280 &key_spi_maxval, 0, "");
281
282/* interval to initialize randseed */
283SYSCTL_INT(_net_key, KEYCTL_RANDOM_INT, int_random, CTLFLAG_RW | CTLFLAG_LOCKED, \
284 &key_int_random, 0, "");
285
286/* lifetime for larval SA; thread safe due to > compare */
287SYSCTL_INT(_net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED, \
288 &key_larval_lifetime, 0, "");
289
290/* counter for blocking to send SADB_ACQUIRE to IKEd */
291SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_COUNT, blockacq_count, CTLFLAG_RW | CTLFLAG_LOCKED, \
292 &key_blockacq_count, 0, "");
293
294/* lifetime for blocking to send SADB_ACQUIRE to IKEd: Thread safe, > compare */
295SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED, \
296 &key_blockacq_lifetime, 0, "");
297
298/* ESP auth */
299SYSCTL_INT(_net_key, KEYCTL_ESP_AUTH, esp_auth, CTLFLAG_RW | CTLFLAG_LOCKED, \
300 &ipsec_esp_auth, 0, "");
301
302/* minimum ESP key length */
303SYSCTL_INT(_net_key, KEYCTL_ESP_KEYMIN, esp_keymin, CTLFLAG_RW | CTLFLAG_LOCKED, \
304 &ipsec_esp_keymin, 0, "");
305
306/* minimum AH key length */
307SYSCTL_INT(_net_key, KEYCTL_AH_KEYMIN, ah_keymin, CTLFLAG_RW | CTLFLAG_LOCKED, \
308 &ipsec_ah_keymin, 0, "");
309
310/* perfered old SA rather than new SA */
311SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA, prefered_oldsa, CTLFLAG_RW | CTLFLAG_LOCKED, \
312 &key_preferred_oldsa, 0, "");
313
314/* time between NATT keepalives in seconds, 0 disabled */
315SYSCTL_INT(_net_key, KEYCTL_NATT_KEEPALIVE_INTERVAL, natt_keepalive_interval, CTLFLAG_RW | CTLFLAG_LOCKED, \
316 &natt_keepalive_interval, 0, "");
317
318/* PF_KEY statistics */
319SYSCTL_STRUCT(_net_key, KEYCTL_PFKEYSTAT, pfkeystat, CTLFLAG_RD | CTLFLAG_LOCKED, \
320 &pfkeystat, pfkeystat, "");
321
322#ifndef LIST_FOREACH
323#define LIST_FOREACH(elm, head, field) \
324for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field))
325#endif
326#define __LIST_CHAINED(elm) \
327(!((elm)->chain.le_next == NULL && (elm)->chain.le_prev == NULL))
328#define LIST_INSERT_TAIL(head, elm, type, field) \
329do {\
330struct type *curelm = LIST_FIRST(head); \
331if (curelm == NULL) {\
332LIST_INSERT_HEAD(head, elm, field); \
333} else { \
334while (LIST_NEXT(curelm, field)) \
335curelm = LIST_NEXT(curelm, field);\
336LIST_INSERT_AFTER(curelm, elm, field);\
337}\
338} while (0)
339
340#define KEY_CHKSASTATE(head, sav, name) \
341if ((head) != (sav)) { \
342ipseclog((LOG_DEBUG, "%s: state mismatched (TREE=%d SA=%d)\n", \
343(name), (head), (sav))); \
344continue; \
345} \
346
347#define KEY_CHKSPDIR(head, sp, name) \
348do { \
349if ((head) != (sp)) { \
350ipseclog((LOG_DEBUG, "%s: direction mismatched (TREE=%d SP=%d), " \
351"anyway continue.\n", \
352(name), (head), (sp))); \
353} \
354} while (0)
355
356/*
357 * set parameters into secpolicyindex buffer.
358 * Must allocate secpolicyindex buffer passed to this function.
359 */
360#define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, ifp, s_s, s_e, d_s, d_e, idx) \
361do { \
362bzero((idx), sizeof(struct secpolicyindex)); \
363(idx)->dir = (_dir); \
364(idx)->prefs = (ps); \
365(idx)->prefd = (pd); \
366(idx)->ul_proto = (ulp); \
367(idx)->internal_if = (ifp); \
368if (s) bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len); \
369if (d) bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len); \
370if (s_s) bcopy((s_s), &(idx)->src_range.start, ((struct sockaddr *)(s_s))->sa_len); \
371if (s_e) bcopy((s_e), &(idx)->src_range.end, ((struct sockaddr *)(s_e))->sa_len); \
372if (d_s) bcopy((d_s), &(idx)->dst_range.start, ((struct sockaddr *)(d_s))->sa_len); \
373if (d_e) bcopy((d_e), &(idx)->dst_range.end, ((struct sockaddr *)(d_e))->sa_len); \
374} while (0)
375
376/*
377 * set parameters into secasindex buffer.
378 * Must allocate secasindex buffer before calling this function.
379 */
380#define KEY_SETSECASIDX(p, m, r, s, d, ifi, idx) \
381do { \
382bzero((idx), sizeof(struct secasindex)); \
383(idx)->proto = (p); \
384(idx)->mode = (m); \
385(idx)->reqid = (r); \
386bcopy((s), &(idx)->src, ((const struct sockaddr *)(s))->sa_len); \
387bcopy((d), &(idx)->dst, ((const struct sockaddr *)(d))->sa_len); \
388(idx)->ipsec_ifindex = (ifi); \
389} while (0)
390
391/* key statistics */
392struct _keystat {
393 u_int32_t getspi_count; /* the avarage of count to try to get new SPI */
394} keystat;
395
396struct sadb_msghdr {
397 struct sadb_msg *msg;
398 struct sadb_ext *ext[SADB_EXT_MAX + 1];
399 int extoff[SADB_EXT_MAX + 1];
400 int extlen[SADB_EXT_MAX + 1];
401};
402
403static struct secpolicy *__key_getspbyid(u_int32_t id);
404static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int, u_int16_t);
405static int key_do_get_translated_port(struct secashead *, struct secasvar *, u_int);
406static void key_delsp(struct secpolicy *);
407static struct secpolicy *key_getsp(struct secpolicyindex *);
408static u_int16_t key_newreqid(void);
409static struct mbuf *key_gather_mbuf(struct mbuf *,
410 const struct sadb_msghdr *, int, int, int *);
411static int key_spdadd(struct socket *, struct mbuf *,
412 const struct sadb_msghdr *);
413static u_int32_t key_getnewspid(void);
414static int key_spddelete(struct socket *, struct mbuf *,
415 const struct sadb_msghdr *);
416static int key_spddelete2(struct socket *, struct mbuf *,
417 const struct sadb_msghdr *);
418static int key_spdenable(struct socket *, struct mbuf *,
419 const struct sadb_msghdr *);
420static int key_spddisable(struct socket *, struct mbuf *,
421 const struct sadb_msghdr *);
422static int key_spdget(struct socket *, struct mbuf *,
423 const struct sadb_msghdr *);
424static int key_spdflush(struct socket *, struct mbuf *,
425 const struct sadb_msghdr *);
426static int key_spddump(struct socket *, struct mbuf *,
427 const struct sadb_msghdr *);
428static struct mbuf *key_setdumpsp(struct secpolicy *,
429 u_int8_t, u_int32_t, u_int32_t);
430static u_int key_getspreqmsglen(struct secpolicy *);
431static int key_spdexpire(struct secpolicy *);
432static struct secashead *key_newsah(struct secasindex *, ifnet_t, u_int, u_int8_t, u_int16_t);
433static struct secasvar *key_newsav(struct mbuf *,
434 const struct sadb_msghdr *, struct secashead *, int *,
435 struct socket *);
436static struct secashead *key_getsah(struct secasindex *, u_int16_t);
437static struct secasvar *key_checkspidup(struct secasindex *, u_int32_t);
438static void key_setspi __P((struct secasvar *, u_int32_t));
439static struct secasvar *key_getsavbyspi(struct secashead *, u_int32_t);
440static int key_setsaval(struct secasvar *, struct mbuf *,
441 const struct sadb_msghdr *);
442static int key_mature(struct secasvar *);
443static struct mbuf *key_setdumpsa(struct secasvar *, u_int8_t,
444 u_int8_t, u_int32_t, u_int32_t);
445static struct mbuf *key_setsadbmsg(u_int8_t, u_int16_t, u_int8_t,
446 u_int32_t, pid_t, u_int16_t);
447static struct mbuf *key_setsadbsa(struct secasvar *);
448static struct mbuf *key_setsadbaddr(u_int16_t,
449 struct sockaddr *, size_t, u_int8_t);
450static struct mbuf *key_setsadbipsecif(ifnet_t, ifnet_t, ifnet_t, u_int8_t);
451static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t, u_int16_t);
452static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
453 u_int32_t);
454static struct mbuf *key_setsalifecurr(struct sadb_lifetime *);
455static void *key_newbuf(const void *, u_int);
456static int key_ismyaddr6(struct sockaddr_in6 *);
457static void key_update_natt_keepalive_timestamp(struct secasvar *, struct secasvar *);
458
459/* flags for key_cmpsaidx() */
460#define CMP_HEAD 0x1 /* protocol, addresses. */
461#define CMP_PORT 0x2 /* additionally HEAD, reqid, mode. */
462#define CMP_REQID 0x4 /* additionally HEAD, reqid. */
463#define CMP_MODE 0x8 /* additionally mode. */
464#define CMP_EXACTLY 0xF /* all elements. */
465static int key_cmpsaidx(struct secasindex *, struct secasindex *, int);
466
467static int key_cmpspidx_exactly(struct secpolicyindex *,
468 struct secpolicyindex *);
469static int key_cmpspidx_withmask(struct secpolicyindex *,
470 struct secpolicyindex *);
471static int key_sockaddrcmp(struct sockaddr *, struct sockaddr *, int);
472static int key_is_addr_in_range(struct sockaddr_storage *, struct secpolicyaddrrange *);
473static int key_bbcmp(caddr_t, caddr_t, u_int);
474static void key_srandom(void);
475static u_int8_t key_satype2proto(u_int8_t);
476static u_int8_t key_proto2satype(u_int16_t);
477
478static int key_getspi(struct socket *, struct mbuf *,
479 const struct sadb_msghdr *);
480static u_int32_t key_do_getnewspi(struct sadb_spirange *, struct secasindex *);
481static int key_update(struct socket *, struct mbuf *,
482 const struct sadb_msghdr *);
483static int key_add(struct socket *, struct mbuf *, const struct sadb_msghdr *);
484static struct mbuf *key_getmsgbuf_x1(struct mbuf *, const struct sadb_msghdr *);
485static int key_delete(struct socket *, struct mbuf *,
486 const struct sadb_msghdr *);
487static int key_get(struct socket *, struct mbuf *, const struct sadb_msghdr *);
488
489static void key_getcomb_setlifetime(struct sadb_comb *);
490#if IPSEC_ESP
491static struct mbuf *key_getcomb_esp(void);
492#endif
493static struct mbuf *key_getcomb_ah(void);
494static struct mbuf *key_getprop(const struct secasindex *);
495
496static int key_acquire(struct secasindex *, struct secpolicy *);
497#ifndef IPSEC_NONBLOCK_ACQUIRE
498static struct secacq *key_newacq(struct secasindex *);
499static struct secacq *key_getacq(struct secasindex *);
500static struct secacq *key_getacqbyseq(u_int32_t);
501#endif
502static struct secspacq *key_newspacq(struct secpolicyindex *);
503static struct secspacq *key_getspacq(struct secpolicyindex *);
504static int key_acquire2(struct socket *, struct mbuf *,
505 const struct sadb_msghdr *);
506static int key_register(struct socket *, struct mbuf *,
507 const struct sadb_msghdr *);
508static int key_expire(struct secasvar *);
509static int key_flush(struct socket *, struct mbuf *,
510 const struct sadb_msghdr *);
511static int key_dump(struct socket *, struct mbuf *, const struct sadb_msghdr *);
512static int key_promisc(struct socket *, struct mbuf *,
513 const struct sadb_msghdr *);
514static int key_senderror(struct socket *, struct mbuf *, int);
515static int key_validate_ext(const struct sadb_ext *, int);
516static int key_align(struct mbuf *, struct sadb_msghdr *);
517static struct mbuf *key_alloc_mbuf(int);
518static int key_getsastat(struct socket *, struct mbuf *, const struct sadb_msghdr *);
519static int key_migrate(struct socket *, struct mbuf *, const struct sadb_msghdr *);
520static void bzero_keys(const struct sadb_msghdr *);
521
522extern int ipsec_bypass;
523extern int esp_udp_encap_port;
524int ipsec_send_natt_keepalive(struct secasvar *sav);
525bool ipsec_fill_offload_frame(ifnet_t ifp, struct secasvar *sav, struct ifnet_keepalive_offload_frame *frame, size_t frame_data_offset);
526
527void key_init(struct protosw *, struct domain *);
528
529static u_int64_t
530key_get_continuous_time_ns(void)
531{
532 u_int64_t current_time_ns = 0;
533 absolutetime_to_nanoseconds(abstime: mach_continuous_time(), result: &current_time_ns);
534 return current_time_ns;
535}
536
537static u_int64_t
538key_convert_continuous_time_ns(u_int64_t time_value)
539{
540 // Pass through 0 as it indicates value is not set
541 if (time_value == 0) {
542 return 0;
543 }
544
545 // Get current time
546 clock_sec_t time_sec;
547 clock_usec_t time_usec;
548 clock_get_calendar_microtime(secs: &time_sec, microsecs: &time_usec);
549
550 // Get time offset
551 const u_int64_t time_offset_ns = key_get_continuous_time_ns() - time_value;
552 const clock_sec_t time_offset_sec = time_offset_ns / NSEC_PER_SEC;
553 const clock_usec_t time_offset_usec = (u_int32_t)(time_offset_ns - (time_offset_sec * NSEC_PER_SEC)) / NSEC_PER_USEC;
554
555 // Subtract offset from current time
556 time_sec -= time_offset_sec;
557 if (time_offset_usec > time_usec) {
558 time_sec--;
559 time_usec = USEC_PER_SEC - (time_offset_usec - time_usec);
560 } else {
561 time_usec -= time_offset_usec;
562 }
563
564 // Return result rounded to nearest second
565 return time_sec + ((time_usec >= (USEC_PER_SEC / 2)) ? 1 : 0);
566}
567
568static void
569key_get_flowid(struct secasvar *sav)
570{
571#if SKYWALK
572 struct flowidns_flow_key fk;
573 struct secashead *sah = sav->sah;
574
575 if ((sah->dir != IPSEC_DIR_OUTBOUND) && (sah->dir != IPSEC_DIR_ANY)) {
576 return;
577 }
578
579 bzero(s: &fk, n: sizeof(fk));
580 ASSERT(sah->saidx.src.ss_family == sah->saidx.dst.ss_family);
581 switch (sah->saidx.src.ss_family) {
582 case AF_INET:
583 ASSERT(sah->saidx.src.ss_len == sizeof(struct sockaddr_in));
584 ASSERT(sah->saidx.dst.ss_len == sizeof(struct sockaddr_in));
585 fk.ffk_laddr_v4 =
586 ((struct sockaddr_in *)&(sah->saidx.src))->sin_addr;
587 fk.ffk_raddr_v4 =
588 ((struct sockaddr_in *)&(sah->saidx.dst))->sin_addr;
589 break;
590
591 case AF_INET6:
592 ASSERT(sah->saidx.src.ss_len == sizeof(struct sockaddr_in6));
593 ASSERT(sah->saidx.dst.ss_len == sizeof(struct sockaddr_in6));
594 fk.ffk_laddr_v6 =
595 ((struct sockaddr_in6 *)&(sah->saidx.src))->sin6_addr;
596 fk.ffk_raddr_v6 =
597 ((struct sockaddr_in6 *)&(sah->saidx.dst))->sin6_addr;
598 break;
599
600 default:
601 VERIFY(0);
602 break;
603 }
604
605 ASSERT(sav->spi != 0);
606 fk.ffk_spi = sav->spi;;
607 fk.ffk_af = sah->saidx.src.ss_family;
608 fk.ffk_proto = (uint8_t)(sah->saidx.proto);
609
610 flowidns_allocate_flowid(domain: FLOWIDNS_DOMAIN_IPSEC, flow_key: &fk, flowid: &sav->flowid);
611#else /* !SKYWALK */
612 sav->flowid = 0;
613#endif /* !SKYWALK */
614}
615
616static void
617key_release_flowid(struct secasvar *sav)
618{
619#if SKYWALK
620 if (sav->flowid != 0) {
621 flowidns_release_flowid(flowid: sav->flowid);
622 sav->flowid = 0;
623 }
624#else /* !SKYWALK */
625 VERIFY(sav->flowid == 0);
626#endif /* !SKYWALK */
627}
628
629/*
630 * PF_KEY init
631 * setup locks, and then init timer and associated data
632 */
633void
634key_init(struct protosw *pp, struct domain *dp __unused)
635{
636 static int key_initialized = 0;
637 int i;
638
639 VERIFY((pp->pr_flags & (PR_INITIALIZED | PR_ATTACHED)) == PR_ATTACHED);
640
641 _CASSERT(PFKEY_ALIGN8(sizeof(struct sadb_msg)) <= _MHLEN);
642 _CASSERT(MAX_REPLAY_WINDOWS == MBUF_TC_MAX);
643
644 if (key_initialized) {
645 return;
646 }
647 key_initialized = 1;
648
649 for (i = 0; i < SPIHASHSIZE; i++) {
650 LIST_INIT(&spihash[i]);
651 }
652
653 bzero(s: (caddr_t)&key_cb, n: sizeof(key_cb));
654
655 for (i = 0; i < IPSEC_DIR_MAX; i++) {
656 LIST_INIT(&sptree[i]);
657 }
658 ipsec_policy_count = 0;
659
660 LIST_INIT(&sahtree);
661 LIST_INIT(&custom_sahtree);
662
663 for (i = 0; i <= SADB_SATYPE_MAX; i++) {
664 LIST_INIT(&regtree[i]);
665 }
666 ipsec_sav_count = 0;
667
668#ifndef IPSEC_NONBLOCK_ACQUIRE
669 LIST_INIT(&acqtree);
670#endif
671 LIST_INIT(&spacqtree);
672
673 /* system default */
674#if INET
675 ip4_def_policy.policy = IPSEC_POLICY_NONE;
676 ip4_def_policy.refcnt++; /*never reclaim this*/
677#endif
678 ip6_def_policy.policy = IPSEC_POLICY_NONE;
679 ip6_def_policy.refcnt++; /*never reclaim this*/
680
681 key_timehandler_running = 0;
682
683 /* initialize key statistics */
684 keystat.getspi_count = 1;
685
686 esp_init();
687#ifndef __APPLE__
688 printf("IPsec: Initialized Security Association Processing.\n");
689#endif
690}
691
692static void
693key_start_timehandler(void)
694{
695 /* must be called while locked */
696 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
697 if (key_timehandler_running == 0) {
698 key_timehandler_running = 1;
699 (void)timeout((void *)key_timehandler, arg: (void *)0, ticks: hz);
700 }
701
702 /* Turn off the ipsec bypass */
703 if (ipsec_bypass != 0) {
704 ipsec_bypass = 0;
705 }
706}
707
708/* %%% IPsec policy management */
709/*
710 * allocating a SP for OUTBOUND or INBOUND packet.
711 * Must call key_freesp() later.
712 * OUT: NULL: not found
713 * others: found and return the pointer.
714 */
715struct secpolicy *
716key_allocsp(
717 struct secpolicyindex *spidx,
718 u_int dir)
719{
720 struct secpolicy *sp;
721
722 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
723 /* sanity check */
724 if (spidx == NULL) {
725 panic("key_allocsp: NULL pointer is passed.");
726 }
727
728 /* check direction */
729 switch (dir) {
730 case IPSEC_DIR_INBOUND:
731 case IPSEC_DIR_OUTBOUND:
732 break;
733 default:
734 panic("key_allocsp: Invalid direction is passed.");
735 }
736
737 /* get a SP entry */
738 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
739 printf("*** objects\n");
740 kdebug_secpolicyindex(spidx));
741
742 lck_mtx_lock(sadb_mutex);
743 LIST_FOREACH(sp, &sptree[dir], chain) {
744 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
745 printf("*** in SPD\n");
746 kdebug_secpolicyindex(&sp->spidx));
747
748 if (sp->state == IPSEC_SPSTATE_DEAD) {
749 continue;
750 }
751
752 /* If the policy is disabled, skip */
753 if (sp->disabled > 0) {
754 continue;
755 }
756
757 /* If the incoming spidx specifies bound if,
758 * ignore unbound policies*/
759 if (spidx->internal_if != NULL
760 && (sp->spidx.internal_if == NULL || sp->ipsec_if == NULL)) {
761 continue;
762 }
763
764 if (key_cmpspidx_withmask(&sp->spidx, spidx)) {
765 goto found;
766 }
767 }
768 lck_mtx_unlock(sadb_mutex);
769 return NULL;
770
771found:
772
773 /* found a SPD entry */
774 sp->lastused = key_get_continuous_time_ns();
775 sp->refcnt++;
776 lck_mtx_unlock(sadb_mutex);
777
778 /* sanity check */
779 KEY_CHKSPDIR(sp->spidx.dir, dir, "key_allocsp");
780 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
781 printf("DP key_allocsp cause refcnt++:%d SP:0x%llx\n",
782 sp->refcnt, (uint64_t)VM_KERNEL_ADDRPERM(sp)));
783 return sp;
784}
785
786/*
787 * return a policy that matches this particular inbound packet.
788 * XXX slow
789 */
790struct secpolicy *
791key_gettunnel(
792 struct sockaddr *osrc,
793 struct sockaddr *odst,
794 struct sockaddr *isrc,
795 struct sockaddr *idst)
796{
797 struct secpolicy *sp;
798 const int dir = IPSEC_DIR_INBOUND;
799 struct ipsecrequest *r1, *r2, *p;
800 struct sockaddr *os, *od, *is, *id;
801 struct secpolicyindex spidx;
802
803 if (isrc->sa_family != idst->sa_family) {
804 ipseclog((LOG_ERR, "protocol family mismatched %d != %d\n.",
805 isrc->sa_family, idst->sa_family));
806 return NULL;
807 }
808
809 lck_mtx_lock(sadb_mutex);
810 LIST_FOREACH(sp, &sptree[dir], chain) {
811 if (sp->state == IPSEC_SPSTATE_DEAD) {
812 continue;
813 }
814
815 r1 = r2 = NULL;
816 for (p = sp->req; p; p = p->next) {
817 if (p->saidx.mode != IPSEC_MODE_TUNNEL) {
818 continue;
819 }
820
821 r1 = r2;
822 r2 = p;
823
824 if (!r1) {
825 /* here we look at address matches only */
826 spidx = sp->spidx;
827 if (isrc->sa_len > sizeof(spidx.src) ||
828 idst->sa_len > sizeof(spidx.dst)) {
829 continue;
830 }
831 bcopy(src: isrc, dst: &spidx.src, n: isrc->sa_len);
832 bcopy(src: idst, dst: &spidx.dst, n: idst->sa_len);
833 if (!key_cmpspidx_withmask(&sp->spidx, &spidx)) {
834 continue;
835 }
836 } else {
837 is = (struct sockaddr *)&r1->saidx.src;
838 id = (struct sockaddr *)&r1->saidx.dst;
839 if (key_sockaddrcmp(is, isrc, 0) ||
840 key_sockaddrcmp(id, idst, 0)) {
841 continue;
842 }
843 }
844
845 os = (struct sockaddr *)&r2->saidx.src;
846 od = (struct sockaddr *)&r2->saidx.dst;
847 if (key_sockaddrcmp(os, osrc, 0) ||
848 key_sockaddrcmp(od, odst, 0)) {
849 continue;
850 }
851
852 goto found;
853 }
854 }
855 lck_mtx_unlock(sadb_mutex);
856 return NULL;
857
858found:
859 sp->lastused = key_get_continuous_time_ns();
860 sp->refcnt++;
861 lck_mtx_unlock(sadb_mutex);
862 return sp;
863}
864
865struct secasvar *
866key_alloc_outbound_sav_for_interface(ifnet_t interface, int family,
867 struct sockaddr *src,
868 struct sockaddr *dst)
869{
870 struct secashead *sah;
871 struct secasvar *sav;
872 u_int stateidx;
873 u_int state;
874 const u_int *saorder_state_valid;
875 int arraysize;
876 struct sockaddr_in *sin;
877 u_int16_t dstport;
878 bool strict = true;
879
880 if (interface == NULL) {
881 return NULL;
882 }
883
884 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
885
886 lck_mtx_lock(sadb_mutex);
887
888 do {
889 LIST_FOREACH(sah, &sahtree, chain) {
890 if (sah->state == SADB_SASTATE_DEAD) {
891 continue;
892 }
893 if (sah->ipsec_if == interface &&
894 (family == AF_INET6 || family == AF_INET) &&
895 sah->dir == IPSEC_DIR_OUTBOUND) {
896 if (strict &&
897 sah->saidx.mode == IPSEC_MODE_TRANSPORT &&
898 src != NULL && dst != NULL) {
899 // Validate addresses for transport mode
900 if (key_sockaddrcmp((struct sockaddr *)&sah->saidx.src, src, 0) != 0) {
901 // Source doesn't match
902 continue;
903 }
904
905 if (key_sockaddrcmp((struct sockaddr *)&sah->saidx.dst, dst, 0) != 0) {
906 // Destination doesn't match
907 continue;
908 }
909 }
910
911 /* This SAH is linked to the IPsec interface, and the right family. We found it! */
912 if (key_preferred_oldsa) {
913 saorder_state_valid = saorder_state_valid_prefer_old;
914 arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
915 } else {
916 saorder_state_valid = saorder_state_valid_prefer_new;
917 arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
918 }
919
920 sin = (struct sockaddr_in *)&sah->saidx.dst;
921 dstport = sin->sin_port;
922 if (sah->saidx.mode == IPSEC_MODE_TRANSPORT) {
923 sin->sin_port = IPSEC_PORT_ANY;
924 }
925
926 for (stateidx = 0; stateidx < arraysize; stateidx++) {
927 state = saorder_state_valid[stateidx];
928 sav = key_do_allocsa_policy(sah, state, dstport);
929 if (sav != NULL) {
930 lck_mtx_unlock(sadb_mutex);
931 return sav;
932 }
933 }
934
935 break;
936 }
937 }
938 if (strict) {
939 // If we didn't find anything, try again without strict
940 strict = false;
941 } else {
942 // We already were on the second try, bail
943 break;
944 }
945 } while (true);
946
947 lck_mtx_unlock(sadb_mutex);
948 return NULL;
949}
950
951/*
952 * allocating an SA entry for an *OUTBOUND* packet.
953 * checking each request entries in SP, and acquire an SA if need.
954 * OUT: 0: there are valid requests.
955 * ENOENT: policy may be valid, but SA with REQUIRE is on acquiring.
956 */
957int
958key_checkrequest(
959 struct ipsecrequest *isr,
960 struct secasindex *saidx,
961 struct secasvar **sav)
962{
963 u_int level;
964 int error;
965 struct sockaddr_in *sin;
966
967 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
968
969 *sav = NULL;
970
971 /* sanity check */
972 if (isr == NULL || saidx == NULL) {
973 panic("key_checkrequest: NULL pointer is passed.");
974 }
975
976 /* check mode */
977 switch (saidx->mode) {
978 case IPSEC_MODE_TRANSPORT:
979 case IPSEC_MODE_TUNNEL:
980 break;
981 case IPSEC_MODE_ANY:
982 default:
983 panic("key_checkrequest: Invalid policy defined.");
984 }
985
986 /* get current level */
987 level = ipsec_get_reqlevel(isr);
988
989
990 /*
991 * key_allocsa_policy should allocate the oldest SA available.
992 * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt.
993 */
994 if (*sav == NULL) {
995 *sav = key_allocsa_policy(saidx);
996 }
997
998 /* When there is SA. */
999 if (*sav != NULL) {
1000 return 0;
1001 }
1002
1003 /* There is no SA.
1004 *
1005 * Remove dst port - used for special natt support - don't call
1006 * key_acquire with it.
1007 */
1008 if (saidx->mode == IPSEC_MODE_TRANSPORT) {
1009 sin = (struct sockaddr_in *)&saidx->dst;
1010 sin->sin_port = IPSEC_PORT_ANY;
1011 }
1012 if ((error = key_acquire(saidx, isr->sp)) != 0) {
1013 /* XXX What should I do ? */
1014 ipseclog((LOG_DEBUG, "key_checkrequest: error %d returned "
1015 "from key_acquire.\n", error));
1016 return error;
1017 }
1018
1019 return level == IPSEC_LEVEL_REQUIRE ? ENOENT : 0;
1020}
1021
1022/*
1023 * allocating a SA for policy entry from SAD.
1024 * NOTE: searching SAD of aliving state.
1025 * OUT: NULL: not found.
1026 * others: found and return the pointer.
1027 */
1028u_int32_t sah_search_calls = 0;
1029u_int32_t sah_search_count = 0;
1030struct secasvar *
1031key_allocsa_policy(
1032 struct secasindex *saidx)
1033{
1034 struct secashead *sah;
1035 struct secasvar *sav;
1036 u_int stateidx, state;
1037 const u_int *saorder_state_valid;
1038 int arraysize;
1039 struct sockaddr_in *sin;
1040 u_int16_t dstport;
1041
1042 lck_mtx_lock(sadb_mutex);
1043 sah_search_calls++;
1044 LIST_FOREACH(sah, &sahtree, chain) {
1045 sah_search_count++;
1046 if (sah->state == SADB_SASTATE_DEAD) {
1047 continue;
1048 }
1049 if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE | CMP_REQID)) {
1050 goto found;
1051 }
1052 }
1053 lck_mtx_unlock(sadb_mutex);
1054 return NULL;
1055
1056found:
1057
1058 /*
1059 * search a valid state list for outbound packet.
1060 * This search order is important.
1061 */
1062 if (key_preferred_oldsa) {
1063 saorder_state_valid = saorder_state_valid_prefer_old;
1064 arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
1065 } else {
1066 saorder_state_valid = saorder_state_valid_prefer_new;
1067 arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
1068 }
1069
1070
1071 sin = (struct sockaddr_in *)&saidx->dst;
1072 dstport = sin->sin_port;
1073 if (saidx->mode == IPSEC_MODE_TRANSPORT) {
1074 sin->sin_port = IPSEC_PORT_ANY;
1075 }
1076
1077 for (stateidx = 0; stateidx < arraysize; stateidx++) {
1078 state = saorder_state_valid[stateidx];
1079
1080 sav = key_do_allocsa_policy(sah, state, dstport);
1081 if (sav != NULL) {
1082 lck_mtx_unlock(sadb_mutex);
1083 return sav;
1084 }
1085 }
1086 lck_mtx_unlock(sadb_mutex);
1087 return NULL;
1088}
1089
1090static void
1091key_send_delete(struct secasvar *sav)
1092{
1093 struct mbuf *m, *result;
1094 u_int8_t satype;
1095
1096 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
1097
1098 if ((satype = key_proto2satype(sav->sah->saidx.proto)) == 0) {
1099 panic("key_do_allocsa_policy: invalid proto is passed.");
1100 }
1101
1102 m = key_setsadbmsg(SADB_DELETE, 0,
1103 satype, 0, 0, (u_int16_t)(sav->refcnt - 1));
1104 if (!m) {
1105 goto msgfail;
1106 }
1107 result = m;
1108
1109 /* set sadb_address for saidx's. */
1110 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
1111 (struct sockaddr *)&sav->sah->saidx.src,
1112 sav->sah->saidx.src.ss_len << 3,
1113 IPSEC_ULPROTO_ANY);
1114 if (!m) {
1115 goto msgfail;
1116 }
1117 m_cat(result, m);
1118
1119 /* set sadb_address for saidx's. */
1120 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
1121 (struct sockaddr *)&sav->sah->saidx.dst,
1122 sav->sah->saidx.src.ss_len << 3,
1123 IPSEC_ULPROTO_ANY);
1124 if (!m) {
1125 goto msgfail;
1126 }
1127 m_cat(result, m);
1128
1129 /* create SA extension */
1130 m = key_setsadbsa(sav);
1131 if (!m) {
1132 goto msgfail;
1133 }
1134 m_cat(result, m);
1135
1136 if (result->m_len < sizeof(struct sadb_msg)) {
1137 result = m_pullup(result,
1138 sizeof(struct sadb_msg));
1139 if (result == NULL) {
1140 goto msgfail;
1141 }
1142 }
1143
1144 result->m_pkthdr.len = 0;
1145 for (m = result; m; m = m->m_next) {
1146 result->m_pkthdr.len += m->m_len;
1147 }
1148
1149 VERIFY(PFKEY_UNIT64(result->m_pkthdr.len) <= UINT16_MAX);
1150 mtod(result, struct sadb_msg *)->sadb_msg_len =
1151 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
1152
1153 if (key_sendup_mbuf(NULL, result,
1154 KEY_SENDUP_REGISTERED)) {
1155 goto msgfail;
1156 }
1157msgfail:
1158 key_freesav(sav, KEY_SADB_LOCKED);
1159}
1160
1161/*
1162 * searching SAD with direction, protocol, mode and state.
1163 * called by key_allocsa_policy().
1164 * OUT:
1165 * NULL : not found
1166 * others : found, pointer to a SA.
1167 */
1168static struct secasvar *
1169key_do_allocsa_policy(
1170 struct secashead *sah,
1171 u_int state,
1172 u_int16_t dstport)
1173{
1174 struct secasvar *sav, *nextsav, *candidate, *natt_candidate, *no_natt_candidate, *d;
1175
1176 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1177
1178 /* initialize */
1179 candidate = NULL;
1180 natt_candidate = NULL;
1181 no_natt_candidate = NULL;
1182
1183 for (sav = LIST_FIRST(&sah->savtree[state]);
1184 sav != NULL;
1185 sav = nextsav) {
1186 nextsav = LIST_NEXT(sav, chain);
1187
1188 /* sanity check */
1189 KEY_CHKSASTATE(sav->state, state, "key_do_allocsa_policy");
1190
1191 if (sah->saidx.mode == IPSEC_MODE_TUNNEL && dstport &&
1192 ((sav->flags & SADB_X_EXT_NATT) != 0) &&
1193 ntohs(dstport) != sav->remote_ike_port) {
1194 continue;
1195 }
1196
1197 if (sah->saidx.mode == IPSEC_MODE_TRANSPORT &&
1198 ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0) &&
1199 ntohs(dstport) != sav->remote_ike_port) {
1200 continue; /* skip this one - not a match - or not UDP */
1201 }
1202 if ((sah->saidx.mode == IPSEC_MODE_TUNNEL &&
1203 ((sav->flags & SADB_X_EXT_NATT) != 0)) ||
1204 (sah->saidx.mode == IPSEC_MODE_TRANSPORT &&
1205 ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0))) {
1206 if (natt_candidate == NULL) {
1207 natt_candidate = sav;
1208 continue;
1209 } else {
1210 candidate = natt_candidate;
1211 }
1212 } else {
1213 if (no_natt_candidate == NULL) {
1214 no_natt_candidate = sav;
1215 continue;
1216 } else {
1217 candidate = no_natt_candidate;
1218 }
1219 }
1220
1221 /* Which SA is the better ? */
1222
1223 /* sanity check 2 */
1224 if (candidate->lft_c == NULL || sav->lft_c == NULL) {
1225 panic("key_do_allocsa_policy: "
1226 "lifetime_current is NULL.\n");
1227 }
1228
1229 /* What the best method is to compare ? */
1230 if (key_preferred_oldsa) {
1231 if (candidate->lft_c->sadb_lifetime_addtime >
1232 sav->lft_c->sadb_lifetime_addtime) {
1233 if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0) {
1234 natt_candidate = sav;
1235 } else {
1236 no_natt_candidate = sav;
1237 }
1238 }
1239 continue;
1240 /*NOTREACHED*/
1241 }
1242
1243 /* prefered new sa rather than old sa */
1244 if (candidate->lft_c->sadb_lifetime_addtime <
1245 sav->lft_c->sadb_lifetime_addtime) {
1246 d = candidate;
1247 if ((sah->saidx.mode == IPSEC_MODE_TUNNEL &&
1248 ((sav->flags & SADB_X_EXT_NATT) != 0)) ||
1249 (sah->saidx.mode == IPSEC_MODE_TRANSPORT &&
1250 ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0))) {
1251 natt_candidate = sav;
1252 } else {
1253 no_natt_candidate = sav;
1254 }
1255 } else {
1256 d = sav;
1257 }
1258
1259 /*
1260 * prepared to delete the SA when there is more
1261 * suitable candidate and the lifetime of the SA is not
1262 * permanent.
1263 */
1264 if (d->lft_c->sadb_lifetime_addtime != 0) {
1265 key_send_delete(sav: d);
1266 }
1267 }
1268
1269 /* choose latest if both types present */
1270 if (natt_candidate == NULL) {
1271 candidate = no_natt_candidate;
1272 } else if (no_natt_candidate == NULL) {
1273 candidate = natt_candidate;
1274 } else if (sah->saidx.mode == IPSEC_MODE_TUNNEL && dstport) {
1275 candidate = natt_candidate;
1276 } else if (natt_candidate->lft_c->sadb_lifetime_addtime >
1277 no_natt_candidate->lft_c->sadb_lifetime_addtime) {
1278 candidate = natt_candidate;
1279 } else {
1280 candidate = no_natt_candidate;
1281 }
1282
1283 if (candidate) {
1284 candidate->refcnt++;
1285 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1286 printf("DP allocsa_policy cause "
1287 "refcnt++:%d SA:0x%llx\n", candidate->refcnt,
1288 (uint64_t)VM_KERNEL_ADDRPERM(candidate)));
1289 }
1290 return candidate;
1291}
1292
1293/*
1294 * allocating a SA entry for a *INBOUND* packet.
1295 * Must call key_freesav() later.
1296 * OUT: positive: pointer to a sav.
1297 * NULL: not found, or error occurred.
1298 *
1299 * In the comparison, source address will be ignored for RFC2401 conformance.
1300 * To quote, from section 4.1:
1301 * A security association is uniquely identified by a triple consisting
1302 * of a Security Parameter Index (SPI), an IP Destination Address, and a
1303 * security protocol (AH or ESP) identifier.
1304 * Note that, however, we do need to keep source address in IPsec SA.
1305 * IKE specification and PF_KEY specification do assume that we
1306 * keep source address in IPsec SA. We see a tricky situation here.
1307 */
1308struct secasvar *
1309key_allocsa(
1310 u_int family,
1311 caddr_t src,
1312 caddr_t dst,
1313 uint32_t dst_ifscope,
1314 u_int proto,
1315 u_int32_t spi)
1316{
1317 return key_allocsa_extended(family, src, dst, dst_ifscope, proto, spi, NULL);
1318}
1319
1320struct secasvar *
1321key_allocsa_extended(u_int family,
1322 caddr_t src,
1323 caddr_t dst,
1324 uint32_t dst_ifscope,
1325 u_int proto,
1326 u_int32_t spi,
1327 ifnet_t interface)
1328{
1329 struct secasvar *sav, *match;
1330 u_int stateidx, state, tmpidx, matchidx;
1331 union sockaddr_in_4_6 dst_address = {};
1332 const u_int *saorder_state_valid;
1333 int arraysize;
1334 bool dst_ll_address = false;
1335
1336 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1337
1338 /* sanity check */
1339 if (src == NULL || dst == NULL) {
1340 panic("key_allocsa: NULL pointer is passed.");
1341 }
1342
1343 /*
1344 * when both systems employ similar strategy to use a SA.
1345 * the search order is important even in the inbound case.
1346 */
1347 if (key_preferred_oldsa) {
1348 saorder_state_valid = saorder_state_valid_prefer_old;
1349 arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
1350 } else {
1351 saorder_state_valid = saorder_state_valid_prefer_new;
1352 arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
1353 }
1354
1355 /* check dst address */
1356 switch (family) {
1357 case AF_INET:
1358 dst_address.sin.sin_family = AF_INET;
1359 dst_address.sin.sin_len = sizeof(dst_address.sin);
1360 memcpy(dst: &dst_address.sin.sin_addr, src: dst, n: sizeof(dst_address.sin.sin_addr));
1361 break;
1362 case AF_INET6:
1363 dst_address.sin6.sin6_family = AF_INET6;
1364 dst_address.sin6.sin6_len = sizeof(dst_address.sin6);
1365 memcpy(dst: &dst_address.sin6.sin6_addr, src: dst, n: sizeof(dst_address.sin6.sin6_addr));
1366 if (IN6_IS_SCOPE_LINKLOCAL(&dst_address.sin6.sin6_addr)) {
1367 dst_ll_address = true;
1368 /* kame fake scopeid */
1369 dst_address.sin6.sin6_scope_id = dst_ifscope;
1370 if (in6_embedded_scope) {
1371 in6_verify_ifscope(&dst_address.sin6.sin6_addr, dst_address.sin6.sin6_scope_id);
1372 dst_address.sin6.sin6_scope_id =
1373 ntohs(dst_address.sin6.sin6_addr.s6_addr16[1]);
1374 dst_address.sin6.sin6_addr.s6_addr16[1] = 0;
1375 }
1376 }
1377 break;
1378 default:
1379 ipseclog((LOG_DEBUG, "key_allocsa: "
1380 "unknown address family=%d.\n", family));
1381 return NULL;
1382 }
1383
1384
1385 /*
1386 * searching SAD.
1387 * XXX: to be checked internal IP header somewhere. Also when
1388 * IPsec tunnel packet is received. But ESP tunnel mode is
1389 * encrypted so we can't check internal IP header.
1390 */
1391 /*
1392 * search a valid state list for inbound packet.
1393 * the search order is not important.
1394 */
1395 match = NULL;
1396 matchidx = arraysize;
1397 lck_mtx_lock(sadb_mutex);
1398 LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
1399 if (sav->spi != spi) {
1400 continue;
1401 }
1402 if (interface != NULL &&
1403 sav->sah->ipsec_if != interface) {
1404 continue;
1405 }
1406 if (proto != sav->sah->saidx.proto) {
1407 continue;
1408 }
1409 if (family != sav->sah->saidx.src.ss_family ||
1410 family != sav->sah->saidx.dst.ss_family) {
1411 continue;
1412 }
1413 tmpidx = arraysize;
1414 for (stateidx = 0; stateidx < matchidx; stateidx++) {
1415 state = saorder_state_valid[stateidx];
1416 if (sav->state == state) {
1417 tmpidx = stateidx;
1418 break;
1419 }
1420 }
1421 if (tmpidx >= matchidx) {
1422 continue;
1423 }
1424
1425 struct sockaddr_in6 tmp_sah_dst = {};
1426 struct sockaddr *sah_dst = (struct sockaddr *)&sav->sah->saidx.dst;
1427 if (dst_ll_address) {
1428 if (!IN6_IS_SCOPE_LINKLOCAL(&(__DECONST(struct sockaddr_in6 *, sah_dst))->sin6_addr)) {
1429 continue;
1430 } else {
1431 tmp_sah_dst.sin6_family = AF_INET6;
1432 tmp_sah_dst.sin6_len = sizeof(tmp_sah_dst);
1433 memcpy(dst: &tmp_sah_dst.sin6_addr, src: &(__DECONST(struct sockaddr_in6 *, sah_dst))->sin6_addr, n: sizeof(tmp_sah_dst.sin6_addr));
1434 tmp_sah_dst.sin6_scope_id = sav->sah->outgoing_if;
1435 sah_dst = (struct sockaddr *)&tmp_sah_dst;
1436 }
1437 }
1438
1439 if (key_sockaddrcmp(SA(&dst_address.sa), sah_dst, 0) != 0) {
1440 continue;
1441 }
1442
1443 match = sav;
1444 matchidx = tmpidx;
1445 }
1446 if (match) {
1447 goto found;
1448 }
1449
1450 /* not found */
1451 lck_mtx_unlock(sadb_mutex);
1452 return NULL;
1453
1454found:
1455 match->refcnt++;
1456 lck_mtx_unlock(sadb_mutex);
1457 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1458 printf("DP allocsa cause refcnt++:%d SA:0x%llx\n",
1459 match->refcnt, (uint64_t)VM_KERNEL_ADDRPERM(match)));
1460 return match;
1461}
1462
1463/*
1464 * This function checks whether a UDP packet with a random local port
1465 * and a remote port of 4500 matches an SA in the kernel. If does match,
1466 * send the packet to the ESP engine. If not, send the packet to the UDP protocol.
1467 */
1468bool
1469key_checksa_present(u_int family,
1470 caddr_t local_addr,
1471 caddr_t remote_addr,
1472 u_int16_t local_port,
1473 u_int16_t remote_port,
1474 uint32_t source_ifscope,
1475 uint32_t remote_ifscope)
1476{
1477 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1478
1479 /* sanity check */
1480 if (local_addr == NULL || remote_addr == NULL) {
1481 panic("key_allocsa: NULL pointer is passed.");
1482 }
1483
1484 /*
1485 * searching SAD.
1486 * XXX: to be checked internal IP header somewhere. Also when
1487 * IPsec tunnel packet is received. But ESP tunnel mode is
1488 * encrypted so we can't check internal IP header.
1489 */
1490 /*
1491 * search a valid state list for inbound packet.
1492 * the search order is not important.
1493 */
1494 struct secashead *sah = NULL;
1495 bool found_sa = false;
1496
1497 lck_mtx_lock(sadb_mutex);
1498 LIST_FOREACH(sah, &sahtree, chain) {
1499 if (sah->state == SADB_SASTATE_DEAD) {
1500 continue;
1501 }
1502
1503 if (sah->dir != IPSEC_DIR_OUTBOUND) {
1504 continue;
1505 }
1506
1507 if (family != sah->saidx.src.ss_family) {
1508 continue;
1509 }
1510
1511 struct sockaddr_in src_in = {};
1512 struct sockaddr_in6 src_in6 = {};
1513
1514 /* check src address */
1515 switch (family) {
1516 case AF_INET:
1517 src_in.sin_family = AF_INET;
1518 src_in.sin_len = sizeof(src_in);
1519 memcpy(dst: &src_in.sin_addr, src: local_addr, n: sizeof(src_in.sin_addr));
1520 if (key_sockaddrcmp((struct sockaddr*)&src_in,
1521 (struct sockaddr *)&sah->saidx.src, 0) != 0) {
1522 continue;
1523 }
1524 break;
1525 case AF_INET6:
1526 src_in6.sin6_family = AF_INET6;
1527 src_in6.sin6_len = sizeof(src_in6);
1528 memcpy(dst: &src_in6.sin6_addr, src: local_addr, n: sizeof(src_in6.sin6_addr));
1529 if (IN6_IS_SCOPE_LINKLOCAL(&src_in6.sin6_addr)) {
1530 /* kame fake scopeid */
1531 src_in6.sin6_scope_id = source_ifscope;
1532 if (in6_embedded_scope) {
1533 in6_verify_ifscope(&src_in6.sin6_addr, src_in6.sin6_scope_id);
1534 src_in6.sin6_scope_id =
1535 ntohs(src_in6.sin6_addr.s6_addr16[1]);
1536 src_in6.sin6_addr.s6_addr16[1] = 0;
1537 }
1538 }
1539 if (key_sockaddrcmp((struct sockaddr*)&src_in6,
1540 (struct sockaddr *)&sah->saidx.src, 0) != 0) {
1541 continue;
1542 }
1543 break;
1544 default:
1545 ipseclog((LOG_DEBUG, "key_checksa_present: "
1546 "unknown address family=%d.\n",
1547 family));
1548 continue;
1549 }
1550
1551 struct sockaddr_in dest_in = {};
1552 struct sockaddr_in6 dest_in6 = {};
1553
1554 /* check dst address */
1555 switch (family) {
1556 case AF_INET:
1557 dest_in.sin_family = AF_INET;
1558 dest_in.sin_len = sizeof(dest_in);
1559 memcpy(dst: &dest_in.sin_addr, src: remote_addr, n: sizeof(dest_in.sin_addr));
1560 if (key_sockaddrcmp((struct sockaddr*)&dest_in,
1561 (struct sockaddr *)&sah->saidx.dst, 0) != 0) {
1562 continue;
1563 }
1564
1565 break;
1566 case AF_INET6:
1567 dest_in6.sin6_family = AF_INET6;
1568 dest_in6.sin6_len = sizeof(dest_in6);
1569 memcpy(dst: &dest_in6.sin6_addr, src: remote_addr, n: sizeof(dest_in6.sin6_addr));
1570 if (IN6_IS_SCOPE_LINKLOCAL(&dest_in6.sin6_addr)) {
1571 /* kame fake scopeid */
1572 dest_in6.sin6_scope_id = remote_ifscope;
1573 if (in6_embedded_scope) {
1574 in6_verify_ifscope(&dest_in6.sin6_addr, dest_in6.sin6_scope_id);
1575 dest_in6.sin6_scope_id = ntohs(dest_in6.sin6_addr.s6_addr16[1]);
1576 dest_in6.sin6_addr.s6_addr16[1] = 0;
1577 }
1578 }
1579 if (key_sockaddrcmp((struct sockaddr*)&dest_in6,
1580 (struct sockaddr *)&sah->saidx.dst, 0) != 0) {
1581 continue;
1582 }
1583
1584 break;
1585 default:
1586 ipseclog((LOG_DEBUG, "key_checksa_present: "
1587 "unknown address family=%d.\n", family));
1588 continue;
1589 }
1590
1591 struct secasvar *nextsav = NULL;
1592 for (u_int stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); stateidx++) {
1593 u_int state = saorder_state_alive[stateidx];
1594 for (struct secasvar *sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) {
1595 nextsav = LIST_NEXT(sav, chain);
1596 /* sanity check */
1597 if (sav->state != state) {
1598 ipseclog((LOG_DEBUG, "key_checksa_present: "
1599 "invalid sav->state "
1600 "(state: %d SA: %d)\n",
1601 state, sav->state));
1602 continue;
1603 }
1604
1605 if (sav->remote_ike_port != ntohs(remote_port)) {
1606 continue;
1607 }
1608
1609 if (sav->natt_encapsulated_src_port != local_port) {
1610 continue;
1611 }
1612 found_sa = true;
1613 break;
1614 }
1615 }
1616 }
1617
1618 /* not found */
1619 lck_mtx_unlock(sadb_mutex);
1620 return found_sa;
1621}
1622
1623u_int16_t
1624key_natt_get_translated_port(
1625 struct secasvar *outsav)
1626{
1627 struct secasindex saidx = {};
1628 struct secashead *sah;
1629 u_int stateidx, state;
1630 const u_int *saorder_state_valid;
1631 int arraysize;
1632
1633 /* get sa for incoming */
1634 saidx.mode = outsav->sah->saidx.mode;
1635 saidx.reqid = 0;
1636 saidx.proto = outsav->sah->saidx.proto;
1637 bcopy(src: &outsav->sah->saidx.src, dst: &saidx.dst, n: sizeof(struct sockaddr_in));
1638 bcopy(src: &outsav->sah->saidx.dst, dst: &saidx.src, n: sizeof(struct sockaddr_in));
1639
1640 lck_mtx_lock(sadb_mutex);
1641 LIST_FOREACH(sah, &sahtree, chain) {
1642 if (sah->state == SADB_SASTATE_DEAD) {
1643 continue;
1644 }
1645 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE)) {
1646 goto found;
1647 }
1648 }
1649 lck_mtx_unlock(sadb_mutex);
1650 return 0;
1651
1652found:
1653 /*
1654 * Found sah - now go thru list of SAs and find
1655 * matching remote ike port. If found - set
1656 * sav->natt_encapsulated_src_port and return the port.
1657 */
1658 /*
1659 * search a valid state list for outbound packet.
1660 * This search order is important.
1661 */
1662 if (key_preferred_oldsa) {
1663 saorder_state_valid = saorder_state_valid_prefer_old;
1664 arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
1665 } else {
1666 saorder_state_valid = saorder_state_valid_prefer_new;
1667 arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
1668 }
1669
1670 for (stateidx = 0; stateidx < arraysize; stateidx++) {
1671 state = saorder_state_valid[stateidx];
1672 if (key_do_get_translated_port(sah, outsav, state)) {
1673 lck_mtx_unlock(sadb_mutex);
1674 return outsav->natt_encapsulated_src_port;
1675 }
1676 }
1677 lck_mtx_unlock(sadb_mutex);
1678 return 0;
1679}
1680
1681static int
1682key_do_get_translated_port(
1683 struct secashead *sah,
1684 struct secasvar *outsav,
1685 u_int state)
1686{
1687 struct secasvar *currsav, *nextsav, *candidate;
1688
1689
1690 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1691
1692 /* initilize */
1693 candidate = NULL;
1694
1695 for (currsav = LIST_FIRST(&sah->savtree[state]);
1696 currsav != NULL;
1697 currsav = nextsav) {
1698 nextsav = LIST_NEXT(currsav, chain);
1699
1700 /* sanity check */
1701 KEY_CHKSASTATE(currsav->state, state, "key_do_get_translated_port");
1702
1703 if ((currsav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) == 0 ||
1704 currsav->remote_ike_port != outsav->remote_ike_port) {
1705 continue;
1706 }
1707
1708 if (candidate == NULL) {
1709 candidate = currsav;
1710 continue;
1711 }
1712
1713 /* Which SA is the better ? */
1714
1715 /* sanity check 2 */
1716 if (candidate->lft_c == NULL || currsav->lft_c == NULL) {
1717 panic("key_do_get_translated_port: "
1718 "lifetime_current is NULL.\n");
1719 }
1720
1721 /* What the best method is to compare ? */
1722 if (key_preferred_oldsa) {
1723 if (candidate->lft_c->sadb_lifetime_addtime >
1724 currsav->lft_c->sadb_lifetime_addtime) {
1725 candidate = currsav;
1726 }
1727 continue;
1728 /*NOTREACHED*/
1729 }
1730
1731 /* prefered new sa rather than old sa */
1732 if (candidate->lft_c->sadb_lifetime_addtime <
1733 currsav->lft_c->sadb_lifetime_addtime) {
1734 candidate = currsav;
1735 }
1736 }
1737
1738 if (candidate) {
1739 outsav->natt_encapsulated_src_port = candidate->natt_encapsulated_src_port;
1740 return 1;
1741 }
1742
1743 return 0;
1744}
1745
1746/*
1747 * Must be called after calling key_allocsp().
1748 */
1749void
1750key_freesp(
1751 struct secpolicy *sp,
1752 int locked)
1753{
1754 /* sanity check */
1755 if (sp == NULL) {
1756 panic("key_freesp: NULL pointer is passed.");
1757 }
1758
1759 if (!locked) {
1760 lck_mtx_lock(sadb_mutex);
1761 } else {
1762 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1763 }
1764 sp->refcnt--;
1765 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1766 printf("DP freesp cause refcnt--:%d SP:0x%llx\n",
1767 sp->refcnt, (uint64_t)VM_KERNEL_ADDRPERM(sp)));
1768
1769 if (sp->refcnt == 0) {
1770 key_delsp(sp);
1771 }
1772 if (!locked) {
1773 lck_mtx_unlock(sadb_mutex);
1774 }
1775 return;
1776}
1777
1778/*
1779 * Must be called after calling key_allocsa().
1780 * This function is called by key_freesp() to free some SA allocated
1781 * for a policy.
1782 */
1783void
1784key_freesav(
1785 struct secasvar *sav,
1786 int locked)
1787{
1788 /* sanity check */
1789 if (sav == NULL) {
1790 panic("key_freesav: NULL pointer is passed.");
1791 }
1792
1793 if (!locked) {
1794 lck_mtx_lock(sadb_mutex);
1795 } else {
1796 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1797 }
1798 sav->refcnt--;
1799 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1800 printf("DP freesav cause refcnt--:%d SA:0x%llx SPI %u\n",
1801 sav->refcnt, (uint64_t)VM_KERNEL_ADDRPERM(sav),
1802 (u_int32_t)ntohl(sav->spi)));
1803
1804 if (sav->refcnt == 0) {
1805 key_delsav(sav);
1806 }
1807 if (!locked) {
1808 lck_mtx_unlock(sadb_mutex);
1809 }
1810 return;
1811}
1812
1813/* %%% SPD management */
1814/*
1815 * free security policy entry.
1816 */
1817static void
1818key_delsp(
1819 struct secpolicy *sp)
1820{
1821 /* sanity check */
1822 if (sp == NULL) {
1823 panic("key_delsp: NULL pointer is passed.");
1824 }
1825
1826 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1827 sp->state = IPSEC_SPSTATE_DEAD;
1828
1829 if (sp->refcnt > 0) {
1830 return; /* can't free */
1831 }
1832 /* remove from SP index */
1833 if (__LIST_CHAINED(sp)) {
1834 LIST_REMOVE(sp, chain);
1835 ipsec_policy_count--;
1836 }
1837
1838 if (sp->spidx.internal_if) {
1839 ifnet_release(interface: sp->spidx.internal_if);
1840 sp->spidx.internal_if = NULL;
1841 }
1842
1843 if (sp->ipsec_if) {
1844 ifnet_release(interface: sp->ipsec_if);
1845 sp->ipsec_if = NULL;
1846 }
1847
1848 if (sp->outgoing_if) {
1849 ifnet_release(interface: sp->outgoing_if);
1850 sp->outgoing_if = NULL;
1851 }
1852
1853 {
1854 struct ipsecrequest *isr = sp->req, *nextisr;
1855
1856 while (isr != NULL) {
1857 nextisr = isr->next;
1858 kfree_type(struct ipsecrequest, isr);
1859 isr = nextisr;
1860 }
1861 }
1862 keydb_delsecpolicy(sp);
1863
1864 return;
1865}
1866
1867/*
1868 * search SPD
1869 * OUT: NULL : not found
1870 * others : found, pointer to a SP.
1871 */
1872static struct secpolicy *
1873key_getsp(
1874 struct secpolicyindex *spidx)
1875{
1876 struct secpolicy *sp;
1877
1878 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1879
1880 /* sanity check */
1881 if (spidx == NULL) {
1882 panic("key_getsp: NULL pointer is passed.");
1883 }
1884
1885 LIST_FOREACH(sp, &sptree[spidx->dir], chain) {
1886 if (sp->state == IPSEC_SPSTATE_DEAD) {
1887 continue;
1888 }
1889 if (key_cmpspidx_exactly(spidx, &sp->spidx)) {
1890 sp->refcnt++;
1891 return sp;
1892 }
1893 }
1894
1895 return NULL;
1896}
1897
1898/*
1899 * get SP by index.
1900 * OUT: NULL : not found
1901 * others : found, pointer to a SP.
1902 */
1903struct secpolicy *
1904key_getspbyid(
1905 u_int32_t id)
1906{
1907 struct secpolicy *sp;
1908
1909 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1910
1911 lck_mtx_lock(sadb_mutex);
1912 sp = __key_getspbyid(id);
1913 lck_mtx_unlock(sadb_mutex);
1914
1915 return sp;
1916}
1917
1918static struct secpolicy *
1919__key_getspbyid(u_int32_t id)
1920{
1921 struct secpolicy *sp;
1922
1923 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1924
1925 LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) {
1926 if (sp->state == IPSEC_SPSTATE_DEAD) {
1927 continue;
1928 }
1929 if (sp->id == id) {
1930 sp->refcnt++;
1931 return sp;
1932 }
1933 }
1934
1935 LIST_FOREACH(sp, &sptree[IPSEC_DIR_OUTBOUND], chain) {
1936 if (sp->state == IPSEC_SPSTATE_DEAD) {
1937 continue;
1938 }
1939 if (sp->id == id) {
1940 sp->refcnt++;
1941 return sp;
1942 }
1943 }
1944
1945 return NULL;
1946}
1947
1948struct secpolicy *
1949key_newsp(void)
1950{
1951 struct secpolicy *newsp = NULL;
1952
1953 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1954 newsp = keydb_newsecpolicy();
1955 if (!newsp) {
1956 return newsp;
1957 }
1958
1959 newsp->refcnt = 1;
1960 newsp->req = NULL;
1961
1962 return newsp;
1963}
1964
1965/*
1966 * create secpolicy structure from sadb_x_policy structure.
1967 * NOTE: `state', `secpolicyindex' in secpolicy structure are not set,
1968 * so must be set properly later.
1969 */
1970struct secpolicy *
1971key_msg2sp(
1972 struct sadb_x_policy *xpl0,
1973 size_t len,
1974 int *error)
1975{
1976 struct secpolicy *newsp;
1977
1978 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1979
1980 /* sanity check */
1981 if (xpl0 == NULL) {
1982 panic("key_msg2sp: NULL pointer was passed.");
1983 }
1984 if (len < sizeof(*xpl0)) {
1985 panic("key_msg2sp: invalid length.");
1986 }
1987 if (len != PFKEY_EXTLEN(xpl0)) {
1988 ipseclog((LOG_DEBUG, "key_msg2sp: Invalid msg length.\n"));
1989 *error = EINVAL;
1990 return NULL;
1991 }
1992
1993 if ((newsp = key_newsp()) == NULL) {
1994 *error = ENOBUFS;
1995 return NULL;
1996 }
1997
1998 newsp->spidx.dir = xpl0->sadb_x_policy_dir;
1999 newsp->policy = xpl0->sadb_x_policy_type;
2000
2001 /* check policy */
2002 switch (xpl0->sadb_x_policy_type) {
2003 case IPSEC_POLICY_DISCARD:
2004 case IPSEC_POLICY_GENERATE:
2005 case IPSEC_POLICY_NONE:
2006 case IPSEC_POLICY_ENTRUST:
2007 case IPSEC_POLICY_BYPASS:
2008 newsp->req = NULL;
2009 break;
2010
2011 case IPSEC_POLICY_IPSEC:
2012 {
2013 int tlen;
2014 struct sadb_x_ipsecrequest *xisr;
2015 struct ipsecrequest **p_isr = &newsp->req;
2016
2017 /* validity check */
2018 if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) {
2019 ipseclog((LOG_DEBUG,
2020 "key_msg2sp: Invalid msg length.\n"));
2021 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2022 *error = EINVAL;
2023 return NULL;
2024 }
2025
2026 tlen = PFKEY_EXTLEN(xpl0) - sizeof(*xpl0);
2027 xisr = (struct sadb_x_ipsecrequest *)(xpl0 + 1);
2028
2029 while (tlen > 0) {
2030 if (tlen < sizeof(*xisr)) {
2031 ipseclog((LOG_DEBUG, "key_msg2sp: "
2032 "invalid ipsecrequest.\n"));
2033 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2034 *error = EINVAL;
2035 return NULL;
2036 }
2037
2038 /* length check */
2039 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
2040 ipseclog((LOG_DEBUG, "key_msg2sp: "
2041 "invalid ipsecrequest length.\n"));
2042 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2043 *error = EINVAL;
2044 return NULL;
2045 }
2046
2047 /* allocate request buffer */
2048 *p_isr = kalloc_type(struct ipsecrequest,
2049 Z_WAITOK_ZERO_NOFAIL);
2050
2051 switch (xisr->sadb_x_ipsecrequest_proto) {
2052 case IPPROTO_ESP:
2053 case IPPROTO_AH:
2054 break;
2055 default:
2056 ipseclog((LOG_DEBUG,
2057 "key_msg2sp: invalid proto type=%u\n",
2058 xisr->sadb_x_ipsecrequest_proto));
2059 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2060 *error = EPROTONOSUPPORT;
2061 return NULL;
2062 }
2063 (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
2064
2065 switch (xisr->sadb_x_ipsecrequest_mode) {
2066 case IPSEC_MODE_TRANSPORT:
2067 case IPSEC_MODE_TUNNEL:
2068 break;
2069 case IPSEC_MODE_ANY:
2070 default:
2071 ipseclog((LOG_DEBUG,
2072 "key_msg2sp: invalid mode=%u\n",
2073 xisr->sadb_x_ipsecrequest_mode));
2074 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2075 *error = EINVAL;
2076 return NULL;
2077 }
2078 (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
2079
2080 switch (xisr->sadb_x_ipsecrequest_level) {
2081 case IPSEC_LEVEL_DEFAULT:
2082 case IPSEC_LEVEL_USE:
2083 case IPSEC_LEVEL_REQUIRE:
2084 break;
2085 case IPSEC_LEVEL_UNIQUE:
2086 /* validity check */
2087 /*
2088 * If range violation of reqid, kernel will
2089 * update it, don't refuse it.
2090 */
2091 if (xisr->sadb_x_ipsecrequest_reqid
2092 > IPSEC_MANUAL_REQID_MAX) {
2093 ipseclog((LOG_DEBUG,
2094 "key_msg2sp: reqid=%d range "
2095 "violation, updated by kernel.\n",
2096 xisr->sadb_x_ipsecrequest_reqid));
2097 xisr->sadb_x_ipsecrequest_reqid = 0;
2098 }
2099
2100 /* allocate new reqid id if reqid is zero. */
2101 if (xisr->sadb_x_ipsecrequest_reqid == 0) {
2102 u_int16_t reqid;
2103 if ((reqid = key_newreqid()) == 0) {
2104 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2105 *error = ENOBUFS;
2106 return NULL;
2107 }
2108 (*p_isr)->saidx.reqid = reqid;
2109 xisr->sadb_x_ipsecrequest_reqid = reqid;
2110 } else {
2111 /* set it for manual keying. */
2112 (*p_isr)->saidx.reqid =
2113 xisr->sadb_x_ipsecrequest_reqid;
2114 }
2115 break;
2116
2117 default:
2118 ipseclog((LOG_DEBUG, "key_msg2sp: invalid level=%u\n",
2119 xisr->sadb_x_ipsecrequest_level));
2120 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2121 *error = EINVAL;
2122 return NULL;
2123 }
2124 (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
2125
2126 /* set IP addresses if there */
2127 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
2128 struct sockaddr *paddr;
2129
2130 if (tlen < xisr->sadb_x_ipsecrequest_len) {
2131 ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
2132 "address length.\n"));
2133 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2134 *error = EINVAL;
2135 return NULL;
2136 }
2137
2138 paddr = (struct sockaddr *)(xisr + 1);
2139 uint8_t src_len = paddr->sa_len;
2140
2141 /* +sizeof(uint8_t) for dst_len below */
2142 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr) + src_len + sizeof(uint8_t)) {
2143 ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
2144 "invalid source address length.\n"));
2145 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2146 *error = EINVAL;
2147 return NULL;
2148 }
2149
2150 /* validity check */
2151 if (paddr->sa_len
2152 > sizeof((*p_isr)->saidx.src)) {
2153 ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
2154 "address length.\n"));
2155 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2156 *error = EINVAL;
2157 return NULL;
2158 }
2159
2160 bcopy(src: paddr, dst: &(*p_isr)->saidx.src,
2161 MIN(paddr->sa_len, sizeof((*p_isr)->saidx.src)));
2162
2163 paddr = (struct sockaddr *)((caddr_t)paddr + paddr->sa_len);
2164 uint8_t dst_len = paddr->sa_len;
2165
2166 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr) + src_len + dst_len) {
2167 ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
2168 "invalid dest address length.\n"));
2169 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2170 *error = EINVAL;
2171 return NULL;
2172 }
2173
2174 /* validity check */
2175 if (paddr->sa_len
2176 > sizeof((*p_isr)->saidx.dst)) {
2177 ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
2178 "address length.\n"));
2179 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2180 *error = EINVAL;
2181 return NULL;
2182 }
2183
2184 bcopy(src: paddr, dst: &(*p_isr)->saidx.dst,
2185 MIN(paddr->sa_len, sizeof((*p_isr)->saidx.dst)));
2186 }
2187
2188 (*p_isr)->sp = newsp;
2189
2190 /* initialization for the next. */
2191 p_isr = &(*p_isr)->next;
2192 tlen -= xisr->sadb_x_ipsecrequest_len;
2193
2194 /* validity check */
2195 if (tlen < 0) {
2196 ipseclog((LOG_DEBUG, "key_msg2sp: becoming tlen < 0.\n"));
2197 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2198 *error = EINVAL;
2199 return NULL;
2200 }
2201
2202 xisr = (struct sadb_x_ipsecrequest *)(void *)
2203 ((caddr_t)xisr + xisr->sadb_x_ipsecrequest_len);
2204 }
2205 }
2206 break;
2207 default:
2208 ipseclog((LOG_DEBUG, "key_msg2sp: invalid policy type.\n"));
2209 key_freesp(sp: newsp, KEY_SADB_UNLOCKED);
2210 *error = EINVAL;
2211 return NULL;
2212 }
2213
2214 *error = 0;
2215 return newsp;
2216}
2217
2218static u_int16_t
2219key_newreqid(void)
2220{
2221 lck_mtx_lock(sadb_mutex);
2222 static u_int16_t auto_reqid = IPSEC_MANUAL_REQID_MAX + 1;
2223 int done = 0;
2224
2225 /* The reqid must be limited to 16 bits because the PF_KEY message format only uses
2226 * 16 bits for this field. Once it becomes larger than 16 bits - ipsec fails to
2227 * work anymore. Changing the PF_KEY message format would introduce compatibility
2228 * issues. This code now tests to see if the tentative reqid is in use */
2229
2230 while (!done) {
2231 struct secpolicy *sp;
2232 struct ipsecrequest *isr;
2233 int dir;
2234
2235 auto_reqid = (auto_reqid == 0xFFFF
2236 ? IPSEC_MANUAL_REQID_MAX + 1 : auto_reqid + 1);
2237
2238 /* check for uniqueness */
2239 done = 1;
2240 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2241 LIST_FOREACH(sp, &sptree[dir], chain) {
2242 for (isr = sp->req; isr != NULL; isr = isr->next) {
2243 if (isr->saidx.reqid == auto_reqid) {
2244 done = 0;
2245 break;
2246 }
2247 }
2248 if (done == 0) {
2249 break;
2250 }
2251 }
2252 if (done == 0) {
2253 break;
2254 }
2255 }
2256 }
2257
2258 lck_mtx_unlock(sadb_mutex);
2259 return auto_reqid;
2260}
2261
2262/*
2263 * copy secpolicy struct to sadb_x_policy structure indicated.
2264 */
2265struct mbuf *
2266key_sp2msg(
2267 struct secpolicy *sp)
2268{
2269 struct sadb_x_policy *xpl;
2270 u_int tlen;
2271 caddr_t p;
2272 struct mbuf *m;
2273
2274 /* sanity check. */
2275 if (sp == NULL) {
2276 panic("key_sp2msg: NULL pointer was passed.");
2277 }
2278
2279 tlen = key_getspreqmsglen(sp);
2280 if (PFKEY_UNIT64(tlen) > UINT16_MAX) {
2281 ipseclog((LOG_ERR, "key_getspreqmsglen returned length %u\n",
2282 tlen));
2283 return NULL;
2284 }
2285
2286 m = key_alloc_mbuf(tlen);
2287 if (!m || m->m_next) { /*XXX*/
2288 if (m) {
2289 m_freem(m);
2290 }
2291 return NULL;
2292 }
2293
2294 m->m_len = tlen;
2295 m->m_next = NULL;
2296 xpl = mtod(m, struct sadb_x_policy *);
2297 bzero(s: xpl, n: tlen);
2298
2299 xpl->sadb_x_policy_len = (u_int16_t)PFKEY_UNIT64(tlen);
2300 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2301 xpl->sadb_x_policy_type = (u_int16_t)sp->policy;
2302 xpl->sadb_x_policy_dir = sp->spidx.dir;
2303 xpl->sadb_x_policy_id = sp->id;
2304 p = (caddr_t)xpl + sizeof(*xpl);
2305
2306 /* if is the policy for ipsec ? */
2307 if (sp->policy == IPSEC_POLICY_IPSEC) {
2308 struct sadb_x_ipsecrequest *xisr;
2309 struct ipsecrequest *isr;
2310
2311 for (isr = sp->req; isr != NULL; isr = isr->next) {
2312 xisr = (struct sadb_x_ipsecrequest *)(void *)p;
2313
2314 xisr->sadb_x_ipsecrequest_proto = isr->saidx.proto;
2315 xisr->sadb_x_ipsecrequest_mode = isr->saidx.mode;
2316 xisr->sadb_x_ipsecrequest_level = (u_int8_t)isr->level;
2317 xisr->sadb_x_ipsecrequest_reqid = (u_int16_t)isr->saidx.reqid;
2318
2319 p += sizeof(*xisr);
2320 bcopy(src: &isr->saidx.src, dst: p, n: isr->saidx.src.ss_len);
2321 p += isr->saidx.src.ss_len;
2322 bcopy(src: &isr->saidx.dst, dst: p, n: isr->saidx.dst.ss_len);
2323 p += isr->saidx.src.ss_len;
2324
2325 xisr->sadb_x_ipsecrequest_len =
2326 PFKEY_ALIGN8(sizeof(*xisr)
2327 + isr->saidx.src.ss_len
2328 + isr->saidx.dst.ss_len);
2329 }
2330 }
2331
2332 return m;
2333}
2334
2335/* m will not be freed nor modified */
2336static struct mbuf *
2337key_gather_mbuf(struct mbuf *m, const struct sadb_msghdr *mhp,
2338 int ndeep, int nitem, int *items)
2339{
2340 int idx;
2341 int i;
2342 struct mbuf *result = NULL, *n;
2343 int len;
2344
2345 if (m == NULL || mhp == NULL) {
2346 panic("null pointer passed to key_gather");
2347 }
2348
2349 for (i = 0; i < nitem; i++) {
2350 idx = items[i];
2351 if (idx < 0 || idx > SADB_EXT_MAX) {
2352 goto fail;
2353 }
2354 /* don't attempt to pull empty extension */
2355 if (idx == SADB_EXT_RESERVED && mhp->msg == NULL) {
2356 continue;
2357 }
2358 if (idx != SADB_EXT_RESERVED &&
2359 (mhp->ext[idx] == NULL || mhp->extlen[idx] == 0)) {
2360 continue;
2361 }
2362
2363 if (idx == SADB_EXT_RESERVED) {
2364 len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
2365 MGETHDR(n, M_WAITOK, MT_DATA); // sadb_msg len < MHLEN - enforced by _CASSERT
2366 if (!n) {
2367 goto fail;
2368 }
2369 n->m_len = len;
2370 n->m_next = NULL;
2371 m_copydata(m, 0, sizeof(struct sadb_msg),
2372 mtod(n, caddr_t));
2373 } else if (i < ndeep) {
2374 len = mhp->extlen[idx];
2375 n = key_alloc_mbuf(len);
2376 if (!n || n->m_next) { /*XXX*/
2377 if (n) {
2378 m_freem(n);
2379 }
2380 goto fail;
2381 }
2382 m_copydata(m, mhp->extoff[idx], mhp->extlen[idx],
2383 mtod(n, caddr_t));
2384 } else {
2385 n = m_copym(m, mhp->extoff[idx], mhp->extlen[idx],
2386 M_WAITOK);
2387 }
2388 if (n == NULL) {
2389 goto fail;
2390 }
2391
2392 if (result) {
2393 m_cat(result, n);
2394 } else {
2395 result = n;
2396 }
2397 }
2398
2399 if ((result->m_flags & M_PKTHDR) != 0) {
2400 result->m_pkthdr.len = 0;
2401 for (n = result; n; n = n->m_next) {
2402 result->m_pkthdr.len += n->m_len;
2403 }
2404 }
2405
2406 return result;
2407
2408fail:
2409 m_freem(result);
2410 return NULL;
2411}
2412
2413/*
2414 * SADB_X_SPDADD, SADB_X_SPDSETIDX or SADB_X_SPDUPDATE processing
2415 * add a entry to SP database, when received
2416 * <base, address(SD), (lifetime(H),) policy>
2417 * from the user(?).
2418 * Adding to SP database,
2419 * and send
2420 * <base, address(SD), (lifetime(H),) policy>
2421 * to the socket which was send.
2422 *
2423 * SPDADD set a unique policy entry.
2424 * SPDSETIDX like SPDADD without a part of policy requests.
2425 * SPDUPDATE replace a unique policy entry.
2426 *
2427 * m will always be freed.
2428 */
2429static int
2430key_spdadd(
2431 struct socket *so,
2432 struct mbuf *m,
2433 const struct sadb_msghdr *mhp)
2434{
2435 struct sadb_address *src0, *dst0, *src1 = NULL, *dst1 = NULL;
2436 struct sadb_x_policy *xpl0, *xpl;
2437 struct sadb_lifetime *lft = NULL;
2438 struct secpolicyindex spidx;
2439 struct secpolicy *newsp;
2440 ifnet_t internal_if = NULL;
2441 char *outgoing_if = NULL;
2442 char *ipsec_if = NULL;
2443 struct sadb_x_ipsecif *ipsecifopts = NULL;
2444 int error;
2445 int use_src_range = 0;
2446 int use_dst_range = 0;
2447 int init_disabled = 0;
2448 int address_family, address_len;
2449
2450 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2451
2452 /* sanity check */
2453 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
2454 panic("key_spdadd: NULL pointer is passed.");
2455 }
2456
2457 if (mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_START] != NULL && mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_END] != NULL) {
2458 use_src_range = 1;
2459 }
2460 if (mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_START] != NULL && mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_END] != NULL) {
2461 use_dst_range = 1;
2462 }
2463
2464 if ((!use_src_range && mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL) ||
2465 (!use_dst_range && mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) ||
2466 mhp->ext[SADB_X_EXT_POLICY] == NULL) {
2467 ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
2468 return key_senderror(so, m, EINVAL);
2469 }
2470 if ((use_src_range && (mhp->extlen[SADB_X_EXT_ADDR_RANGE_SRC_START] < sizeof(struct sadb_address)
2471 || mhp->extlen[SADB_X_EXT_ADDR_RANGE_SRC_END] < sizeof(struct sadb_address))) ||
2472 (!use_src_range && mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address)) ||
2473 (use_dst_range && (mhp->extlen[SADB_X_EXT_ADDR_RANGE_DST_START] < sizeof(struct sadb_address)
2474 || mhp->extlen[SADB_X_EXT_ADDR_RANGE_DST_END] < sizeof(struct sadb_address))) ||
2475 (!use_dst_range && mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) ||
2476 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
2477 ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
2478 return key_senderror(so, m, EINVAL);
2479 }
2480 if (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL) {
2481 if (mhp->extlen[SADB_EXT_LIFETIME_HARD]
2482 < sizeof(struct sadb_lifetime)) {
2483 ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
2484 return key_senderror(so, m, EINVAL);
2485 }
2486 lft = (struct sadb_lifetime *)
2487 (void *)mhp->ext[SADB_EXT_LIFETIME_HARD];
2488 }
2489 if (mhp->ext[SADB_X_EXT_IPSECIF] != NULL) {
2490 if (mhp->extlen[SADB_X_EXT_IPSECIF] < sizeof(struct sadb_x_ipsecif)) {
2491 ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
2492 return key_senderror(so, m, EINVAL);
2493 }
2494 }
2495
2496 if (use_src_range) {
2497 src0 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_START];
2498 src1 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_END];
2499 } else {
2500 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
2501 }
2502 if (use_dst_range) {
2503 dst0 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_START];
2504 dst1 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_END];
2505 } else {
2506 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
2507 }
2508 xpl0 = (struct sadb_x_policy *)(void *)mhp->ext[SADB_X_EXT_POLICY];
2509 ipsecifopts = (struct sadb_x_ipsecif *)(void *)mhp->ext[SADB_X_EXT_IPSECIF];
2510
2511 /* check addresses */
2512 address_family = ((struct sockaddr *)(src0 + 1))->sa_family;
2513 address_len = ((struct sockaddr *)(src0 + 1))->sa_len;
2514 if (use_src_range) {
2515 if (((struct sockaddr *)(src1 + 1))->sa_family != address_family ||
2516 ((struct sockaddr *)(src1 + 1))->sa_len != address_len) {
2517 return key_senderror(so, m, EINVAL);
2518 }
2519 }
2520 if (((struct sockaddr *)(dst0 + 1))->sa_family != address_family ||
2521 ((struct sockaddr *)(dst0 + 1))->sa_len != address_len) {
2522 return key_senderror(so, m, EINVAL);
2523 }
2524 if (use_dst_range) {
2525 if (((struct sockaddr *)(dst1 + 1))->sa_family != address_family ||
2526 ((struct sockaddr *)(dst1 + 1))->sa_len != address_len) {
2527 return key_senderror(so, m, EINVAL);
2528 }
2529 }
2530
2531 /* checking the direction. */
2532 switch (xpl0->sadb_x_policy_dir) {
2533 case IPSEC_DIR_INBOUND:
2534 case IPSEC_DIR_OUTBOUND:
2535 break;
2536 default:
2537 ipseclog((LOG_DEBUG, "key_spdadd: Invalid SP direction.\n"));
2538 return key_senderror(so, m, EINVAL);
2539 }
2540
2541 /* check policy */
2542 /* key_spdadd() accepts DISCARD, NONE and IPSEC. */
2543 if (xpl0->sadb_x_policy_type == IPSEC_POLICY_ENTRUST
2544 || xpl0->sadb_x_policy_type == IPSEC_POLICY_BYPASS) {
2545 ipseclog((LOG_DEBUG, "key_spdadd: Invalid policy type.\n"));
2546 return key_senderror(so, m, EINVAL);
2547 }
2548
2549 /* policy requests are mandatory when action is ipsec. */
2550 if (mhp->msg->sadb_msg_type != SADB_X_SPDSETIDX
2551 && xpl0->sadb_x_policy_type == IPSEC_POLICY_IPSEC
2552 && mhp->extlen[SADB_X_EXT_POLICY] <= sizeof(*xpl0)) {
2553 ipseclog((LOG_DEBUG, "key_spdadd: some policy requests part required.\n"));
2554 return key_senderror(so, m, EINVAL);
2555 }
2556
2557 /* Process interfaces */
2558 if (ipsecifopts != NULL) {
2559 ipsecifopts->sadb_x_ipsecif_internal_if[IFXNAMSIZ - 1] = '\0';
2560 ipsecifopts->sadb_x_ipsecif_outgoing_if[IFXNAMSIZ - 1] = '\0';
2561 ipsecifopts->sadb_x_ipsecif_ipsec_if[IFXNAMSIZ - 1] = '\0';
2562
2563 if (ipsecifopts->sadb_x_ipsecif_internal_if[0]) {
2564 ifnet_find_by_name(ifname: ipsecifopts->sadb_x_ipsecif_internal_if, interface: &internal_if);
2565 }
2566 if (ipsecifopts->sadb_x_ipsecif_outgoing_if[0]) {
2567 outgoing_if = ipsecifopts->sadb_x_ipsecif_outgoing_if;
2568 }
2569 if (ipsecifopts->sadb_x_ipsecif_ipsec_if[0]) {
2570 ipsec_if = ipsecifopts->sadb_x_ipsecif_ipsec_if;
2571 }
2572 init_disabled = ipsecifopts->sadb_x_ipsecif_init_disabled;
2573 }
2574
2575 /* make secindex */
2576 /* XXX boundary check against sa_len */
2577 KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir,
2578 src0 + 1,
2579 dst0 + 1,
2580 src0->sadb_address_prefixlen,
2581 dst0->sadb_address_prefixlen,
2582 src0->sadb_address_proto,
2583 internal_if,
2584 use_src_range ? src0 + 1 : NULL,
2585 use_src_range ? src1 + 1 : NULL,
2586 use_dst_range ? dst0 + 1 : NULL,
2587 use_dst_range ? dst1 + 1 : NULL,
2588 &spidx);
2589
2590 /*
2591 * checking there is SP already or not.
2592 * SPDUPDATE doesn't depend on whether there is a SP or not.
2593 * If the type is either SPDADD or SPDSETIDX AND a SP is found,
2594 * then error.
2595 */
2596 lck_mtx_lock(sadb_mutex);
2597 newsp = key_getsp(spidx: &spidx);
2598 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
2599 if (newsp) {
2600 newsp->state = IPSEC_SPSTATE_DEAD;
2601 key_freesp(sp: newsp, KEY_SADB_LOCKED);
2602 }
2603 } else {
2604 if (newsp != NULL) {
2605 key_freesp(sp: newsp, KEY_SADB_LOCKED);
2606 ipseclog((LOG_DEBUG, "key_spdadd: a SP entry exists already.\n"));
2607 lck_mtx_unlock(sadb_mutex);
2608 if (internal_if) {
2609 ifnet_release(interface: internal_if);
2610 internal_if = NULL;
2611 }
2612 return key_senderror(so, m, EEXIST);
2613 }
2614 }
2615 lck_mtx_unlock(sadb_mutex);
2616
2617 /* allocation new SP entry */
2618 if ((newsp = key_msg2sp(xpl0, PFKEY_EXTLEN(xpl0), error: &error)) == NULL) {
2619 if (internal_if) {
2620 ifnet_release(interface: internal_if);
2621 internal_if = NULL;
2622 }
2623 return key_senderror(so, m, error);
2624 }
2625
2626 if ((newsp->id = key_getnewspid()) == 0) {
2627 keydb_delsecpolicy(newsp);
2628 if (internal_if) {
2629 ifnet_release(interface: internal_if);
2630 internal_if = NULL;
2631 }
2632 return key_senderror(so, m, ENOBUFS);
2633 }
2634
2635 /* XXX boundary check against sa_len */
2636 KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir,
2637 src0 + 1,
2638 dst0 + 1,
2639 src0->sadb_address_prefixlen,
2640 dst0->sadb_address_prefixlen,
2641 src0->sadb_address_proto,
2642 internal_if,
2643 use_src_range ? src0 + 1 : NULL,
2644 use_src_range ? src1 + 1 : NULL,
2645 use_dst_range ? dst0 + 1 : NULL,
2646 use_dst_range ? dst1 + 1 : NULL,
2647 &newsp->spidx);
2648
2649#if 1
2650 /*
2651 * allow IPv6 over IPv4 or IPv4 over IPv6 tunnels using ESP -
2652 * otherwise reject if inner and outer address families not equal
2653 */
2654 if (newsp->req && newsp->req->saidx.src.ss_family) {
2655 struct sockaddr *sa;
2656 sa = (struct sockaddr *)(src0 + 1);
2657 if (sa->sa_family != newsp->req->saidx.src.ss_family) {
2658 if (newsp->req->saidx.mode != IPSEC_MODE_TUNNEL || newsp->req->saidx.proto != IPPROTO_ESP) {
2659 keydb_delsecpolicy(newsp);
2660 if (internal_if) {
2661 ifnet_release(interface: internal_if);
2662 internal_if = NULL;
2663 }
2664 return key_senderror(so, m, EINVAL);
2665 }
2666 }
2667 }
2668 if (newsp->req && newsp->req->saidx.dst.ss_family) {
2669 struct sockaddr *sa;
2670 sa = (struct sockaddr *)(dst0 + 1);
2671 if (sa->sa_family != newsp->req->saidx.dst.ss_family) {
2672 if (newsp->req->saidx.mode != IPSEC_MODE_TUNNEL || newsp->req->saidx.proto != IPPROTO_ESP) {
2673 keydb_delsecpolicy(newsp);
2674 if (internal_if) {
2675 ifnet_release(interface: internal_if);
2676 internal_if = NULL;
2677 }
2678 return key_senderror(so, m, EINVAL);
2679 }
2680 }
2681 }
2682#endif
2683
2684 const u_int64_t current_time_ns = key_get_continuous_time_ns();
2685 newsp->created = current_time_ns;
2686 newsp->lastused = current_time_ns;
2687
2688 if (lft != NULL) {
2689 // Convert to nanoseconds
2690 u_int64_t lifetime_ns;
2691 if (__improbable(os_mul_overflow(lft->sadb_lifetime_addtime, NSEC_PER_SEC, &lifetime_ns))) {
2692 ipseclog((LOG_DEBUG, "key_spdadd: invalid lifetime value %llu.\n",
2693 lft->sadb_lifetime_addtime));
2694 return key_senderror(so, m, EINVAL);
2695 }
2696 newsp->lifetime = lifetime_ns;
2697
2698 u_int64_t validtime_ns;
2699 if (__improbable(os_mul_overflow(lft->sadb_lifetime_usetime, NSEC_PER_SEC, &validtime_ns))) {
2700 ipseclog((LOG_DEBUG, "key_spdadd: invalid use time value %llu.\n",
2701 lft->sadb_lifetime_usetime));
2702 return key_senderror(so, m, EINVAL);
2703 }
2704 newsp->validtime = validtime_ns;
2705 } else {
2706 newsp->lifetime = 0;
2707 newsp->validtime = 0;
2708 }
2709
2710
2711 if (outgoing_if != NULL) {
2712 ifnet_find_by_name(ifname: outgoing_if, interface: &newsp->outgoing_if);
2713 }
2714 if (ipsec_if != NULL) {
2715 ifnet_find_by_name(ifname: ipsec_if, interface: &newsp->ipsec_if);
2716 }
2717 if (init_disabled > 0) {
2718 newsp->disabled = 1;
2719 }
2720
2721 newsp->refcnt = 1; /* do not reclaim until I say I do */
2722 newsp->state = IPSEC_SPSTATE_ALIVE;
2723 lck_mtx_lock(sadb_mutex);
2724 /*
2725 * policies of type generate should be at the end of the SPD
2726 * because they function as default discard policies
2727 * Don't start timehandler for generate policies
2728 */
2729 if (newsp->policy == IPSEC_POLICY_GENERATE) {
2730 LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain);
2731 } else { /* XXX until we have policy ordering in the kernel */
2732 struct secpolicy *tmpsp;
2733
2734 LIST_FOREACH(tmpsp, &sptree[newsp->spidx.dir], chain)
2735 if (tmpsp->policy == IPSEC_POLICY_GENERATE) {
2736 break;
2737 }
2738 if (tmpsp) {
2739 LIST_INSERT_BEFORE(tmpsp, newsp, chain);
2740 } else {
2741 LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain);
2742 }
2743 key_start_timehandler();
2744 }
2745
2746 ipsec_policy_count++;
2747 /* Turn off the ipsec bypass */
2748 if (ipsec_bypass != 0) {
2749 ipsec_bypass = 0;
2750 }
2751
2752 /* delete the entry in spacqtree */
2753 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
2754 struct secspacq *spacq;
2755 if ((spacq = key_getspacq(&spidx)) != NULL) {
2756 /* reset counter in order to deletion by timehandler. */
2757 spacq->created = key_get_continuous_time_ns();
2758 spacq->count = 0;
2759 }
2760 }
2761 lck_mtx_unlock(sadb_mutex);
2762
2763 {
2764 struct mbuf *n, *mpolicy;
2765 struct sadb_msg *newmsg;
2766 int off;
2767
2768 /* create new sadb_msg to reply. */
2769 if (lft) {
2770 int mbufItems[] = {SADB_EXT_RESERVED, SADB_X_EXT_POLICY,
2771 SADB_EXT_LIFETIME_HARD, SADB_EXT_ADDRESS_SRC,
2772 SADB_EXT_ADDRESS_DST, SADB_X_EXT_ADDR_RANGE_SRC_START, SADB_X_EXT_ADDR_RANGE_SRC_END,
2773 SADB_X_EXT_ADDR_RANGE_DST_START, SADB_X_EXT_ADDR_RANGE_DST_END};
2774 n = key_gather_mbuf(m, mhp, ndeep: 2, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
2775 } else {
2776 int mbufItems[] = {SADB_EXT_RESERVED, SADB_X_EXT_POLICY,
2777 SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST,
2778 SADB_X_EXT_ADDR_RANGE_SRC_START, SADB_X_EXT_ADDR_RANGE_SRC_END,
2779 SADB_X_EXT_ADDR_RANGE_DST_START, SADB_X_EXT_ADDR_RANGE_DST_END};
2780 n = key_gather_mbuf(m, mhp, ndeep: 2, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
2781 }
2782 if (!n) {
2783 return key_senderror(so, m, ENOBUFS);
2784 }
2785
2786 if (n->m_len < sizeof(*newmsg)) {
2787 n = m_pullup(n, sizeof(*newmsg));
2788 if (!n) {
2789 return key_senderror(so, m, ENOBUFS);
2790 }
2791 }
2792 newmsg = mtod(n, struct sadb_msg *);
2793 newmsg->sadb_msg_errno = 0;
2794
2795 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
2796 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
2797
2798 off = 0;
2799 mpolicy = m_pulldown(n, PFKEY_ALIGN8(sizeof(struct sadb_msg)),
2800 sizeof(*xpl), &off);
2801 if (mpolicy == NULL) {
2802 /* n is already freed */
2803 return key_senderror(so, m, ENOBUFS);
2804 }
2805 xpl = (struct sadb_x_policy *)(void *)(mtod(mpolicy, caddr_t) + off);
2806 if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
2807 m_freem(n);
2808 return key_senderror(so, m, EINVAL);
2809 }
2810 xpl->sadb_x_policy_id = newsp->id;
2811
2812 m_freem(m);
2813 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
2814 }
2815}
2816
2817/*
2818 * get new policy id.
2819 * OUT:
2820 * 0: failure.
2821 * others: success.
2822 */
2823static u_int32_t
2824key_getnewspid(void)
2825{
2826 u_int32_t newid = 0;
2827 int count = key_spi_trycnt; /* XXX */
2828 struct secpolicy *sp;
2829
2830 /* when requesting to allocate spi ranged */
2831 lck_mtx_lock(sadb_mutex);
2832 while (count--) {
2833 newid = (policy_id = (policy_id == ~0 ? 1 : policy_id + 1));
2834
2835 if ((sp = __key_getspbyid(id: newid)) == NULL) {
2836 break;
2837 }
2838
2839 key_freesp(sp, KEY_SADB_LOCKED);
2840 }
2841 lck_mtx_unlock(sadb_mutex);
2842 if (count == 0 || newid == 0) {
2843 ipseclog((LOG_DEBUG, "key_getnewspid: to allocate policy id is failed.\n"));
2844 return 0;
2845 }
2846
2847 return newid;
2848}
2849
2850/*
2851 * SADB_SPDDELETE processing
2852 * receive
2853 * <base, address(SD), policy(*)>
2854 * from the user(?), and set SADB_SASTATE_DEAD,
2855 * and send,
2856 * <base, address(SD), policy(*)>
2857 * to the ikmpd.
2858 * policy(*) including direction of policy.
2859 *
2860 * m will always be freed.
2861 */
2862static int
2863key_spddelete(
2864 struct socket *so,
2865 struct mbuf *m,
2866 const struct sadb_msghdr *mhp)
2867{
2868 struct sadb_address *src0, *dst0, *src1 = NULL, *dst1 = NULL;
2869 struct sadb_x_policy *xpl0;
2870 struct secpolicyindex spidx;
2871 struct secpolicy *sp;
2872 ifnet_t internal_if = NULL;
2873 struct sadb_x_ipsecif *ipsecifopts = NULL;
2874 int use_src_range = 0;
2875 int use_dst_range = 0;
2876
2877 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2878
2879 /* sanity check */
2880 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
2881 panic("key_spddelete: NULL pointer is passed.");
2882 }
2883
2884 if (mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_START] != NULL && mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_END] != NULL) {
2885 use_src_range = 1;
2886 }
2887 if (mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_START] != NULL && mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_END] != NULL) {
2888 use_dst_range = 1;
2889 }
2890
2891 if ((!use_src_range && mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL) ||
2892 (!use_dst_range && mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) ||
2893 mhp->ext[SADB_X_EXT_POLICY] == NULL) {
2894 ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n"));
2895 return key_senderror(so, m, EINVAL);
2896 }
2897 if ((use_src_range && (mhp->extlen[SADB_X_EXT_ADDR_RANGE_SRC_START] < sizeof(struct sadb_address)
2898 || mhp->extlen[SADB_X_EXT_ADDR_RANGE_SRC_END] < sizeof(struct sadb_address))) ||
2899 (!use_src_range && mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address)) ||
2900 (use_dst_range && (mhp->extlen[SADB_X_EXT_ADDR_RANGE_DST_START] < sizeof(struct sadb_address)
2901 || mhp->extlen[SADB_X_EXT_ADDR_RANGE_DST_END] < sizeof(struct sadb_address))) ||
2902 (!use_dst_range && mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) ||
2903 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
2904 ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n"));
2905 return key_senderror(so, m, EINVAL);
2906 }
2907
2908 if (use_src_range) {
2909 src0 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_START];
2910 src1 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_SRC_END];
2911 } else {
2912 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
2913 }
2914 if (use_dst_range) {
2915 dst0 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_START];
2916 dst1 = (struct sadb_address *)mhp->ext[SADB_X_EXT_ADDR_RANGE_DST_END];
2917 } else {
2918 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
2919 }
2920 xpl0 = (struct sadb_x_policy *)(void *)mhp->ext[SADB_X_EXT_POLICY];
2921 ipsecifopts = (struct sadb_x_ipsecif *)(void *)mhp->ext[SADB_X_EXT_IPSECIF];
2922
2923 /* checking the direction. */
2924 switch (xpl0->sadb_x_policy_dir) {
2925 case IPSEC_DIR_INBOUND:
2926 case IPSEC_DIR_OUTBOUND:
2927 break;
2928 default:
2929 ipseclog((LOG_DEBUG, "key_spddelete: Invalid SP direction.\n"));
2930 return key_senderror(so, m, EINVAL);
2931 }
2932
2933 /* Process interfaces */
2934 if (ipsecifopts != NULL) {
2935 ipsecifopts->sadb_x_ipsecif_internal_if[IFXNAMSIZ - 1] = '\0';
2936 ipsecifopts->sadb_x_ipsecif_outgoing_if[IFXNAMSIZ - 1] = '\0';
2937 ipsecifopts->sadb_x_ipsecif_ipsec_if[IFXNAMSIZ - 1] = '\0';
2938
2939 if (ipsecifopts->sadb_x_ipsecif_internal_if[0]) {
2940 ifnet_find_by_name(ifname: ipsecifopts->sadb_x_ipsecif_internal_if, interface: &internal_if);
2941 }
2942 }
2943
2944 /* make secindex */
2945 /* XXX boundary check against sa_len */
2946 KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir,
2947 src0 + 1,
2948 dst0 + 1,
2949 src0->sadb_address_prefixlen,
2950 dst0->sadb_address_prefixlen,
2951 src0->sadb_address_proto,
2952 internal_if,
2953 use_src_range ? src0 + 1 : NULL,
2954 use_src_range ? src1 + 1 : NULL,
2955 use_dst_range ? dst0 + 1 : NULL,
2956 use_dst_range ? dst1 + 1 : NULL,
2957 &spidx);
2958
2959 /* Is there SP in SPD ? */
2960 lck_mtx_lock(sadb_mutex);
2961 if ((sp = key_getsp(spidx: &spidx)) == NULL) {
2962 ipseclog((LOG_DEBUG, "key_spddelete: no SP found.\n"));
2963 lck_mtx_unlock(sadb_mutex);
2964 if (internal_if) {
2965 ifnet_release(interface: internal_if);
2966 internal_if = NULL;
2967 }
2968 return key_senderror(so, m, EINVAL);
2969 }
2970
2971 if (internal_if) {
2972 ifnet_release(interface: internal_if);
2973 internal_if = NULL;
2974 }
2975
2976 /* save policy id to buffer to be returned. */
2977 xpl0->sadb_x_policy_id = sp->id;
2978
2979 sp->state = IPSEC_SPSTATE_DEAD;
2980 key_freesp(sp, KEY_SADB_LOCKED);
2981 lck_mtx_unlock(sadb_mutex);
2982
2983
2984 {
2985 struct mbuf *n;
2986 struct sadb_msg *newmsg;
2987 int mbufItems[] = {SADB_EXT_RESERVED, SADB_X_EXT_POLICY,
2988 SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST,
2989 SADB_X_EXT_ADDR_RANGE_SRC_START, SADB_X_EXT_ADDR_RANGE_SRC_END,
2990 SADB_X_EXT_ADDR_RANGE_DST_START, SADB_X_EXT_ADDR_RANGE_DST_END};
2991
2992 /* create new sadb_msg to reply. */
2993 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
2994 if (!n) {
2995 return key_senderror(so, m, ENOBUFS);
2996 }
2997
2998 newmsg = mtod(n, struct sadb_msg *);
2999 newmsg->sadb_msg_errno = 0;
3000 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
3001 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
3002
3003 m_freem(m);
3004 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
3005 }
3006}
3007
3008/*
3009 * SADB_SPDDELETE2 processing
3010 * receive
3011 * <base, policy(*)>
3012 * from the user(?), and set SADB_SASTATE_DEAD,
3013 * and send,
3014 * <base, policy(*)>
3015 * to the ikmpd.
3016 * policy(*) including direction of policy.
3017 *
3018 * m will always be freed.
3019 */
3020static int
3021key_spddelete2(
3022 struct socket *so,
3023 struct mbuf *m,
3024 const struct sadb_msghdr *mhp)
3025{
3026 u_int32_t id;
3027 struct secpolicy *sp;
3028
3029 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3030
3031 /* sanity check */
3032 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
3033 panic("key_spddelete2: NULL pointer is passed.");
3034 }
3035
3036 if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
3037 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
3038 ipseclog((LOG_DEBUG, "key_spddelete2: invalid message is passed.\n"));
3039 key_senderror(so, m, EINVAL);
3040 return 0;
3041 }
3042
3043 id = ((struct sadb_x_policy *)
3044 (void *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
3045
3046 /* Is there SP in SPD ? */
3047 lck_mtx_lock(sadb_mutex);
3048 if ((sp = __key_getspbyid(id)) == NULL) {
3049 lck_mtx_unlock(sadb_mutex);
3050 ipseclog((LOG_DEBUG, "key_spddelete2: no SP found id:%u.\n", id));
3051 return key_senderror(so, m, EINVAL);
3052 }
3053
3054 sp->state = IPSEC_SPSTATE_DEAD;
3055 key_freesp(sp, KEY_SADB_LOCKED);
3056 lck_mtx_unlock(sadb_mutex);
3057
3058 {
3059 struct mbuf *n, *nn;
3060 struct sadb_msg *newmsg;
3061 int off, len;
3062
3063 /* create new sadb_msg to reply. */
3064 len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
3065
3066 if (len > MCLBYTES) {
3067 return key_senderror(so, m, ENOBUFS);
3068 }
3069 MGETHDR(n, M_WAITOK, MT_DATA);
3070 if (n && len > MHLEN) {
3071 MCLGET(n, M_WAITOK);
3072 if ((n->m_flags & M_EXT) == 0) {
3073 m_freem(n);
3074 n = NULL;
3075 }
3076 }
3077 if (!n) {
3078 return key_senderror(so, m, ENOBUFS);
3079 }
3080
3081 n->m_len = len;
3082 n->m_next = NULL;
3083 off = 0;
3084
3085 m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off);
3086 off += PFKEY_ALIGN8(sizeof(struct sadb_msg));
3087
3088#if DIAGNOSTIC
3089 if (off != len) {
3090 panic("length inconsistency in key_spddelete2");
3091 }
3092#endif
3093
3094 n->m_next = m_copym(m, mhp->extoff[SADB_X_EXT_POLICY],
3095 mhp->extlen[SADB_X_EXT_POLICY], M_WAITOK);
3096 if (!n->m_next) {
3097 m_freem(n);
3098 return key_senderror(so, m, ENOBUFS);
3099 }
3100
3101 n->m_pkthdr.len = 0;
3102 for (nn = n; nn; nn = nn->m_next) {
3103 n->m_pkthdr.len += nn->m_len;
3104 }
3105
3106 newmsg = mtod(n, struct sadb_msg *);
3107 newmsg->sadb_msg_errno = 0;
3108 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
3109 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
3110
3111 m_freem(m);
3112 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
3113 }
3114}
3115
3116static int
3117key_spdenable(
3118 struct socket *so,
3119 struct mbuf *m,
3120 const struct sadb_msghdr *mhp)
3121{
3122 u_int32_t id;
3123 struct secpolicy *sp;
3124
3125 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3126
3127 /* sanity check */
3128 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
3129 panic("key_spdenable: NULL pointer is passed.");
3130 }
3131
3132 if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
3133 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
3134 ipseclog((LOG_DEBUG, "key_spdenable: invalid message is passed.\n"));
3135 key_senderror(so, m, EINVAL);
3136 return 0;
3137 }
3138
3139 id = ((struct sadb_x_policy *)
3140 (void *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
3141
3142 /* Is there SP in SPD ? */
3143 lck_mtx_lock(sadb_mutex);
3144 if ((sp = __key_getspbyid(id)) == NULL) {
3145 lck_mtx_unlock(sadb_mutex);
3146 ipseclog((LOG_DEBUG, "key_spdenable: no SP found id:%u.\n", id));
3147 return key_senderror(so, m, EINVAL);
3148 }
3149
3150 sp->disabled = 0;
3151 key_freesp(sp, KEY_SADB_LOCKED);
3152 lck_mtx_unlock(sadb_mutex);
3153
3154 {
3155 struct mbuf *n;
3156 struct sadb_msg *newmsg;
3157 int mbufItems[] = {SADB_EXT_RESERVED, SADB_X_EXT_POLICY};
3158
3159 /* create new sadb_msg to reply. */
3160 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
3161 if (!n) {
3162 return key_senderror(so, m, ENOBUFS);
3163 }
3164
3165 if (n->m_len < sizeof(struct sadb_msg)) {
3166 n = m_pullup(n, sizeof(struct sadb_msg));
3167 if (n == NULL) {
3168 return key_senderror(so, m, ENOBUFS);
3169 }
3170 }
3171 newmsg = mtod(n, struct sadb_msg *);
3172 newmsg->sadb_msg_errno = 0;
3173 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
3174 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
3175
3176 m_freem(m);
3177 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
3178 }
3179}
3180
3181static int
3182key_spddisable(
3183 struct socket *so,
3184 struct mbuf *m,
3185 const struct sadb_msghdr *mhp)
3186{
3187 u_int32_t id;
3188 struct secpolicy *sp;
3189
3190 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3191
3192 /* sanity check */
3193 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
3194 panic("key_spddisable: NULL pointer is passed.");
3195 }
3196
3197 if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
3198 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
3199 ipseclog((LOG_DEBUG, "key_spddisable: invalid message is passed.\n"));
3200 key_senderror(so, m, EINVAL);
3201 return 0;
3202 }
3203
3204 id = ((struct sadb_x_policy *)
3205 (void *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
3206
3207 /* Is there SP in SPD ? */
3208 lck_mtx_lock(sadb_mutex);
3209 if ((sp = __key_getspbyid(id)) == NULL) {
3210 lck_mtx_unlock(sadb_mutex);
3211 ipseclog((LOG_DEBUG, "key_spddisable: no SP found id:%u.\n", id));
3212 return key_senderror(so, m, EINVAL);
3213 }
3214
3215 sp->disabled = 1;
3216 key_freesp(sp, KEY_SADB_LOCKED);
3217 lck_mtx_unlock(sadb_mutex);
3218
3219 {
3220 struct mbuf *n;
3221 struct sadb_msg *newmsg;
3222 int mbufItems[] = {SADB_EXT_RESERVED, SADB_X_EXT_POLICY};
3223
3224 /* create new sadb_msg to reply. */
3225 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
3226 if (!n) {
3227 return key_senderror(so, m, ENOBUFS);
3228 }
3229
3230 if (n->m_len < sizeof(struct sadb_msg)) {
3231 n = m_pullup(n, sizeof(struct sadb_msg));
3232 if (n == NULL) {
3233 return key_senderror(so, m, ENOBUFS);
3234 }
3235 }
3236 newmsg = mtod(n, struct sadb_msg *);
3237 newmsg->sadb_msg_errno = 0;
3238 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
3239 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
3240
3241 m_freem(m);
3242 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
3243 }
3244}
3245
3246/*
3247 * SADB_X_GET processing
3248 * receive
3249 * <base, policy(*)>
3250 * from the user(?),
3251 * and send,
3252 * <base, address(SD), policy>
3253 * to the ikmpd.
3254 * policy(*) including direction of policy.
3255 *
3256 * m will always be freed.
3257 */
3258static int
3259key_spdget(
3260 struct socket *so,
3261 struct mbuf *m,
3262 const struct sadb_msghdr *mhp)
3263{
3264 u_int32_t id;
3265 struct secpolicy *sp;
3266 struct mbuf *n;
3267
3268 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3269
3270 /* sanity check */
3271 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
3272 panic("key_spdget: NULL pointer is passed.");
3273 }
3274
3275 if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
3276 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
3277 ipseclog((LOG_DEBUG, "key_spdget: invalid message is passed.\n"));
3278 return key_senderror(so, m, EINVAL);
3279 }
3280
3281 id = ((struct sadb_x_policy *)
3282 (void *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
3283
3284 /* Is there SP in SPD ? */
3285 lck_mtx_lock(sadb_mutex);
3286 if ((sp = __key_getspbyid(id)) == NULL) {
3287 ipseclog((LOG_DEBUG, "key_spdget: no SP found id:%u.\n", id));
3288 lck_mtx_unlock(sadb_mutex);
3289 return key_senderror(so, m, ENOENT);
3290 }
3291 lck_mtx_unlock(sadb_mutex);
3292 n = key_setdumpsp(sp, SADB_X_SPDGET, 0, mhp->msg->sadb_msg_pid);
3293 key_freesp(sp, KEY_SADB_UNLOCKED);
3294 if (n != NULL) {
3295 m_freem(m);
3296 return key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
3297 } else {
3298 return key_senderror(so, m, ENOBUFS);
3299 }
3300}
3301
3302/*
3303 * SADB_X_SPDACQUIRE processing.
3304 * Acquire policy and SA(s) for a *OUTBOUND* packet.
3305 * send
3306 * <base, policy(*)>
3307 * to KMD, and expect to receive
3308 * <base> with SADB_X_SPDACQUIRE if error occurred,
3309 * or
3310 * <base, policy>
3311 * with SADB_X_SPDUPDATE from KMD by PF_KEY.
3312 * policy(*) is without policy requests.
3313 *
3314 * 0 : succeed
3315 * others: error number
3316 */
3317int
3318key_spdacquire(
3319 struct secpolicy *sp)
3320{
3321 struct mbuf *result = NULL, *m;
3322 struct secspacq *newspacq;
3323 int error;
3324
3325 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3326
3327 /* sanity check */
3328 if (sp == NULL) {
3329 panic("key_spdacquire: NULL pointer is passed.");
3330 }
3331 if (sp->req != NULL) {
3332 panic("key_spdacquire: called but there is request.");
3333 }
3334 if (sp->policy != IPSEC_POLICY_IPSEC) {
3335 panic("key_spdacquire: policy mismathed. IPsec is expected.");
3336 }
3337
3338 /* get a entry to check whether sent message or not. */
3339 lck_mtx_lock(sadb_mutex);
3340 sp->refcnt++;
3341 if ((newspacq = key_getspacq(&sp->spidx)) != NULL) {
3342 key_freesp(sp, KEY_SADB_LOCKED);
3343 if (key_blockacq_count < newspacq->count) {
3344 /* reset counter and do send message. */
3345 newspacq->count = 0;
3346 } else {
3347 /* increment counter and do nothing. */
3348 newspacq->count++;
3349 lck_mtx_unlock(sadb_mutex);
3350 return 0;
3351 }
3352 } else {
3353 /* make new entry for blocking to send SADB_ACQUIRE. */
3354 if ((newspacq = key_newspacq(&sp->spidx)) == NULL) {
3355 key_freesp(sp, KEY_SADB_LOCKED);
3356 lck_mtx_unlock(sadb_mutex);
3357 return ENOBUFS;
3358 }
3359 key_freesp(sp, KEY_SADB_LOCKED);
3360 /* add to acqtree */
3361 LIST_INSERT_HEAD(&spacqtree, newspacq, chain);
3362 key_start_timehandler();
3363 }
3364 lck_mtx_unlock(sadb_mutex);
3365 /* create new sadb_msg to reply. */
3366 m = key_setsadbmsg(SADB_X_SPDACQUIRE, 0, 0, 0, 0, 0);
3367 if (!m) {
3368 error = ENOBUFS;
3369 goto fail;
3370 }
3371 result = m;
3372
3373 result->m_pkthdr.len = 0;
3374 for (m = result; m; m = m->m_next) {
3375 result->m_pkthdr.len += m->m_len;
3376 }
3377
3378 VERIFY(PFKEY_UNIT64(result->m_pkthdr.len) <= UINT16_MAX);
3379 mtod(result, struct sadb_msg *)->sadb_msg_len =
3380 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
3381
3382 return key_sendup_mbuf(NULL, m, KEY_SENDUP_REGISTERED);
3383
3384fail:
3385 if (result) {
3386 m_freem(result);
3387 }
3388 return error;
3389}
3390
3391/*
3392 * SADB_SPDFLUSH processing
3393 * receive
3394 * <base>
3395 * from the user, and free all entries in secpctree.
3396 * and send,
3397 * <base>
3398 * to the user.
3399 * NOTE: what to do is only marking SADB_SASTATE_DEAD.
3400 *
3401 * m will always be freed.
3402 */
3403static int
3404key_spdflush(
3405 struct socket *so,
3406 struct mbuf *m,
3407 const struct sadb_msghdr *mhp)
3408{
3409 struct sadb_msg *newmsg;
3410 struct secpolicy *sp;
3411 u_int dir;
3412
3413 /* sanity check */
3414 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
3415 panic("key_spdflush: NULL pointer is passed.");
3416 }
3417
3418 if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg))) {
3419 return key_senderror(so, m, EINVAL);
3420 }
3421
3422 lck_mtx_lock(sadb_mutex);
3423 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
3424 LIST_FOREACH(sp, &sptree[dir], chain) {
3425 sp->state = IPSEC_SPSTATE_DEAD;
3426 }
3427 }
3428 lck_mtx_unlock(sadb_mutex);
3429
3430 if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
3431 ipseclog((LOG_DEBUG, "key_spdflush: No more memory.\n"));
3432 return key_senderror(so, m, ENOBUFS);
3433 }
3434
3435 if (m->m_next) {
3436 m_freem(m->m_next);
3437 }
3438 m->m_next = NULL;
3439 m->m_pkthdr.len = m->m_len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
3440 newmsg = mtod(m, struct sadb_msg *);
3441 newmsg->sadb_msg_errno = 0;
3442 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(m->m_pkthdr.len);
3443
3444 return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
3445}
3446
3447/*
3448 * SADB_SPDDUMP processing
3449 * receive
3450 * <base>
3451 * from the user, and dump all SP leaves
3452 * and send,
3453 * <base> .....
3454 * to the ikmpd.
3455 *
3456 * m will always be freed.
3457 */
3458
3459static int
3460key_spddump(
3461 struct socket *so,
3462 struct mbuf *m,
3463 const struct sadb_msghdr *mhp)
3464{
3465 struct secpolicy *sp, **spbuf = NULL, **sp_ptr;
3466 u_int32_t cnt = 0, bufcount = 0;
3467 u_int dir;
3468 struct mbuf *n;
3469 int error = 0;
3470
3471 /* sanity check */
3472 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
3473 panic("key_spddump: NULL pointer is passed.");
3474 }
3475
3476 if ((bufcount = ipsec_policy_count) == 0) {
3477 error = ENOENT;
3478 goto end;
3479 }
3480
3481 if (os_add_overflow(bufcount, 256, &bufcount)) {
3482 ipseclog((LOG_DEBUG, "key_spddump: bufcount overflow, ipsec policy count %u.\n", ipsec_policy_count));
3483 bufcount = ipsec_policy_count;
3484 }
3485
3486 spbuf = kalloc_type(struct secpolicy *, bufcount, Z_WAITOK);
3487 if (spbuf == NULL) {
3488 ipseclog((LOG_DEBUG, "key_spddump: No more memory.\n"));
3489 error = ENOMEM;
3490 goto end;
3491 }
3492 lck_mtx_lock(sadb_mutex);
3493 /* search SPD entry, make list. */
3494 sp_ptr = spbuf;
3495 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
3496 LIST_FOREACH(sp, &sptree[dir], chain) {
3497 if (cnt == bufcount) {
3498 break; /* buffer full */
3499 }
3500 *sp_ptr++ = sp;
3501 sp->refcnt++;
3502 cnt++;
3503 }
3504 }
3505 lck_mtx_unlock(sadb_mutex);
3506
3507 if (cnt == 0) {
3508 error = ENOENT;
3509 goto end;
3510 }
3511
3512 sp_ptr = spbuf;
3513 while (cnt) {
3514 --cnt;
3515 n = key_setdumpsp(*sp_ptr++, SADB_X_SPDDUMP, cnt,
3516 mhp->msg->sadb_msg_pid);
3517
3518 if (n) {
3519 key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
3520 }
3521 }
3522
3523 lck_mtx_lock(sadb_mutex);
3524 while (sp_ptr > spbuf) {
3525 key_freesp(sp: *(--sp_ptr), KEY_SADB_LOCKED);
3526 }
3527 lck_mtx_unlock(sadb_mutex);
3528
3529end:
3530 kfree_type(struct secpolicy *, bufcount, spbuf);
3531 if (error) {
3532 return key_senderror(so, m, error);
3533 }
3534
3535 m_freem(m);
3536 return 0;
3537}
3538
3539static struct mbuf *
3540key_setdumpsp(
3541 struct secpolicy *sp,
3542 u_int8_t msg_type,
3543 u_int32_t seq,
3544 u_int32_t pid)
3545{
3546 struct mbuf *result = NULL, *m;
3547
3548 m = key_setsadbmsg(msg_type, 0, SADB_SATYPE_UNSPEC, seq, pid, (u_int16_t)sp->refcnt);
3549 if (!m) {
3550 goto fail;
3551 }
3552 result = m;
3553
3554 if (sp->spidx.src_range.start.ss_len > 0) {
3555 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_START,
3556 (struct sockaddr *)&sp->spidx.src_range.start, sp->spidx.prefs,
3557 sp->spidx.ul_proto);
3558 if (!m) {
3559 goto fail;
3560 }
3561 m_cat(result, m);
3562
3563 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_END,
3564 (struct sockaddr *)&sp->spidx.src_range.end, sp->spidx.prefs,
3565 sp->spidx.ul_proto);
3566 if (!m) {
3567 goto fail;
3568 }
3569 m_cat(result, m);
3570 } else {
3571 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
3572 (struct sockaddr *)&sp->spidx.src, sp->spidx.prefs,
3573 sp->spidx.ul_proto);
3574 if (!m) {
3575 goto fail;
3576 }
3577 m_cat(result, m);
3578 }
3579
3580 if (sp->spidx.dst_range.start.ss_len > 0) {
3581 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_START,
3582 (struct sockaddr *)&sp->spidx.dst_range.start, sp->spidx.prefd,
3583 sp->spidx.ul_proto);
3584 if (!m) {
3585 goto fail;
3586 }
3587 m_cat(result, m);
3588
3589 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_END,
3590 (struct sockaddr *)&sp->spidx.dst_range.end, sp->spidx.prefd,
3591 sp->spidx.ul_proto);
3592 if (!m) {
3593 goto fail;
3594 }
3595 m_cat(result, m);
3596 } else {
3597 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
3598 (struct sockaddr *)&sp->spidx.dst, sp->spidx.prefd,
3599 sp->spidx.ul_proto);
3600 if (!m) {
3601 goto fail;
3602 }
3603 m_cat(result, m);
3604 }
3605
3606 if (sp->spidx.internal_if || sp->outgoing_if || sp->ipsec_if || sp->disabled) {
3607 m = key_setsadbipsecif(sp->spidx.internal_if, sp->outgoing_if, sp->ipsec_if, sp->disabled);
3608 if (!m) {
3609 goto fail;
3610 }
3611 m_cat(result, m);
3612 }
3613
3614 m = key_sp2msg(sp);
3615 if (!m) {
3616 goto fail;
3617 }
3618 m_cat(result, m);
3619
3620 if ((result->m_flags & M_PKTHDR) == 0) {
3621 goto fail;
3622 }
3623
3624 if (result->m_len < sizeof(struct sadb_msg)) {
3625 result = m_pullup(result, sizeof(struct sadb_msg));
3626 if (result == NULL) {
3627 goto fail;
3628 }
3629 }
3630
3631 result->m_pkthdr.len = 0;
3632 for (m = result; m; m = m->m_next) {
3633 result->m_pkthdr.len += m->m_len;
3634 }
3635
3636 if (PFKEY_UNIT64(result->m_pkthdr.len) >= UINT16_MAX) {
3637 ipseclog((LOG_DEBUG, "key_setdumpsp: packet header length > UINT16_MAX\n"));
3638 goto fail;
3639 }
3640
3641 mtod(result, struct sadb_msg *)->sadb_msg_len =
3642 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
3643
3644 return result;
3645
3646fail:
3647 m_freem(result);
3648 return NULL;
3649}
3650
3651/*
3652 * get PFKEY message length for security policy and request.
3653 */
3654static u_int
3655key_getspreqmsglen(
3656 struct secpolicy *sp)
3657{
3658 u_int tlen;
3659
3660 tlen = sizeof(struct sadb_x_policy);
3661
3662 /* if is the policy for ipsec ? */
3663 if (sp->policy != IPSEC_POLICY_IPSEC) {
3664 return tlen;
3665 }
3666
3667 /* get length of ipsec requests */
3668 {
3669 struct ipsecrequest *isr;
3670 int len;
3671
3672 for (isr = sp->req; isr != NULL; isr = isr->next) {
3673 len = sizeof(struct sadb_x_ipsecrequest)
3674 + isr->saidx.src.ss_len
3675 + isr->saidx.dst.ss_len;
3676
3677 tlen += PFKEY_ALIGN8(len);
3678 }
3679 }
3680
3681 return tlen;
3682}
3683
3684/*
3685 * SADB_SPDEXPIRE processing
3686 * send
3687 * <base, address(SD), lifetime(CH), policy>
3688 * to KMD by PF_KEY.
3689 *
3690 * OUT: 0 : succeed
3691 * others : error number
3692 */
3693static int
3694key_spdexpire(
3695 struct secpolicy *sp)
3696{
3697 struct mbuf *result = NULL, *m;
3698 int len;
3699 int error = EINVAL;
3700 struct sadb_lifetime *lt;
3701
3702 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3703
3704 /* sanity check */
3705 if (sp == NULL) {
3706 panic("key_spdexpire: NULL pointer is passed.");
3707 }
3708
3709 /* set msg header */
3710 m = key_setsadbmsg(SADB_X_SPDEXPIRE, 0, 0, 0, 0, 0);
3711 if (!m) {
3712 error = ENOBUFS;
3713 goto fail;
3714 }
3715 result = m;
3716
3717 /* create lifetime extension (current and hard) */
3718 len = PFKEY_ALIGN8(sizeof(*lt)) * 2;
3719 m = key_alloc_mbuf(len);
3720 if (!m || m->m_next) { /*XXX*/
3721 if (m) {
3722 m_freem(m);
3723 }
3724 error = ENOBUFS;
3725 goto fail;
3726 }
3727 bzero(mtod(m, caddr_t), n: len);
3728 lt = mtod(m, struct sadb_lifetime *);
3729 lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
3730 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
3731 lt->sadb_lifetime_allocations = 0;
3732 lt->sadb_lifetime_bytes = 0;
3733 lt->sadb_lifetime_addtime = key_convert_continuous_time_ns(time_value: sp->created);
3734 lt->sadb_lifetime_usetime = key_convert_continuous_time_ns(time_value: sp->lastused);
3735 lt = (struct sadb_lifetime *)(void *)(mtod(m, caddr_t) + len / 2);
3736 lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
3737 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
3738 lt->sadb_lifetime_allocations = 0;
3739 lt->sadb_lifetime_bytes = 0;
3740 lt->sadb_lifetime_addtime = sp->lifetime / NSEC_PER_SEC;
3741 lt->sadb_lifetime_usetime = sp->validtime / NSEC_PER_SEC;
3742 m_cat(result, m);
3743
3744 /* set sadb_address(es) for source */
3745 if (sp->spidx.src_range.start.ss_len > 0) {
3746 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_START,
3747 (struct sockaddr *)&sp->spidx.src_range.start, sp->spidx.prefs,
3748 sp->spidx.ul_proto);
3749 if (!m) {
3750 error = ENOBUFS;
3751 goto fail;
3752 }
3753 m_cat(result, m);
3754
3755 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_END,
3756 (struct sockaddr *)&sp->spidx.src_range.end, sp->spidx.prefs,
3757 sp->spidx.ul_proto);
3758 if (!m) {
3759 error = ENOBUFS;
3760 goto fail;
3761 }
3762 m_cat(result, m);
3763 } else {
3764 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
3765 (struct sockaddr *)&sp->spidx.src, sp->spidx.prefs,
3766 sp->spidx.ul_proto);
3767 if (!m) {
3768 error = ENOBUFS;
3769 goto fail;
3770 }
3771 m_cat(result, m);
3772 }
3773
3774 /* set sadb_address(es) for dest */
3775 if (sp->spidx.dst_range.start.ss_len > 0) {
3776 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_START,
3777 (struct sockaddr *)&sp->spidx.dst_range.start, sp->spidx.prefd,
3778 sp->spidx.ul_proto);
3779 if (!m) {
3780 error = ENOBUFS;
3781 goto fail;
3782 }
3783 m_cat(result, m);
3784
3785 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_END,
3786 (struct sockaddr *)&sp->spidx.dst_range.end, sp->spidx.prefd,
3787 sp->spidx.ul_proto);
3788 if (!m) {
3789 error = ENOBUFS;
3790 goto fail;
3791 }
3792 m_cat(result, m);
3793 } else {
3794 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
3795 (struct sockaddr *)&sp->spidx.dst, sp->spidx.prefd,
3796 sp->spidx.ul_proto);
3797 if (!m) {
3798 error = ENOBUFS;
3799 goto fail;
3800 }
3801 m_cat(result, m);
3802 }
3803
3804 /* set secpolicy */
3805 m = key_sp2msg(sp);
3806 if (!m) {
3807 error = ENOBUFS;
3808 goto fail;
3809 }
3810 m_cat(result, m);
3811
3812 if ((result->m_flags & M_PKTHDR) == 0) {
3813 error = EINVAL;
3814 goto fail;
3815 }
3816
3817 if (result->m_len < sizeof(struct sadb_msg)) {
3818 result = m_pullup(result, sizeof(struct sadb_msg));
3819 if (result == NULL) {
3820 error = ENOBUFS;
3821 goto fail;
3822 }
3823 }
3824
3825 result->m_pkthdr.len = 0;
3826 for (m = result; m; m = m->m_next) {
3827 result->m_pkthdr.len += m->m_len;
3828 }
3829
3830 if (PFKEY_UNIT64(result->m_pkthdr.len) >= UINT16_MAX) {
3831 ipseclog((LOG_DEBUG, "key_setdumpsp: packet header length > UINT16_MAX\n"));
3832 goto fail;
3833 }
3834
3835 mtod(result, struct sadb_msg *)->sadb_msg_len =
3836 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
3837
3838 return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
3839
3840fail:
3841 if (result) {
3842 m_freem(result);
3843 }
3844 return error;
3845}
3846
3847/* %%% SAD management */
3848/*
3849 * allocating a memory for new SA head, and copy from the values of mhp.
3850 * OUT: NULL : failure due to the lack of memory.
3851 * others : pointer to new SA head.
3852 */
3853static struct secashead *
3854key_newsah(struct secasindex *saidx,
3855 ifnet_t ipsec_if,
3856 u_int outgoing_if,
3857 u_int8_t dir,
3858 u_int16_t flags)
3859{
3860 struct secashead *newsah;
3861
3862 /* sanity check */
3863 if (saidx == NULL) {
3864 panic("key_newsaidx: NULL pointer is passed.");
3865 }
3866
3867 VERIFY(flags == SECURITY_ASSOCIATION_PFKEY || flags == SECURITY_ASSOCIATION_CUSTOM_IPSEC);
3868
3869 newsah = keydb_newsecashead();
3870 if (newsah == NULL) {
3871 return NULL;
3872 }
3873
3874 bcopy(src: saidx, dst: &newsah->saidx, n: sizeof(newsah->saidx));
3875
3876 /* remove the ports */
3877 switch (saidx->src.ss_family) {
3878 case AF_INET:
3879 ((struct sockaddr_in *)(&newsah->saidx.src))->sin_port = IPSEC_PORT_ANY;
3880 break;
3881 case AF_INET6:
3882 ((struct sockaddr_in6 *)(&newsah->saidx.src))->sin6_port = IPSEC_PORT_ANY;
3883 break;
3884 default:
3885 break;
3886 }
3887 switch (saidx->dst.ss_family) {
3888 case AF_INET:
3889 ((struct sockaddr_in *)(&newsah->saidx.dst))->sin_port = IPSEC_PORT_ANY;
3890 break;
3891 case AF_INET6:
3892 ((struct sockaddr_in6 *)(&newsah->saidx.dst))->sin6_port = IPSEC_PORT_ANY;
3893 break;
3894 default:
3895 break;
3896 }
3897
3898 newsah->outgoing_if = outgoing_if;
3899 if (ipsec_if) {
3900 ifnet_reference(interface: ipsec_if);
3901 newsah->ipsec_if = ipsec_if;
3902 }
3903 newsah->dir = dir;
3904 /* add to saidxtree */
3905 newsah->state = SADB_SASTATE_MATURE;
3906 newsah->flags = flags;
3907
3908 if (flags == SECURITY_ASSOCIATION_PFKEY) {
3909 LIST_INSERT_HEAD(&sahtree, newsah, chain);
3910 } else {
3911 LIST_INSERT_HEAD(&custom_sahtree, newsah, chain);
3912 }
3913 key_start_timehandler();
3914
3915 return newsah;
3916}
3917
3918/*
3919 * delete SA index and all SA registered.
3920 */
3921void
3922key_delsah(
3923 struct secashead *sah)
3924{
3925 struct secasvar *sav, *nextsav;
3926 u_int stateidx, state;
3927 int zombie = 0;
3928
3929 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
3930
3931 /* sanity check */
3932 if (sah == NULL) {
3933 panic("key_delsah: NULL pointer is passed.");
3934 }
3935
3936 if (sah->use_count > 0) {
3937 return;
3938 }
3939
3940 /* searching all SA registered in the secindex. */
3941 for (stateidx = 0;
3942 stateidx < _ARRAYLEN(saorder_state_any);
3943 stateidx++) {
3944 state = saorder_state_any[stateidx];
3945 for (sav = (struct secasvar *)LIST_FIRST(&sah->savtree[state]);
3946 sav != NULL;
3947 sav = nextsav) {
3948 nextsav = LIST_NEXT(sav, chain);
3949
3950 if (sav->refcnt > 0) {
3951 /* give up to delete this sa */
3952 zombie++;
3953 continue;
3954 }
3955
3956 /* sanity check */
3957 KEY_CHKSASTATE(state, sav->state, "key_delsah");
3958
3959 key_freesav(sav, KEY_SADB_LOCKED);
3960
3961 /* remove back pointer */
3962 sav->sah = NULL;
3963 sav = NULL;
3964 }
3965 }
3966
3967 /* don't delete sah only if there are savs. */
3968 if (zombie) {
3969 return;
3970 }
3971
3972 ROUTE_RELEASE(&sah->sa_route);
3973
3974 if (sah->ipsec_if) {
3975 ifnet_release(interface: sah->ipsec_if);
3976 sah->ipsec_if = NULL;
3977 }
3978
3979 /* remove from tree of SA index */
3980 if (__LIST_CHAINED(sah)) {
3981 LIST_REMOVE(sah, chain);
3982 }
3983
3984 kfree_type(struct secashead, sah);
3985}
3986
3987/*
3988 * allocating a new SA with LARVAL state. key_add() and key_getspi() call,
3989 * and copy the values of mhp into new buffer.
3990 * When SAD message type is GETSPI:
3991 * to set sequence number from acq_seq++,
3992 * to set zero to SPI.
3993 * not to call key_setsava().
3994 * OUT: NULL : fail
3995 * others : pointer to new secasvar.
3996 *
3997 * does not modify mbuf. does not free mbuf on error.
3998 */
3999static struct secasvar *
4000key_newsav(
4001 struct mbuf *m,
4002 const struct sadb_msghdr *mhp,
4003 struct secashead *sah,
4004 int *errp,
4005 struct socket *so)
4006{
4007 struct secasvar *newsav;
4008 const struct sadb_sa *xsa;
4009
4010 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4011
4012 /* sanity check */
4013 if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL) {
4014 panic("key_newsa: NULL pointer is passed.");
4015 }
4016
4017 newsav = kalloc_type(struct secasvar, Z_NOWAIT_ZERO);
4018 if (newsav == NULL) {
4019 lck_mtx_unlock(sadb_mutex);
4020 newsav = kalloc_type(struct secasvar, Z_WAITOK_ZERO_NOFAIL);
4021 lck_mtx_lock(sadb_mutex);
4022 }
4023
4024 switch (mhp->msg->sadb_msg_type) {
4025 case SADB_GETSPI:
4026 key_setspi(newsav, 0);
4027 newsav->seq = mhp->msg->sadb_msg_seq;
4028 break;
4029
4030 case SADB_ADD:
4031 /* sanity check */
4032 if (mhp->ext[SADB_EXT_SA] == NULL) {
4033 key_delsav(sav: newsav);
4034 ipseclog((LOG_DEBUG, "key_newsa: invalid message is passed.\n"));
4035 *errp = EINVAL;
4036 return NULL;
4037 }
4038 xsa = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
4039 key_setspi(newsav, xsa->sadb_sa_spi);
4040 newsav->seq = mhp->msg->sadb_msg_seq;
4041 break;
4042 default:
4043 key_delsav(sav: newsav);
4044 *errp = EINVAL;
4045 return NULL;
4046 }
4047
4048 if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
4049 if (((struct sadb_x_sa2 *)(void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_alwaysexpire) {
4050 newsav->always_expire = 1;
4051 }
4052 newsav->flags2 = ((struct sadb_x_sa2 *)(void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_flags;
4053 if (newsav->flags2 & SADB_X_EXT_SA2_DELETE_ON_DETACH) {
4054 newsav->so = so;
4055 }
4056 }
4057
4058 // Get current continuous time
4059 const u_int64_t current_time_ns = key_get_continuous_time_ns();
4060
4061 /* copy sav values */
4062 if (mhp->msg->sadb_msg_type != SADB_GETSPI) {
4063 *errp = key_setsaval(newsav, m, mhp);
4064 if (*errp) {
4065 key_delsav(sav: newsav);
4066 return NULL;
4067 }
4068 } else {
4069 /* For get SPI, if has a hard lifetime, apply */
4070 const struct sadb_lifetime *lft0;
4071
4072 lft0 = (struct sadb_lifetime *)(void *)mhp->ext[SADB_EXT_LIFETIME_HARD];
4073 if (lft0 != NULL) {
4074 /* make lifetime for CURRENT */
4075 newsav->lft_c = kalloc_type(struct sadb_lifetime, Z_NOWAIT);
4076 if (newsav->lft_c == NULL) {
4077 lck_mtx_unlock(sadb_mutex);
4078 newsav->lft_c = kalloc_type(struct sadb_lifetime,
4079 Z_WAITOK | Z_NOFAIL);
4080 lck_mtx_lock(sadb_mutex);
4081 }
4082
4083 newsav->lft_c->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
4084 newsav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
4085 newsav->lft_c->sadb_lifetime_allocations = 0;
4086 newsav->lft_c->sadb_lifetime_bytes = 0;
4087 newsav->lft_c->sadb_lifetime_addtime = current_time_ns;
4088 newsav->lft_c->sadb_lifetime_usetime = 0;
4089
4090 if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(*lft0)) {
4091 ipseclog((LOG_DEBUG, "key_newsa: invalid hard lifetime ext len.\n"));
4092 key_delsav(sav: newsav);
4093 *errp = EINVAL;
4094 return NULL;
4095 }
4096 newsav->lft_h = key_newbuf(lft0, sizeof(*lft0));
4097 }
4098 }
4099
4100 /* reset created */
4101 newsav->created = current_time_ns;
4102
4103 newsav->pid = mhp->msg->sadb_msg_pid;
4104
4105 /* add to satree */
4106 newsav->sah = sah;
4107 newsav->refcnt = 1;
4108 newsav->state = SADB_SASTATE_LARVAL;
4109 LIST_INSERT_TAIL(&sah->savtree[SADB_SASTATE_LARVAL], newsav,
4110 secasvar, chain);
4111 ipsec_sav_count++;
4112 ipsec_monitor_sleep_wake();
4113
4114 return newsav;
4115}
4116
4117static int
4118key_migratesav(struct secasvar *sav,
4119 struct secashead *newsah)
4120{
4121 if (sav == NULL || newsah == NULL || sav->state != SADB_SASTATE_MATURE) {
4122 return EINVAL;
4123 }
4124
4125 /* remove from SA header */
4126 if (__LIST_CHAINED(sav)) {
4127 LIST_REMOVE(sav, chain);
4128 }
4129
4130 sav->sah = newsah;
4131 LIST_INSERT_TAIL(&newsah->savtree[SADB_SASTATE_MATURE], sav, secasvar, chain);
4132 return 0;
4133}
4134
4135static void
4136key_reset_sav(struct secasvar *sav)
4137{
4138 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4139
4140 /* sanity check */
4141 if (sav == NULL) {
4142 panic("key_delsav: NULL pointer is passed.");
4143 }
4144
4145 sav->remote_ike_port = 0;
4146 sav->natt_encapsulated_src_port = 0;
4147
4148 if (sav->key_auth != NULL) {
4149 bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
4150 kfree_data(sav->key_auth, PFKEY_UNUNIT64(sav->key_auth->sadb_key_len));
4151 sav->key_auth = NULL;
4152 }
4153 if (sav->key_enc != NULL) {
4154 bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
4155 kfree_data(sav->key_enc, PFKEY_UNUNIT64(sav->key_enc->sadb_key_len));
4156 sav->key_enc = NULL;
4157 }
4158 if (sav->sched_auth) {
4159 bzero(s: sav->sched_auth, n: sav->schedlen_auth);
4160 kfree_data(sav->sched_auth, sav->schedlen_auth);
4161 sav->sched_auth = NULL;
4162 sav->schedlen_auth = 0;
4163 }
4164 if (sav->sched_enc) {
4165 bzero(s: sav->sched_enc, n: sav->schedlen_enc);
4166 kfree_data(sav->sched_enc, sav->schedlen_enc);
4167 sav->sched_enc = NULL;
4168 sav->schedlen_enc = 0;
4169 }
4170
4171 for (int i = 0; i < MAX_REPLAY_WINDOWS; i++) {
4172 if (sav->replay[i] != NULL) {
4173 keydb_delsecreplay(sav->replay[i]);
4174 sav->replay[i] = NULL;
4175 }
4176 }
4177 if (sav->lft_c != NULL) {
4178 kfree_type(struct sadb_lifetime, sav->lft_c);
4179 sav->lft_c = NULL;
4180 }
4181 if (sav->lft_h != NULL) {
4182 kfree_data(sav->lft_h, sizeof(*sav->lft_h));
4183 sav->lft_h = NULL;
4184 }
4185 if (sav->lft_s != NULL) {
4186 kfree_data(sav->lft_s, sizeof(*sav->lft_h));
4187 sav->lft_s = NULL;
4188 }
4189 if (sav->iv != NULL) {
4190 kfree_data(sav->iv, sav->ivlen);
4191 sav->iv = NULL;
4192 }
4193 key_release_flowid(sav);
4194 return;
4195}
4196
4197/*
4198 * free() SA variable entry.
4199 */
4200void
4201key_delsav(
4202 struct secasvar *sav)
4203{
4204 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4205
4206 /* sanity check */
4207 if (sav == NULL) {
4208 panic("key_delsav: NULL pointer is passed.");
4209 }
4210
4211 if (sav->refcnt > 0) {
4212 return; /* can't free */
4213 }
4214 /* remove from SA header */
4215 if (__LIST_CHAINED(sav)) {
4216 LIST_REMOVE(sav, chain);
4217 ipsec_sav_count--;
4218 }
4219
4220 if (sav->spihash.le_prev || sav->spihash.le_next) {
4221 LIST_REMOVE(sav, spihash);
4222 }
4223
4224 key_reset_sav(sav);
4225
4226 kfree_type(struct secasvar, sav);
4227}
4228
4229/*
4230 * search SAD.
4231 * OUT:
4232 * NULL : not found
4233 * others : found, pointer to a SA.
4234 */
4235static struct secashead *
4236key_getsah(struct secasindex *saidx, u_int16_t flags)
4237{
4238 struct secashead *sah;
4239
4240 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4241
4242 if ((flags & SECURITY_ASSOCIATION_ANY) == SECURITY_ASSOCIATION_ANY ||
4243 (flags & SECURITY_ASSOCIATION_PFKEY) == SECURITY_ASSOCIATION_PFKEY) {
4244 LIST_FOREACH(sah, &sahtree, chain) {
4245 if (sah->state == SADB_SASTATE_DEAD) {
4246 continue;
4247 }
4248 if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID)) {
4249 return sah;
4250 }
4251 }
4252 }
4253
4254 if ((flags & SECURITY_ASSOCIATION_ANY) == SECURITY_ASSOCIATION_ANY ||
4255 (flags & SECURITY_ASSOCIATION_PFKEY) == SECURITY_ASSOCIATION_CUSTOM_IPSEC) {
4256 LIST_FOREACH(sah, &custom_sahtree, chain) {
4257 if (sah->state == SADB_SASTATE_DEAD) {
4258 continue;
4259 }
4260 if (key_cmpsaidx(&sah->saidx, saidx, 0)) {
4261 return sah;
4262 }
4263 }
4264 }
4265
4266 return NULL;
4267}
4268
4269struct secashead *
4270key_newsah2(struct secasindex *saidx,
4271 u_int8_t dir)
4272{
4273 struct secashead *sah;
4274
4275 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4276
4277 sah = key_getsah(saidx, SECURITY_ASSOCIATION_ANY);
4278 if (!sah) {
4279 return key_newsah(saidx, NULL, outgoing_if: 0, dir, SECURITY_ASSOCIATION_PFKEY);
4280 }
4281 return sah;
4282}
4283
4284/*
4285 * check not to be duplicated SPI.
4286 * NOTE: this function is too slow due to searching all SAD.
4287 * OUT:
4288 * NULL : not found
4289 * others : found, pointer to a SA.
4290 */
4291static struct secasvar *
4292key_checkspidup(
4293 struct secasindex *saidx,
4294 u_int32_t spi)
4295{
4296 struct secasvar *sav;
4297 u_int stateidx, state;
4298
4299 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4300
4301 /* check address family */
4302 if (saidx->src.ss_family != saidx->dst.ss_family) {
4303 ipseclog((LOG_DEBUG, "key_checkspidup: address family mismatched.\n"));
4304 return NULL;
4305 }
4306
4307 /* check all SAD */
4308 LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
4309 if (sav->spi != spi) {
4310 continue;
4311 }
4312 for (stateidx = 0;
4313 stateidx < _ARRAYLEN(saorder_state_alive);
4314 stateidx++) {
4315 state = saorder_state_alive[stateidx];
4316 if (sav->state == state &&
4317 key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
4318 return sav;
4319 }
4320 }
4321 }
4322
4323 return NULL;
4324}
4325
4326static void
4327key_setspi(
4328 struct secasvar *sav,
4329 u_int32_t spi)
4330{
4331 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4332 sav->spi = spi;
4333 if (sav->spihash.le_prev || sav->spihash.le_next) {
4334 LIST_REMOVE(sav, spihash);
4335 }
4336 LIST_INSERT_HEAD(&spihash[SPIHASH(spi)], sav, spihash);
4337}
4338
4339
4340/*
4341 * search SAD litmited alive SA, protocol, SPI.
4342 * OUT:
4343 * NULL : not found
4344 * others : found, pointer to a SA.
4345 */
4346static struct secasvar *
4347key_getsavbyspi(
4348 struct secashead *sah,
4349 u_int32_t spi)
4350{
4351 struct secasvar *sav, *match;
4352 u_int stateidx, state, matchidx;
4353
4354 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4355 match = NULL;
4356 matchidx = _ARRAYLEN(saorder_state_alive);
4357 LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
4358 if (sav->spi != spi) {
4359 continue;
4360 }
4361 if (sav->sah != sah) {
4362 continue;
4363 }
4364 for (stateidx = 0; stateidx < matchidx; stateidx++) {
4365 state = saorder_state_alive[stateidx];
4366 if (sav->state == state) {
4367 match = sav;
4368 matchidx = stateidx;
4369 break;
4370 }
4371 }
4372 }
4373
4374 return match;
4375}
4376
4377/*
4378 * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*.
4379 * You must update these if need.
4380 * OUT: 0: success.
4381 * !0: failure.
4382 *
4383 * does not modify mbuf. does not free mbuf on error.
4384 */
4385static int
4386key_setsaval(
4387 struct secasvar *sav,
4388 struct mbuf *m,
4389 const struct sadb_msghdr *mhp)
4390{
4391#if IPSEC_ESP
4392 const struct esp_algorithm *algo;
4393#endif
4394 int error = 0;
4395
4396 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4397
4398 /* sanity check */
4399 if (m == NULL || mhp == NULL || mhp->msg == NULL) {
4400 panic("key_setsaval: NULL pointer is passed.");
4401 }
4402
4403 /* initialization */
4404 key_reset_sav(sav);
4405 sav->natt_last_activity = natt_now;
4406
4407 /* SA */
4408 if (mhp->ext[SADB_EXT_SA] != NULL) {
4409 const struct sadb_sa *sa0;
4410
4411 sa0 = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
4412 if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) {
4413 ipseclog((LOG_DEBUG, "key_setsaval: invalid message size.\n"));
4414 error = EINVAL;
4415 goto fail;
4416 }
4417
4418 sav->alg_auth = sa0->sadb_sa_auth;
4419 sav->alg_enc = sa0->sadb_sa_encrypt;
4420 sav->flags = sa0->sadb_sa_flags;
4421
4422 /*
4423 * Verify that a nat-traversal port was specified if
4424 * the nat-traversal flag is set.
4425 */
4426 if ((sav->flags & SADB_X_EXT_NATT) != 0) {
4427 if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa_2) ||
4428 ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_port == 0) {
4429 ipseclog((LOG_DEBUG, "key_setsaval: natt port not set.\n"));
4430 error = EINVAL;
4431 goto fail;
4432 }
4433 sav->natt_encapsulated_src_port = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_src_port;
4434 sav->remote_ike_port = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_port;
4435 sav->natt_interval = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_interval;
4436 sav->natt_offload_interval = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_offload_interval;
4437 }
4438
4439 /*
4440 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
4441 * SADB_X_EXT_NATT is set and SADB_X_EXT_NATT_KEEPALIVE is not
4442 * set (we're not behind nat) - otherwise clear it.
4443 */
4444 if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0) {
4445 if ((sav->flags & SADB_X_EXT_NATT) == 0 ||
4446 (sav->flags & SADB_X_EXT_NATT_KEEPALIVE) != 0) {
4447 sav->flags &= ~SADB_X_EXT_NATT_MULTIPLEUSERS;
4448 }
4449 }
4450
4451 /* replay window */
4452 if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) {
4453 if ((sav->flags2 & SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) ==
4454 SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) {
4455 const uint32_t range = PER_TC_REPLAY_WINDOW_RANGE;
4456 for (uint32_t i = 0; i < MAX_REPLAY_WINDOWS; i++) {
4457 sav->replay[i] = keydb_newsecreplay(sa0->sadb_sa_replay);
4458 /* Allowed range for sequence per traffic class */
4459 const uint32_t seq = i << PER_TC_REPLAY_WINDOW_SN_SHIFT;
4460 sav->replay[i]->seq = seq;
4461 sav->replay[i]->lastseq = seq + range - 1;
4462 }
4463 } else {
4464 sav->replay[0] = keydb_newsecreplay(sa0->sadb_sa_replay);
4465 sav->replay[0]->lastseq = ~0;
4466 }
4467 }
4468 }
4469
4470 /* Authentication keys */
4471 if (mhp->ext[SADB_EXT_KEY_AUTH] != NULL) {
4472 const struct sadb_key *key0;
4473 int len;
4474
4475 key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH];
4476 len = mhp->extlen[SADB_EXT_KEY_AUTH];
4477
4478 const size_t max_length = PFKEY_ALIGN8(sizeof(*key0)) +
4479 PFKEY_ALIGN8(IPSEC_KEY_AUTH_MAX_BYTES);
4480 assert(max_length < KALLOC_SAFE_ALLOC_SIZE);
4481
4482 error = 0;
4483 if ((len < sizeof(*key0)) || (len > max_length)) {
4484 ipseclog((LOG_DEBUG, "key_setsaval: invalid auth key ext len. len = %d\n", len));
4485 error = EINVAL;
4486 goto fail;
4487 }
4488 switch (mhp->msg->sadb_msg_satype) {
4489 case SADB_SATYPE_AH:
4490 case SADB_SATYPE_ESP:
4491 if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
4492 sav->alg_auth != SADB_X_AALG_NULL) {
4493 error = EINVAL;
4494 }
4495 break;
4496 default:
4497 error = EINVAL;
4498 break;
4499 }
4500 if (error) {
4501 ipseclog((LOG_DEBUG, "key_setsaval: invalid key_auth values.\n"));
4502 goto fail;
4503 }
4504
4505 sav->key_auth = (struct sadb_key *)key_newbuf(key0, len);
4506 }
4507
4508 /* Encryption key */
4509 if (mhp->ext[SADB_EXT_KEY_ENCRYPT] != NULL) {
4510 const struct sadb_key *key0;
4511 int len;
4512
4513 key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_ENCRYPT];
4514 len = mhp->extlen[SADB_EXT_KEY_ENCRYPT];
4515
4516 const size_t max_length = PFKEY_ALIGN8(sizeof(*key0)) +
4517 PFKEY_ALIGN8(IPSEC_KEY_ENCRYPT_MAX_BYTES);
4518 assert(max_length < KALLOC_SAFE_ALLOC_SIZE);
4519
4520 error = 0;
4521 if ((len < sizeof(*key0)) || (len > max_length)) {
4522 ipseclog((LOG_DEBUG, "key_setsaval: invalid encryption key ext len. len = %d\n", len));
4523 error = EINVAL;
4524 goto fail;
4525 }
4526 switch (mhp->msg->sadb_msg_satype) {
4527 case SADB_SATYPE_ESP:
4528 if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
4529 sav->alg_enc != SADB_EALG_NULL) {
4530 ipseclog((LOG_DEBUG, "key_setsaval: invalid ESP algorithm.\n"));
4531 error = EINVAL;
4532 break;
4533 }
4534 sav->key_enc = (struct sadb_key *)key_newbuf(key0, len);
4535 break;
4536 case SADB_SATYPE_AH:
4537 default:
4538 error = EINVAL;
4539 break;
4540 }
4541 if (error) {
4542 ipseclog((LOG_DEBUG, "key_setsaval: invalid key_enc value.\n"));
4543 goto fail;
4544 }
4545 }
4546
4547 /* set iv */
4548 sav->ivlen = 0;
4549
4550 switch (mhp->msg->sadb_msg_satype) {
4551 case SADB_SATYPE_ESP:
4552#if IPSEC_ESP
4553 algo = esp_algorithm_lookup(sav->alg_enc);
4554 if (algo && algo->ivlen) {
4555 sav->ivlen = (*algo->ivlen)(algo, sav);
4556 }
4557 if (sav->ivlen == 0) {
4558 break;
4559 }
4560 sav->iv = (caddr_t) kalloc_data(sav->ivlen, Z_NOWAIT);
4561 if (sav->iv == 0) {
4562 lck_mtx_unlock(sadb_mutex);
4563 sav->iv = (caddr_t) kalloc_data(sav->ivlen, Z_WAITOK);
4564 lck_mtx_lock(sadb_mutex);
4565 if (sav->iv == 0) {
4566 ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
4567 error = ENOBUFS;
4568 goto fail;
4569 }
4570 }
4571
4572 /* initialize IV with random bytes */
4573 key_randomfill(sav->iv, sav->ivlen);
4574#endif
4575 break;
4576 case SADB_SATYPE_AH:
4577 break;
4578 default:
4579 ipseclog((LOG_DEBUG, "key_setsaval: invalid SA type.\n"));
4580 error = EINVAL;
4581 goto fail;
4582 }
4583
4584 /* reset created */
4585 const u_int64_t current_time_ns = key_get_continuous_time_ns();
4586 sav->created = current_time_ns;
4587
4588 /* make lifetime for CURRENT */
4589 sav->lft_c = kalloc_type(struct sadb_lifetime, Z_NOWAIT);
4590 if (sav->lft_c == NULL) {
4591 lck_mtx_unlock(sadb_mutex);
4592 sav->lft_c = kalloc_type(struct sadb_lifetime,
4593 Z_WAITOK | Z_NOFAIL);
4594 lck_mtx_lock(sadb_mutex);
4595 }
4596
4597 sav->lft_c->sadb_lifetime_len =
4598 PFKEY_UNIT64(sizeof(struct sadb_lifetime));
4599 sav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
4600 sav->lft_c->sadb_lifetime_allocations = 0;
4601 sav->lft_c->sadb_lifetime_bytes = 0;
4602 sav->lft_c->sadb_lifetime_addtime = current_time_ns;
4603 sav->lft_c->sadb_lifetime_usetime = 0;
4604
4605 /* lifetimes for HARD and SOFT */
4606 {
4607 const struct sadb_lifetime *lft0;
4608
4609 lft0 = (struct sadb_lifetime *)
4610 (void *)mhp->ext[SADB_EXT_LIFETIME_HARD];
4611 if (lft0 != NULL) {
4612 if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(*lft0)) {
4613 ipseclog((LOG_DEBUG, "key_setsaval: invalid hard lifetime ext len.\n"));
4614 error = EINVAL;
4615 goto fail;
4616 }
4617 sav->lft_h = (struct sadb_lifetime *)key_newbuf(lft0, sizeof(*lft0));
4618
4619 // Check that conversion to nanoseconds won't cause an overflow
4620 u_int64_t nanotime;
4621 if (__improbable(os_mul_overflow(sav->lft_h->sadb_lifetime_addtime, NSEC_PER_SEC, &nanotime))) {
4622 ipseclog((LOG_DEBUG, "key_setsaval: invalid hard lifetime value %llu.\n",
4623 sav->lft_h->sadb_lifetime_addtime));
4624 error = EINVAL;
4625 goto fail;
4626 }
4627 }
4628
4629 lft0 = (struct sadb_lifetime *)
4630 (void *)mhp->ext[SADB_EXT_LIFETIME_SOFT];
4631 if (lft0 != NULL) {
4632 if (mhp->extlen[SADB_EXT_LIFETIME_SOFT] < sizeof(*lft0)) {
4633 ipseclog((LOG_DEBUG, "key_setsaval: invalid soft lifetime ext len.\n"));
4634 error = EINVAL;
4635 goto fail;
4636 }
4637 sav->lft_s = (struct sadb_lifetime *)key_newbuf(lft0, sizeof(*lft0));
4638
4639 // Check that conversion to nanoseconds won't cause an overflow
4640 u_int64_t nanotime;
4641 if (__improbable(os_mul_overflow(sav->lft_s->sadb_lifetime_addtime, NSEC_PER_SEC, &nanotime))) {
4642 ipseclog((LOG_DEBUG, "key_setsaval: invalid soft lifetime value %llu.\n",
4643 sav->lft_s->sadb_lifetime_addtime));
4644 error = EINVAL;
4645 goto fail;
4646 }
4647 }
4648 }
4649
4650 return 0;
4651
4652fail:
4653 key_reset_sav(sav);
4654 return error;
4655}
4656
4657/*
4658 * validation with a secasvar entry, and set SADB_SATYPE_MATURE.
4659 * OUT: 0: valid
4660 * other: errno
4661 */
4662static int
4663key_mature(
4664 struct secasvar *sav)
4665{
4666 int mature;
4667 int checkmask = 0; /* 2^0: ealg 2^1: aalg 2^2: calg */
4668 int mustmask = 0; /* 2^0: ealg 2^1: aalg 2^2: calg */
4669
4670 mature = 0;
4671
4672 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
4673
4674 /* check SPI value */
4675 switch (sav->sah->saidx.proto) {
4676 case IPPROTO_ESP:
4677 case IPPROTO_AH:
4678
4679 /* No reason to test if this is >= 0, because ntohl(sav->spi) is unsigned. */
4680 if (ntohl(sav->spi) <= 255) {
4681 ipseclog((LOG_DEBUG,
4682 "key_mature: illegal range of SPI %u.\n",
4683 (u_int32_t)ntohl(sav->spi)));
4684 return EINVAL;
4685 }
4686 break;
4687 }
4688
4689 /* check satype */
4690 switch (sav->sah->saidx.proto) {
4691 case IPPROTO_ESP:
4692 /* check flags */
4693 if ((sav->flags & SADB_X_EXT_OLD)
4694 && (sav->flags & SADB_X_EXT_DERIV)) {
4695 ipseclog((LOG_DEBUG, "key_mature: "
4696 "invalid flag (derived) given to old-esp.\n"));
4697 return EINVAL;
4698 }
4699 if (sav->alg_auth == SADB_AALG_NONE) {
4700 checkmask = 1;
4701 } else {
4702 checkmask = 3;
4703 }
4704 mustmask = 1;
4705 break;
4706 case IPPROTO_AH:
4707 /* check flags */
4708 if (sav->flags & SADB_X_EXT_DERIV) {
4709 ipseclog((LOG_DEBUG, "key_mature: "
4710 "invalid flag (derived) given to AH SA.\n"));
4711 return EINVAL;
4712 }
4713 if (sav->alg_enc != SADB_EALG_NONE) {
4714 ipseclog((LOG_DEBUG, "key_mature: "
4715 "protocol and algorithm mismated.\n"));
4716 return EINVAL;
4717 }
4718 checkmask = 2;
4719 mustmask = 2;
4720 break;
4721 default:
4722 ipseclog((LOG_DEBUG, "key_mature: Invalid satype.\n"));
4723 return EPROTONOSUPPORT;
4724 }
4725
4726 /* check authentication algorithm */
4727 if ((checkmask & 2) != 0) {
4728 const struct ah_algorithm *algo;
4729 int keylen;
4730
4731 algo = ah_algorithm_lookup(sav->alg_auth);
4732 if (!algo) {
4733 ipseclog((LOG_DEBUG, "key_mature: "
4734 "unknown authentication algorithm.\n"));
4735 return EINVAL;
4736 }
4737
4738 /* algorithm-dependent check */
4739 if (sav->key_auth) {
4740 keylen = sav->key_auth->sadb_key_bits;
4741 } else {
4742 keylen = 0;
4743 }
4744 if (keylen < algo->keymin || algo->keymax < keylen) {
4745 ipseclog((LOG_DEBUG,
4746 "key_mature: invalid AH key length %d "
4747 "(%d-%d allowed)\n",
4748 keylen, algo->keymin, algo->keymax));
4749 return EINVAL;
4750 }
4751
4752 if (algo->mature) {
4753 if ((*algo->mature)(sav)) {
4754 /* message generated in per-algorithm function*/
4755 return EINVAL;
4756 } else {
4757 mature = SADB_SATYPE_AH;
4758 }
4759 }
4760
4761 if ((mustmask & 2) != 0 && mature != SADB_SATYPE_AH) {
4762 ipseclog((LOG_DEBUG, "key_mature: no satisfy algorithm for AH\n"));
4763 return EINVAL;
4764 }
4765 }
4766
4767 /* check encryption algorithm */
4768 if ((checkmask & 1) != 0) {
4769#if IPSEC_ESP
4770 const struct esp_algorithm *algo;
4771 int keylen;
4772
4773 algo = esp_algorithm_lookup(sav->alg_enc);
4774 if (!algo) {
4775 ipseclog((LOG_DEBUG, "key_mature: unknown encryption algorithm.\n"));
4776 return EINVAL;
4777 }
4778
4779 /* algorithm-dependent check */
4780 if (sav->key_enc) {
4781 keylen = sav->key_enc->sadb_key_bits;
4782 } else {
4783 keylen = 0;
4784 }
4785 if (keylen < algo->keymin || algo->keymax < keylen) {
4786 ipseclog((LOG_DEBUG,
4787 "key_mature: invalid ESP key length %d "
4788 "(%d-%d allowed)\n",
4789 keylen, algo->keymin, algo->keymax));
4790 return EINVAL;
4791 }
4792
4793 if (algo->mature) {
4794 if ((*algo->mature)(sav)) {
4795 /* message generated in per-algorithm function*/
4796 return EINVAL;
4797 } else {
4798 mature = SADB_SATYPE_ESP;
4799 }
4800 }
4801
4802 if ((mustmask & 1) != 0 && mature != SADB_SATYPE_ESP) {
4803 ipseclog((LOG_DEBUG, "key_mature: no satisfy algorithm for ESP\n"));
4804 return EINVAL;
4805 }
4806#else /*IPSEC_ESP*/
4807 ipseclog((LOG_DEBUG, "key_mature: ESP not supported in this configuration\n"));
4808 return EINVAL;
4809#endif
4810 }
4811
4812 key_sa_chgstate(sav, SADB_SASTATE_MATURE);
4813
4814 return 0;
4815}
4816
4817/*
4818 * subroutine for SADB_GET and SADB_DUMP.
4819 */
4820static struct mbuf *
4821key_setdumpsa(
4822 struct secasvar *sav,
4823 u_int8_t type,
4824 u_int8_t satype,
4825 u_int32_t seq,
4826 u_int32_t pid)
4827{
4828 struct mbuf *result = NULL, *tres = NULL, *m;
4829 int l = 0;
4830 int i;
4831 void *p;
4832 int dumporder[] = {
4833 SADB_EXT_SA, SADB_X_EXT_SA2,
4834 SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT,
4835 SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC,
4836 SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH,
4837 SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC,
4838 SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY,
4839 };
4840
4841 m = key_setsadbmsg(type, 0, satype, seq, pid, (u_int16_t)sav->refcnt);
4842 if (m == NULL) {
4843 goto fail;
4844 }
4845 result = m;
4846
4847 for (i = sizeof(dumporder) / sizeof(dumporder[0]) - 1; i >= 0; i--) {
4848 m = NULL;
4849 p = NULL;
4850 switch (dumporder[i]) {
4851 case SADB_EXT_SA:
4852 m = key_setsadbsa(sav);
4853 if (!m) {
4854 goto fail;
4855 }
4856 break;
4857
4858 case SADB_X_EXT_SA2:
4859 m = key_setsadbxsa2(sav->sah->saidx.mode,
4860 sav->replay[0] ? sav->replay[0]->count : 0,
4861 sav->sah->saidx.reqid,
4862 sav->flags2);
4863 if (!m) {
4864 goto fail;
4865 }
4866 break;
4867
4868 case SADB_EXT_ADDRESS_SRC:
4869 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
4870 (struct sockaddr *)&sav->sah->saidx.src,
4871 FULLMASK, IPSEC_ULPROTO_ANY);
4872 if (!m) {
4873 goto fail;
4874 }
4875 break;
4876
4877 case SADB_EXT_ADDRESS_DST:
4878 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
4879 (struct sockaddr *)&sav->sah->saidx.dst,
4880 FULLMASK, IPSEC_ULPROTO_ANY);
4881 if (!m) {
4882 goto fail;
4883 }
4884 break;
4885
4886 case SADB_EXT_KEY_AUTH:
4887 if (!sav->key_auth) {
4888 continue;
4889 }
4890 l = PFKEY_UNUNIT64(sav->key_auth->sadb_key_len);
4891 p = sav->key_auth;
4892 break;
4893
4894 case SADB_EXT_KEY_ENCRYPT:
4895 if (!sav->key_enc) {
4896 continue;
4897 }
4898 l = PFKEY_UNUNIT64(sav->key_enc->sadb_key_len);
4899 p = sav->key_enc;
4900 break;
4901
4902 case SADB_EXT_LIFETIME_CURRENT:
4903 if (!sav->lft_c) {
4904 continue;
4905 }
4906 m = key_setsalifecurr(sav->lft_c);
4907 if (!m) {
4908 goto fail;
4909 }
4910 break;
4911
4912 case SADB_EXT_LIFETIME_HARD:
4913 if (!sav->lft_h) {
4914 continue;
4915 }
4916 l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_h)->sadb_ext_len);
4917 p = sav->lft_h;
4918 break;
4919
4920 case SADB_EXT_LIFETIME_SOFT:
4921 if (!sav->lft_s) {
4922 continue;
4923 }
4924 l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_s)->sadb_ext_len);
4925 p = sav->lft_s;
4926 break;
4927
4928 case SADB_EXT_ADDRESS_PROXY:
4929 case SADB_EXT_IDENTITY_SRC:
4930 case SADB_EXT_IDENTITY_DST:
4931 /* XXX: should we brought from SPD ? */
4932 case SADB_EXT_SENSITIVITY:
4933 default:
4934 continue;
4935 }
4936
4937 if ((!m && !p) || (m && p)) {
4938 goto fail;
4939 }
4940 if (p && tres) {
4941 M_PREPEND(tres, l, M_WAITOK, 1);
4942 if (!tres) {
4943 goto fail;
4944 }
4945 bcopy(src: p, mtod(tres, caddr_t), n: l);
4946 continue;
4947 }
4948 if (p) {
4949 m = key_alloc_mbuf(l);
4950 if (!m) {
4951 goto fail;
4952 }
4953 m_copyback(m, 0, l, p);
4954 }
4955
4956 if (tres) {
4957 m_cat(m, tres);
4958 }
4959 tres = m;
4960 }
4961
4962 m_cat(result, tres);
4963
4964 if (sav->sah && (sav->sah->outgoing_if || sav->sah->ipsec_if)) {
4965 m = key_setsadbipsecif(NULL, ifindex2ifnet[sav->sah->outgoing_if], sav->sah->ipsec_if, 0);
4966 if (!m) {
4967 goto fail;
4968 }
4969 m_cat(result, m);
4970 }
4971
4972 if (result->m_len < sizeof(struct sadb_msg)) {
4973 result = m_pullup(result, sizeof(struct sadb_msg));
4974 if (result == NULL) {
4975 goto fail;
4976 }
4977 }
4978
4979 result->m_pkthdr.len = 0;
4980 for (m = result; m; m = m->m_next) {
4981 result->m_pkthdr.len += m->m_len;
4982 }
4983
4984 VERIFY(PFKEY_UNIT64(result->m_pkthdr.len) <= UINT16_MAX);
4985 mtod(result, struct sadb_msg *)->sadb_msg_len =
4986 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
4987
4988 return result;
4989
4990fail:
4991 m_freem(result);
4992 m_freem(tres);
4993 return NULL;
4994}
4995
4996/*
4997 * set data into sadb_msg.
4998 */
4999static struct mbuf *
5000key_setsadbmsg(
5001 u_int8_t type,
5002 u_int16_t tlen,
5003 u_int8_t satype,
5004 u_int32_t seq,
5005 pid_t pid,
5006 u_int16_t reserved)
5007{
5008 struct mbuf *m;
5009 struct sadb_msg *p;
5010 int len;
5011
5012 len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
5013 if (len > MCLBYTES) {
5014 return NULL;
5015 }
5016 MGETHDR(m, M_DONTWAIT, MT_DATA);
5017 if (m && len > MHLEN) {
5018 MCLGET(m, M_DONTWAIT);
5019 if ((m->m_flags & M_EXT) == 0) {
5020 m_freem(m);
5021 m = NULL;
5022 }
5023 }
5024 if (!m) {
5025 return NULL;
5026 }
5027 m->m_pkthdr.len = m->m_len = len;
5028 m->m_next = NULL;
5029
5030 p = mtod(m, struct sadb_msg *);
5031
5032 bzero(s: p, n: len);
5033 p->sadb_msg_version = PF_KEY_V2;
5034 p->sadb_msg_type = type;
5035 p->sadb_msg_errno = 0;
5036 p->sadb_msg_satype = satype;
5037 p->sadb_msg_len = PFKEY_UNIT64(tlen);
5038 p->sadb_msg_reserved = reserved;
5039 p->sadb_msg_seq = seq;
5040 p->sadb_msg_pid = (u_int32_t)pid;
5041
5042 return m;
5043}
5044
5045/*
5046 * copy secasvar data into sadb_address.
5047 */
5048static struct mbuf *
5049key_setsadbsa(
5050 struct secasvar *sav)
5051{
5052 struct mbuf *m;
5053 struct sadb_sa *p;
5054 u_int16_t len;
5055
5056 len = PFKEY_ALIGN8(sizeof(struct sadb_sa));
5057 m = key_alloc_mbuf(len);
5058 if (!m || m->m_next) { /*XXX*/
5059 if (m) {
5060 m_freem(m);
5061 }
5062 return NULL;
5063 }
5064
5065 p = mtod(m, struct sadb_sa *);
5066
5067 bzero(s: p, n: len);
5068 p->sadb_sa_len = PFKEY_UNIT64(len);
5069 p->sadb_sa_exttype = SADB_EXT_SA;
5070 p->sadb_sa_spi = sav->spi;
5071 p->sadb_sa_replay = (sav->replay[0] != NULL ? sav->replay[0]->wsize : 0);
5072 p->sadb_sa_state = sav->state;
5073 p->sadb_sa_auth = sav->alg_auth;
5074 p->sadb_sa_encrypt = sav->alg_enc;
5075 p->sadb_sa_flags = sav->flags;
5076
5077 return m;
5078}
5079
5080/*
5081 * set data into sadb_address.
5082 */
5083static struct mbuf *
5084key_setsadbaddr(
5085 u_int16_t exttype,
5086 struct sockaddr *saddr,
5087 size_t prefixlen,
5088 u_int8_t ul_proto)
5089{
5090 struct mbuf *m;
5091 struct sadb_address *p;
5092 u_int16_t len;
5093
5094 len = PFKEY_ALIGN8(sizeof(struct sadb_address)) +
5095 PFKEY_ALIGN8(saddr->sa_len);
5096 m = key_alloc_mbuf(len);
5097 if (!m || m->m_next) { /*XXX*/
5098 if (m) {
5099 m_freem(m);
5100 }
5101 return NULL;
5102 }
5103
5104 p = mtod(m, struct sadb_address *);
5105
5106 bzero(s: p, n: len);
5107 p->sadb_address_len = PFKEY_UNIT64(len);
5108 p->sadb_address_exttype = exttype;
5109 p->sadb_address_proto = ul_proto;
5110 if (prefixlen == FULLMASK) {
5111 switch (saddr->sa_family) {
5112 case AF_INET:
5113 prefixlen = sizeof(struct in_addr) << 3;
5114 break;
5115 case AF_INET6:
5116 prefixlen = sizeof(struct in6_addr) << 3;
5117 break;
5118 default:
5119 ; /*XXX*/
5120 }
5121 }
5122 if (prefixlen >= UINT8_MAX) {
5123 ipseclog((LOG_ERR, "key_setsadbaddr: bad prefix length %zu", prefixlen));
5124 m_freem(m);
5125 return NULL;
5126 }
5127 p->sadb_address_prefixlen = (u_int8_t)prefixlen;
5128 p->sadb_address_reserved = 0;
5129
5130 bcopy(src: saddr,
5131 mtod(m, caddr_t) + PFKEY_ALIGN8(sizeof(struct sadb_address)),
5132 n: saddr->sa_len);
5133
5134 return m;
5135}
5136
5137static struct mbuf *
5138key_setsadbipsecif(ifnet_t internal_if,
5139 ifnet_t outgoing_if,
5140 ifnet_t ipsec_if,
5141 u_int8_t init_disabled)
5142{
5143 struct mbuf *m;
5144 struct sadb_x_ipsecif *p;
5145 u_int16_t len;
5146
5147 len = PFKEY_ALIGN8(sizeof(struct sadb_x_ipsecif));
5148 m = key_alloc_mbuf(len);
5149 if (!m || m->m_next) { /*XXX*/
5150 if (m) {
5151 m_freem(m);
5152 }
5153 return NULL;
5154 }
5155
5156 p = mtod(m, struct sadb_x_ipsecif *);
5157
5158 bzero(s: p, n: len);
5159 p->sadb_x_ipsecif_len = PFKEY_UNIT64(len);
5160 p->sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF;
5161
5162 if (internal_if && internal_if->if_xname) {
5163 strlcpy(dst: p->sadb_x_ipsecif_internal_if, src: internal_if->if_xname, IFXNAMSIZ);
5164 }
5165 if (outgoing_if && outgoing_if->if_xname) {
5166 strlcpy(dst: p->sadb_x_ipsecif_outgoing_if, src: outgoing_if->if_xname, IFXNAMSIZ);
5167 }
5168 if (ipsec_if && ipsec_if->if_xname) {
5169 strlcpy(dst: p->sadb_x_ipsecif_ipsec_if, src: ipsec_if->if_xname, IFXNAMSIZ);
5170 }
5171
5172 p->sadb_x_ipsecif_init_disabled = init_disabled;
5173
5174 return m;
5175}
5176
5177/*
5178 * set data into sadb_session_id
5179 */
5180static struct mbuf *
5181key_setsadbsession_id(u_int64_t session_ids[])
5182{
5183 struct mbuf *m;
5184 struct sadb_session_id *p;
5185 u_int16_t len;
5186
5187 len = PFKEY_ALIGN8(sizeof(*p));
5188 m = key_alloc_mbuf(len);
5189 if (!m || m->m_next) { /*XXX*/
5190 if (m) {
5191 m_freem(m);
5192 }
5193 return NULL;
5194 }
5195
5196 p = mtod(m, __typeof__(p));
5197
5198 bzero(s: p, n: len);
5199 p->sadb_session_id_len = PFKEY_UNIT64(len);
5200 p->sadb_session_id_exttype = SADB_EXT_SESSION_ID;
5201 p->sadb_session_id_v[0] = session_ids[0];
5202 p->sadb_session_id_v[1] = session_ids[1];
5203
5204 return m;
5205}
5206
5207/*
5208 * copy stats data into sadb_sastat type.
5209 */
5210static struct mbuf *
5211key_setsadbsastat(u_int32_t dir,
5212 struct sastat *stats,
5213 u_int32_t max_stats)
5214{
5215 struct mbuf *m;
5216 struct sadb_sastat *p;
5217 size_t list_len, len;
5218
5219 if (!stats) {
5220 return NULL;
5221 }
5222
5223 list_len = sizeof(*stats) * max_stats;
5224 len = PFKEY_ALIGN8(sizeof(*p)) + PFKEY_ALIGN8(list_len);
5225 if (PFKEY_UNIT64(len) >= UINT16_MAX) {
5226 ipseclog((LOG_ERR, "key_setsadbsastat: length is too big: %zu\n", len));
5227 return NULL;
5228 }
5229
5230 m = key_alloc_mbuf((int)len);
5231 if (!m || m->m_next) { /*XXX*/
5232 if (m) {
5233 m_freem(m);
5234 }
5235 return NULL;
5236 }
5237
5238 p = mtod(m, __typeof__(p));
5239
5240 bzero(s: p, n: len);
5241 p->sadb_sastat_len = (u_int16_t)PFKEY_UNIT64(len);
5242 p->sadb_sastat_exttype = SADB_EXT_SASTAT;
5243 p->sadb_sastat_dir = dir;
5244 p->sadb_sastat_list_len = max_stats;
5245 if (list_len) {
5246 bcopy(src: stats,
5247 mtod(m, caddr_t) + PFKEY_ALIGN8(sizeof(*p)),
5248 n: list_len);
5249 }
5250
5251 return m;
5252}
5253
5254/*
5255 * set data into sadb_x_sa2.
5256 */
5257static struct mbuf *
5258key_setsadbxsa2(
5259 u_int8_t mode,
5260 u_int32_t seq,
5261 u_int32_t reqid,
5262 u_int16_t flags)
5263{
5264 struct mbuf *m;
5265 struct sadb_x_sa2 *p;
5266 u_int16_t len;
5267
5268 len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa2));
5269 m = key_alloc_mbuf(len);
5270 if (!m || m->m_next) { /*XXX*/
5271 if (m) {
5272 m_freem(m);
5273 }
5274 return NULL;
5275 }
5276
5277 p = mtod(m, struct sadb_x_sa2 *);
5278
5279 bzero(s: p, n: len);
5280 p->sadb_x_sa2_len = PFKEY_UNIT64(len);
5281 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
5282 p->sadb_x_sa2_mode = mode;
5283 p->sadb_x_sa2_reserved1 = 0;
5284 p->sadb_x_sa2_reserved2 = 0;
5285 p->sadb_x_sa2_sequence = seq;
5286 p->sadb_x_sa2_reqid = reqid;
5287 p->sadb_x_sa2_flags = flags;
5288
5289 return m;
5290}
5291
5292/*
5293 * set data into sadb_x_policy
5294 */
5295static struct mbuf *
5296key_setsadbxpolicy(
5297 u_int16_t type,
5298 u_int8_t dir,
5299 u_int32_t id)
5300{
5301 struct mbuf *m;
5302 struct sadb_x_policy *p;
5303 u_int16_t len;
5304
5305 len = PFKEY_ALIGN8(sizeof(struct sadb_x_policy));
5306 m = key_alloc_mbuf(len);
5307 if (!m || m->m_next) { /*XXX*/
5308 if (m) {
5309 m_freem(m);
5310 }
5311 return NULL;
5312 }
5313
5314 p = mtod(m, struct sadb_x_policy *);
5315
5316 bzero(s: p, n: len);
5317 p->sadb_x_policy_len = PFKEY_UNIT64(len);
5318 p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
5319 p->sadb_x_policy_type = type;
5320 p->sadb_x_policy_dir = dir;
5321 p->sadb_x_policy_id = id;
5322
5323 return m;
5324}
5325
5326/*
5327 * Copy current lifetime data, converting timestamps to wall clock time
5328 */
5329static struct mbuf *
5330key_setsalifecurr(
5331 struct sadb_lifetime *lft_c)
5332{
5333 struct mbuf *m;
5334 struct sadb_lifetime *p;
5335 u_int16_t len;
5336
5337 len = PFKEY_ALIGN8(sizeof(struct sadb_lifetime));
5338 m = key_alloc_mbuf(len);
5339 if (!m || m->m_next) { /*XXX*/
5340 if (m) {
5341 m_freem(m);
5342 }
5343 return NULL;
5344 }
5345
5346 p = mtod(m, struct sadb_lifetime *);
5347 bcopy(src: lft_c, dst: p, n: sizeof(struct sadb_lifetime));
5348
5349 // Convert timestamps
5350 p->sadb_lifetime_addtime = key_convert_continuous_time_ns(time_value: lft_c->sadb_lifetime_addtime);
5351 p->sadb_lifetime_usetime = key_convert_continuous_time_ns(time_value: lft_c->sadb_lifetime_usetime);
5352
5353 return m;
5354}
5355
5356/* %%% utilities */
5357/*
5358 * copy a buffer into the new buffer allocated.
5359 */
5360static void *
5361key_newbuf(
5362 const void *src,
5363 u_int len)
5364{
5365 caddr_t new;
5366
5367 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
5368 new = kalloc_data(len, Z_NOWAIT);
5369 if (new == NULL) {
5370 lck_mtx_unlock(sadb_mutex);
5371 new = kalloc_data(len, Z_WAITOK | Z_NOFAIL);
5372 lck_mtx_lock(sadb_mutex);
5373 }
5374 bcopy(src, dst: new, n: len);
5375
5376 return new;
5377}
5378
5379/* compare my own address
5380 * OUT: 1: true, i.e. my address.
5381 * 0: false
5382 */
5383int
5384key_ismyaddr(
5385 struct sockaddr *sa)
5386{
5387#if INET
5388 struct sockaddr_in *sin;
5389 struct in_ifaddr *ia;
5390#endif
5391
5392 /* sanity check */
5393 if (sa == NULL) {
5394 panic("key_ismyaddr: NULL pointer is passed.");
5395 }
5396
5397 switch (sa->sa_family) {
5398#if INET
5399 case AF_INET:
5400 lck_rw_lock_shared(lck: &in_ifaddr_rwlock);
5401 sin = (struct sockaddr_in *)(void *)sa;
5402 for (ia = in_ifaddrhead.tqh_first; ia;
5403 ia = ia->ia_link.tqe_next) {
5404 IFA_LOCK_SPIN(&ia->ia_ifa);
5405 if (sin->sin_family == ia->ia_addr.sin_family &&
5406 sin->sin_len == ia->ia_addr.sin_len &&
5407 sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr) {
5408 IFA_UNLOCK(&ia->ia_ifa);
5409 lck_rw_done(lck: &in_ifaddr_rwlock);
5410 return 1;
5411 }
5412 IFA_UNLOCK(&ia->ia_ifa);
5413 }
5414 lck_rw_done(lck: &in_ifaddr_rwlock);
5415 break;
5416#endif
5417 case AF_INET6:
5418 return key_ismyaddr6((struct sockaddr_in6 *)(void *)sa);
5419 }
5420
5421 return 0;
5422}
5423
5424/*
5425 * compare my own address for IPv6.
5426 * 1: ours
5427 * 0: other
5428 * NOTE: derived ip6_input() in KAME. This is necessary to modify more.
5429 */
5430#include <netinet6/in6_var.h>
5431
5432static int
5433key_ismyaddr6(
5434 struct sockaddr_in6 *sin6)
5435{
5436 struct in6_ifaddr *ia;
5437 struct in6_multi *in6m;
5438
5439 lck_rw_lock_shared(lck: &in6_ifaddr_rwlock);
5440 TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
5441 IFA_LOCK(&ia->ia_ifa);
5442 if (key_sockaddrcmp((struct sockaddr *)&sin6,
5443 (struct sockaddr *)&ia->ia_addr, 0) == 0) {
5444 IFA_UNLOCK(&ia->ia_ifa);
5445 lck_rw_done(lck: &in6_ifaddr_rwlock);
5446 return 1;
5447 }
5448 IFA_UNLOCK(&ia->ia_ifa);
5449
5450 /*
5451 * XXX Multicast
5452 * XXX why do we care about multlicast here while we don't care
5453 * about IPv4 multicast??
5454 * XXX scope
5455 */
5456 in6m = NULL;
5457 in6_multihead_lock_shared();
5458 IN6_LOOKUP_MULTI(&sin6->sin6_addr, ia->ia_ifp, in6m);
5459 in6_multihead_lock_done();
5460 if (in6m != NULL) {
5461 lck_rw_done(lck: &in6_ifaddr_rwlock);
5462 IN6M_REMREF(in6m);
5463 return 1;
5464 }
5465 }
5466 lck_rw_done(lck: &in6_ifaddr_rwlock);
5467
5468 /* loopback, just for safety */
5469 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
5470 return 1;
5471 }
5472
5473 return 0;
5474}
5475
5476/*
5477 * compare two secasindex structure.
5478 * flag can specify to compare 2 saidxes.
5479 * compare two secasindex structure without both mode and reqid.
5480 * don't compare port.
5481 * IN:
5482 * saidx0: source, it can be in SAD.
5483 * saidx1: object.
5484 * OUT:
5485 * 1 : equal
5486 * 0 : not equal
5487 */
5488static int
5489key_cmpsaidx(
5490 struct secasindex *saidx0,
5491 struct secasindex *saidx1,
5492 int flag)
5493{
5494 /* sanity */
5495 if (saidx0 == NULL && saidx1 == NULL) {
5496 return 1;
5497 }
5498
5499 if (saidx0 == NULL || saidx1 == NULL) {
5500 return 0;
5501 }
5502
5503 if (saidx0->ipsec_ifindex != 0 && saidx0->ipsec_ifindex != saidx1->ipsec_ifindex) {
5504 return 0;
5505 }
5506
5507 if (saidx0->proto != saidx1->proto) {
5508 return 0;
5509 }
5510
5511 if (flag == CMP_EXACTLY) {
5512 if (saidx0->mode != saidx1->mode) {
5513 return 0;
5514 }
5515 if (saidx0->reqid != saidx1->reqid) {
5516 return 0;
5517 }
5518 if (bcmp(s1: &saidx0->src, s2: &saidx1->src, n: saidx0->src.ss_len) != 0 ||
5519 bcmp(s1: &saidx0->dst, s2: &saidx1->dst, n: saidx0->dst.ss_len) != 0) {
5520 return 0;
5521 }
5522 } else {
5523 /* CMP_MODE_REQID, CMP_REQID, CMP_HEAD */
5524 if (flag & CMP_REQID) {
5525 /*
5526 * If reqid of SPD is non-zero, unique SA is required.
5527 * The result must be of same reqid in this case.
5528 */
5529 if (saidx1->reqid != 0 && saidx0->reqid != saidx1->reqid) {
5530 return 0;
5531 }
5532 }
5533
5534 if (flag & CMP_MODE) {
5535 if (saidx0->mode != IPSEC_MODE_ANY
5536 && saidx0->mode != saidx1->mode) {
5537 return 0;
5538 }
5539 }
5540
5541 if (key_sockaddrcmp((struct sockaddr *)&saidx0->src,
5542 (struct sockaddr *)&saidx1->src, flag & CMP_PORT ? 1 : 0) != 0) {
5543 return 0;
5544 }
5545 if (key_sockaddrcmp((struct sockaddr *)&saidx0->dst,
5546 (struct sockaddr *)&saidx1->dst, flag & CMP_PORT ? 1 : 0) != 0) {
5547 return 0;
5548 }
5549 }
5550
5551 return 1;
5552}
5553
5554/*
5555 * compare two secindex structure exactly.
5556 * IN:
5557 * spidx0: source, it is often in SPD.
5558 * spidx1: object, it is often from PFKEY message.
5559 * OUT:
5560 * 1 : equal
5561 * 0 : not equal
5562 */
5563static int
5564key_cmpspidx_exactly(
5565 struct secpolicyindex *spidx0,
5566 struct secpolicyindex *spidx1)
5567{
5568 /* sanity */
5569 if (spidx0 == NULL && spidx1 == NULL) {
5570 return 1;
5571 }
5572
5573 if (spidx0 == NULL || spidx1 == NULL) {
5574 return 0;
5575 }
5576
5577 if (spidx0->prefs != spidx1->prefs
5578 || spidx0->prefd != spidx1->prefd
5579 || spidx0->ul_proto != spidx1->ul_proto
5580 || spidx0->internal_if != spidx1->internal_if) {
5581 return 0;
5582 }
5583
5584 if (key_sockaddrcmp((struct sockaddr *)&spidx0->src,
5585 (struct sockaddr *)&spidx1->src, 1) != 0) {
5586 return 0;
5587 }
5588 if (key_sockaddrcmp((struct sockaddr *)&spidx0->dst,
5589 (struct sockaddr *)&spidx1->dst, 1) != 0) {
5590 return 0;
5591 }
5592
5593 if (key_sockaddrcmp((struct sockaddr *)&spidx0->src_range.start,
5594 (struct sockaddr *)&spidx1->src_range.start, 1) != 0) {
5595 return 0;
5596 }
5597 if (key_sockaddrcmp((struct sockaddr *)&spidx0->src_range.end,
5598 (struct sockaddr *)&spidx1->src_range.end, 1) != 0) {
5599 return 0;
5600 }
5601 if (key_sockaddrcmp((struct sockaddr *)&spidx0->dst_range.start,
5602 (struct sockaddr *)&spidx1->dst_range.start, 1) != 0) {
5603 return 0;
5604 }
5605 if (key_sockaddrcmp((struct sockaddr *)&spidx0->dst_range.end,
5606 (struct sockaddr *)&spidx1->dst_range.end, 1) != 0) {
5607 return 0;
5608 }
5609
5610 return 1;
5611}
5612
5613/*
5614 * compare two secindex structure with mask.
5615 * IN:
5616 * spidx0: source, it is often in SPD.
5617 * spidx1: object, it is often from IP header.
5618 * OUT:
5619 * 1 : equal
5620 * 0 : not equal
5621 */
5622static int
5623key_cmpspidx_withmask(
5624 struct secpolicyindex *spidx0,
5625 struct secpolicyindex *spidx1)
5626{
5627 int spidx0_src_is_range = 0;
5628 int spidx0_dst_is_range = 0;
5629
5630 /* sanity */
5631 if (spidx0 == NULL && spidx1 == NULL) {
5632 return 1;
5633 }
5634
5635 if (spidx0 == NULL || spidx1 == NULL) {
5636 return 0;
5637 }
5638
5639 if (spidx0->src_range.start.ss_len > 0) {
5640 spidx0_src_is_range = 1;
5641 }
5642
5643 if (spidx0->dst_range.start.ss_len > 0) {
5644 spidx0_dst_is_range = 1;
5645 }
5646
5647 if ((spidx0_src_is_range ? spidx0->src_range.start.ss_family : spidx0->src.ss_family) != spidx1->src.ss_family ||
5648 (spidx0_dst_is_range ? spidx0->dst_range.start.ss_family : spidx0->dst.ss_family) != spidx1->dst.ss_family ||
5649 (spidx0_src_is_range ? spidx0->src_range.start.ss_len : spidx0->src.ss_len) != spidx1->src.ss_len ||
5650 (spidx0_dst_is_range ? spidx0->dst_range.start.ss_len : spidx0->dst.ss_len) != spidx1->dst.ss_len) {
5651 return 0;
5652 }
5653
5654 /* if spidx.ul_proto == IPSEC_ULPROTO_ANY, ignore. */
5655 if (spidx0->ul_proto != (u_int16_t)IPSEC_ULPROTO_ANY
5656 && spidx0->ul_proto != spidx1->ul_proto) {
5657 return 0;
5658 }
5659
5660 /* If spidx1 specifies interface, ignore src addr */
5661 if (spidx1->internal_if != NULL) {
5662 if (spidx0->internal_if == NULL
5663 || spidx0->internal_if != spidx1->internal_if) {
5664 return 0;
5665 }
5666
5667 /* Still check ports */
5668 switch (spidx0->src.ss_family) {
5669 case AF_INET:
5670 if (spidx0_src_is_range &&
5671 (satosin(&spidx1->src)->sin_port < satosin(&spidx0->src_range.start)->sin_port
5672 || satosin(&spidx1->src)->sin_port > satosin(&spidx0->src_range.end)->sin_port)) {
5673 return 0;
5674 } else if (satosin(&spidx0->src)->sin_port != IPSEC_PORT_ANY
5675 && satosin(&spidx0->src)->sin_port !=
5676 satosin(&spidx1->src)->sin_port) {
5677 return 0;
5678 }
5679 break;
5680 case AF_INET6:
5681 if (spidx0_src_is_range &&
5682 (satosin6(&spidx1->src)->sin6_port < satosin6(&spidx0->src_range.start)->sin6_port
5683 || satosin6(&spidx1->src)->sin6_port > satosin6(&spidx0->src_range.end)->sin6_port)) {
5684 return 0;
5685 } else if (satosin6(&spidx0->src)->sin6_port != IPSEC_PORT_ANY
5686 && satosin6(&spidx0->src)->sin6_port !=
5687 satosin6(&spidx1->src)->sin6_port) {
5688 return 0;
5689 }
5690 break;
5691 default:
5692 break;
5693 }
5694 } else if (spidx0_src_is_range) {
5695 if (!key_is_addr_in_range(&spidx1->src, &spidx0->src_range)) {
5696 return 0;
5697 }
5698 } else {
5699 switch (spidx0->src.ss_family) {
5700 case AF_INET:
5701 if (satosin(&spidx0->src)->sin_port != IPSEC_PORT_ANY
5702 && satosin(&spidx0->src)->sin_port !=
5703 satosin(&spidx1->src)->sin_port) {
5704 return 0;
5705 }
5706 if (!key_bbcmp((caddr_t)&satosin(&spidx0->src)->sin_addr,
5707 (caddr_t)&satosin(&spidx1->src)->sin_addr, spidx0->prefs)) {
5708 return 0;
5709 }
5710 break;
5711 case AF_INET6:
5712 if (satosin6(&spidx0->src)->sin6_port != IPSEC_PORT_ANY
5713 && satosin6(&spidx0->src)->sin6_port !=
5714 satosin6(&spidx1->src)->sin6_port) {
5715 return 0;
5716 }
5717 /*
5718 * scope_id check. if sin6_scope_id is 0, we regard it
5719 * as a wildcard scope, which matches any scope zone ID.
5720 */
5721 if (satosin6(&spidx0->src)->sin6_scope_id &&
5722 satosin6(&spidx1->src)->sin6_scope_id &&
5723 satosin6(&spidx0->src)->sin6_scope_id !=
5724 satosin6(&spidx1->src)->sin6_scope_id) {
5725 return 0;
5726 }
5727 if (!key_bbcmp((caddr_t)&satosin6(&spidx0->src)->sin6_addr,
5728 (caddr_t)&satosin6(&spidx1->src)->sin6_addr, spidx0->prefs)) {
5729 return 0;
5730 }
5731 break;
5732 default:
5733 /* XXX */
5734 if (bcmp(s1: &spidx0->src, s2: &spidx1->src, n: spidx0->src.ss_len) != 0) {
5735 return 0;
5736 }
5737 break;
5738 }
5739 }
5740
5741 if (spidx0_dst_is_range) {
5742 if (!key_is_addr_in_range(&spidx1->dst, &spidx0->dst_range)) {
5743 return 0;
5744 }
5745 } else {
5746 switch (spidx0->dst.ss_family) {
5747 case AF_INET:
5748 if (satosin(&spidx0->dst)->sin_port != IPSEC_PORT_ANY
5749 && satosin(&spidx0->dst)->sin_port !=
5750 satosin(&spidx1->dst)->sin_port) {
5751 return 0;
5752 }
5753 if (!key_bbcmp((caddr_t)&satosin(&spidx0->dst)->sin_addr,
5754 (caddr_t)&satosin(&spidx1->dst)->sin_addr, spidx0->prefd)) {
5755 return 0;
5756 }
5757 break;
5758 case AF_INET6:
5759 if (satosin6(&spidx0->dst)->sin6_port != IPSEC_PORT_ANY
5760 && satosin6(&spidx0->dst)->sin6_port !=
5761 satosin6(&spidx1->dst)->sin6_port) {
5762 return 0;
5763 }
5764 /*
5765 * scope_id check. if sin6_scope_id is 0, we regard it
5766 * as a wildcard scope, which matches any scope zone ID.
5767 */
5768 if (satosin6(&spidx0->src)->sin6_scope_id &&
5769 satosin6(&spidx1->src)->sin6_scope_id &&
5770 satosin6(&spidx0->dst)->sin6_scope_id !=
5771 satosin6(&spidx1->dst)->sin6_scope_id) {
5772 return 0;
5773 }
5774 if (!key_bbcmp((caddr_t)&satosin6(&spidx0->dst)->sin6_addr,
5775 (caddr_t)&satosin6(&spidx1->dst)->sin6_addr, spidx0->prefd)) {
5776 return 0;
5777 }
5778 break;
5779 default:
5780 /* XXX */
5781 if (bcmp(s1: &spidx0->dst, s2: &spidx1->dst, n: spidx0->dst.ss_len) != 0) {
5782 return 0;
5783 }
5784 break;
5785 }
5786 }
5787
5788 /* XXX Do we check other field ? e.g. flowinfo */
5789
5790 return 1;
5791}
5792
5793static int
5794key_is_addr_in_range(struct sockaddr_storage *addr, struct secpolicyaddrrange *addr_range)
5795{
5796 int cmp = 0;
5797
5798 if (addr == NULL || addr_range == NULL) {
5799 return 0;
5800 }
5801
5802 /* Must be greater than or equal to start */
5803 cmp = key_sockaddrcmp((struct sockaddr *)addr, (struct sockaddr *)&addr_range->start, 1);
5804 if (cmp != 0 && cmp != 1) {
5805 return 0;
5806 }
5807
5808 /* Must be less than or equal to end */
5809 cmp = key_sockaddrcmp((struct sockaddr *)addr, (struct sockaddr *)&addr_range->end, 1);
5810 if (cmp != 0 && cmp != -1) {
5811 return 0;
5812 }
5813
5814 return 1;
5815}
5816
5817/*
5818 * Return values:
5819 * -1: sa1 < sa2
5820 * 0: sa1 == sa2
5821 * 1: sa1 > sa2
5822 * 2: Not comparable or error
5823 */
5824static int
5825key_sockaddrcmp(
5826 struct sockaddr *sa1,
5827 struct sockaddr *sa2,
5828 int port)
5829{
5830 int result = 0;
5831 int port_result = 0;
5832
5833 if (sa1->sa_family != sa2->sa_family || sa1->sa_len != sa2->sa_len) {
5834 return 2;
5835 }
5836
5837 if (sa1->sa_len == 0) {
5838 return 0;
5839 }
5840
5841 switch (sa1->sa_family) {
5842 case AF_INET:
5843 if (sa1->sa_len != sizeof(struct sockaddr_in)) {
5844 return 2;
5845 }
5846
5847 result = memcmp(s1: &satosin(sa1)->sin_addr.s_addr, s2: &satosin(sa2)->sin_addr.s_addr, n: sizeof(satosin(sa1)->sin_addr.s_addr));
5848
5849 if (port) {
5850 if (satosin(sa1)->sin_port < satosin(sa2)->sin_port) {
5851 port_result = -1;
5852 } else if (satosin(sa1)->sin_port > satosin(sa2)->sin_port) {
5853 port_result = 1;
5854 }
5855
5856 if (result == 0) {
5857 result = port_result;
5858 } else if ((result > 0 && port_result < 0) || (result < 0 && port_result > 0)) {
5859 return 2;
5860 }
5861 }
5862
5863 break;
5864 case AF_INET6:
5865 if (sa1->sa_len != sizeof(struct sockaddr_in6)) {
5866 return 2; /*EINVAL*/
5867 }
5868 if (satosin6(sa1)->sin6_scope_id !=
5869 satosin6(sa2)->sin6_scope_id) {
5870 return 2;
5871 }
5872
5873 result = memcmp(s1: &satosin6(sa1)->sin6_addr.s6_addr[0], s2: &satosin6(sa2)->sin6_addr.s6_addr[0], n: sizeof(struct in6_addr));
5874
5875 if (port) {
5876 if (satosin6(sa1)->sin6_port < satosin6(sa2)->sin6_port) {
5877 port_result = -1;
5878 } else if (satosin6(sa1)->sin6_port > satosin6(sa2)->sin6_port) {
5879 port_result = 1;
5880 }
5881
5882 if (result == 0) {
5883 result = port_result;
5884 } else if ((result > 0 && port_result < 0) || (result < 0 && port_result > 0)) {
5885 return 2;
5886 }
5887 }
5888
5889 break;
5890 default:
5891 result = memcmp(s1: sa1, s2: sa2, n: sa1->sa_len);
5892 break;
5893 }
5894
5895 if (result < 0) {
5896 result = -1;
5897 } else if (result > 0) {
5898 result = 1;
5899 }
5900
5901 return result;
5902}
5903
5904/*
5905 * compare two buffers with mask.
5906 * IN:
5907 * addr1: source
5908 * addr2: object
5909 * bits: Number of bits to compare
5910 * OUT:
5911 * 1 : equal
5912 * 0 : not equal
5913 */
5914static int
5915key_bbcmp(
5916 caddr_t p1,
5917 caddr_t p2,
5918 u_int bits)
5919{
5920 u_int8_t mask;
5921
5922 /* XXX: This could be considerably faster if we compare a word
5923 * at a time, but it is complicated on LSB Endian machines */
5924
5925 /* Handle null pointers */
5926 if (p1 == NULL || p2 == NULL) {
5927 return p1 == p2;
5928 }
5929
5930 while (bits >= 8) {
5931 if (*p1++ != *p2++) {
5932 return 0;
5933 }
5934 bits -= 8;
5935 }
5936
5937 if (bits > 0) {
5938 mask = (u_int8_t)(~((1 << (8 - bits)) - 1));
5939 if ((*p1 & mask) != (*p2 & mask)) {
5940 return 0;
5941 }
5942 }
5943 return 1; /* Match! */
5944}
5945
5946/*
5947 * time handler.
5948 * scanning SPD and SAD to check status for each entries,
5949 * and do to remove or to expire.
5950 * XXX: year 2038 problem may remain.
5951 */
5952int key_timehandler_debug = 0;
5953u_int32_t spd_count = 0, sah_count = 0, dead_sah_count = 0, empty_sah_count = 0, larval_sav_count = 0, mature_sav_count = 0, dying_sav_count = 0, dead_sav_count = 0;
5954u_int64_t total_sav_count = 0;
5955void
5956key_timehandler(void)
5957{
5958 u_int dir;
5959 struct secpolicy **spbuf = NULL, **spptr = NULL;
5960 struct secasvar **savexbuf = NULL, **savexptr = NULL;
5961 struct secasvar **savkabuf = NULL, **savkaptr = NULL;
5962 u_int32_t spbufcount = 0, savbufcount = 0, spcount = 0, savexcount = 0, savkacount = 0, cnt;
5963 int stop_handler = 1; /* stop the timehandler */
5964 const u_int64_t current_time_ns = key_get_continuous_time_ns();
5965
5966 /* pre-allocate buffers before taking the lock */
5967 /* if allocation failures occur - portions of the processing will be skipped */
5968 if ((spbufcount = ipsec_policy_count) != 0) {
5969 if (os_add_overflow(spbufcount, 256, &spbufcount)) {
5970 ipseclog((LOG_DEBUG, "key_timehandler: spbufcount overflow, ipsec policy count %u.\n", ipsec_policy_count));
5971 spbufcount = ipsec_policy_count;
5972 }
5973
5974 spbuf = kalloc_type(struct secpolicy *, spbufcount, Z_WAITOK);
5975 if (spbuf) {
5976 spptr = spbuf;
5977 }
5978 }
5979 if ((savbufcount = ipsec_sav_count) != 0) {
5980 if (os_add_overflow(savbufcount, 512, &savbufcount)) {
5981 ipseclog((LOG_DEBUG, "key_timehandler: savbufcount overflow, ipsec sa count %u.\n", ipsec_sav_count));
5982 savbufcount = ipsec_sav_count;
5983 }
5984 savexbuf = kalloc_type(struct secasvar *, savbufcount, Z_WAITOK);
5985 if (savexbuf) {
5986 savexptr = savexbuf;
5987 }
5988 savkabuf = kalloc_type(struct secasvar *, savbufcount, Z_WAITOK);
5989 if (savkabuf) {
5990 savkaptr = savkabuf;
5991 }
5992 }
5993 lck_mtx_lock(sadb_mutex);
5994 /* SPD */
5995 if (spbuf) {
5996 struct secpolicy *sp, *nextsp;
5997
5998 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
5999 for (sp = LIST_FIRST(&sptree[dir]);
6000 sp != NULL;
6001 sp = nextsp) {
6002 /* don't prevent timehandler from stopping for generate policy */
6003 if (sp->policy != IPSEC_POLICY_GENERATE) {
6004 stop_handler = 0;
6005 }
6006 spd_count++;
6007 nextsp = LIST_NEXT(sp, chain);
6008
6009 if (sp->state == IPSEC_SPSTATE_DEAD) {
6010 key_freesp(sp, KEY_SADB_LOCKED);
6011 continue;
6012 }
6013
6014 if (sp->lifetime == 0 && sp->validtime == 0) {
6015 continue;
6016 }
6017 if (spbuf && spcount < spbufcount) {
6018 /* the deletion will occur next time */
6019 if ((sp->lifetime
6020 && current_time_ns - sp->created > sp->lifetime)
6021 || (sp->validtime
6022 && current_time_ns - sp->lastused > sp->validtime)) {
6023 //key_spdexpire(sp);
6024 sp->state = IPSEC_SPSTATE_DEAD;
6025 sp->refcnt++;
6026 *spptr++ = sp;
6027 spcount++;
6028 }
6029 }
6030 }
6031 }
6032 }
6033
6034 /* SAD */
6035 {
6036 struct secashead *sah, *nextsah;
6037 struct secasvar *sav, *nextsav;
6038
6039 for (sah = LIST_FIRST(&sahtree);
6040 sah != NULL;
6041 sah = nextsah) {
6042 sah_count++;
6043 nextsah = LIST_NEXT(sah, chain);
6044
6045 /* if sah has been dead, then delete it and process next sah. */
6046 if (sah->state == SADB_SASTATE_DEAD) {
6047 key_delsah(sah);
6048 dead_sah_count++;
6049 continue;
6050 }
6051
6052 if (LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]) == NULL &&
6053 LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]) == NULL &&
6054 LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]) == NULL &&
6055 LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]) == NULL) {
6056 key_delsah(sah);
6057 empty_sah_count++;
6058 continue;
6059 }
6060
6061 if (savbufcount == 0) {
6062 continue;
6063 }
6064
6065 stop_handler = 0;
6066
6067 /* if LARVAL entry doesn't become MATURE, delete it. */
6068 const u_int64_t larval_lifetime = (u_int64_t)key_larval_lifetime * NSEC_PER_SEC;
6069 for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]);
6070 sav != NULL;
6071 sav = nextsav) {
6072 larval_sav_count++;
6073 total_sav_count++;
6074 nextsav = LIST_NEXT(sav, chain);
6075
6076 if (sav->lft_h != NULL) {
6077 /* If a hard lifetime is defined for the LARVAL SA, use it */
6078 if (sav->lft_h->sadb_lifetime_addtime != 0) {
6079 const u_int64_t lifetime_addtime = sav->lft_h->sadb_lifetime_addtime * NSEC_PER_SEC;
6080 if (current_time_ns - sav->created > lifetime_addtime) {
6081 if (sav->always_expire) {
6082 key_send_delete(sav);
6083 sav = NULL;
6084 } else {
6085 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
6086 key_freesav(sav, KEY_SADB_LOCKED);
6087 sav = NULL;
6088 }
6089 }
6090 }
6091 } else {
6092 if (current_time_ns - sav->created > larval_lifetime) {
6093 key_freesav(sav, KEY_SADB_LOCKED);
6094 }
6095 }
6096 }
6097
6098 /*
6099 * If this is a NAT traversal SA with no activity,
6100 * we need to send a keep alive.
6101 *
6102 * Performed outside of the loop before so we will
6103 * only ever send one keepalive. The first SA on
6104 * the list is the one that will be used for sending
6105 * traffic, so this is the one we use for determining
6106 * when to send the keepalive.
6107 */
6108 if (savkabuf && savkacount < savbufcount) {
6109 sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]); //%%% should we check dying list if this is empty???
6110 if (sav && (natt_keepalive_interval || sav->natt_interval) &&
6111 (sav->flags & (SADB_X_EXT_NATT_KEEPALIVE | SADB_X_EXT_ESP_KEEPALIVE)) != 0) {
6112 sav->refcnt++;
6113 *savkaptr++ = sav;
6114 savkacount++;
6115 }
6116 }
6117
6118 /*
6119 * check MATURE entry to start to send expire message
6120 * whether or not.
6121 */
6122 for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]);
6123 sav != NULL;
6124 sav = nextsav) {
6125 mature_sav_count++;
6126 total_sav_count++;
6127 nextsav = LIST_NEXT(sav, chain);
6128
6129 /* we don't need to check. */
6130 if (sav->lft_s == NULL) {
6131 continue;
6132 }
6133
6134 /* sanity check */
6135 if (sav->lft_c == NULL) {
6136 ipseclog((LOG_DEBUG, "key_timehandler: "
6137 "There is no CURRENT time, why?\n"));
6138 continue;
6139 }
6140
6141 /* check SOFT lifetime */
6142 if (sav->lft_s->sadb_lifetime_addtime != 0) {
6143 const u_int64_t lifetime_addtime = sav->lft_s->sadb_lifetime_addtime * NSEC_PER_SEC;
6144 if (current_time_ns - sav->created > lifetime_addtime) {
6145 /*
6146 * If always_expire is set, expire. Otherwise,
6147 * if the SA has not been used, delete immediately.
6148 */
6149 if (sav->lft_c->sadb_lifetime_usetime == 0
6150 && sav->always_expire == 0) {
6151 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
6152 key_freesav(sav, KEY_SADB_LOCKED);
6153 sav = NULL;
6154 } else if (savexbuf && savexcount < savbufcount) {
6155 key_sa_chgstate(sav, SADB_SASTATE_DYING);
6156 sav->refcnt++;
6157 *savexptr++ = sav;
6158 savexcount++;
6159 }
6160 }
6161 }
6162 /* check SOFT lifetime by bytes */
6163 /*
6164 * XXX I don't know the way to delete this SA
6165 * when new SA is installed. Caution when it's
6166 * installed too big lifetime by time.
6167 */
6168 else if (savexbuf && savexcount < savbufcount
6169 && sav->lft_s->sadb_lifetime_bytes != 0
6170 && sav->lft_s->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) {
6171 /*
6172 * XXX If we keep to send expire
6173 * message in the status of
6174 * DYING. Do remove below code.
6175 */
6176 //key_expire(sav);
6177 key_sa_chgstate(sav, SADB_SASTATE_DYING);
6178 sav->refcnt++;
6179 *savexptr++ = sav;
6180 savexcount++;
6181 }
6182 }
6183
6184 /* check DYING entry to change status to DEAD. */
6185 for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]);
6186 sav != NULL;
6187 sav = nextsav) {
6188 dying_sav_count++;
6189 total_sav_count++;
6190 nextsav = LIST_NEXT(sav, chain);
6191
6192 /* we don't need to check. */
6193 if (sav->lft_h == NULL) {
6194 continue;
6195 }
6196
6197 /* sanity check */
6198 if (sav->lft_c == NULL) {
6199 ipseclog((LOG_DEBUG, "key_timehandler: "
6200 "There is no CURRENT time, why?\n"));
6201 continue;
6202 }
6203
6204 /* check HARD lifetime */
6205 if (sav->lft_h->sadb_lifetime_addtime != 0) {
6206 const u_int64_t lifetime_addtime = sav->lft_h->sadb_lifetime_addtime * NSEC_PER_SEC;
6207 if (current_time_ns - sav->created > lifetime_addtime) {
6208 if (sav->always_expire) {
6209 key_send_delete(sav);
6210 sav = NULL;
6211 } else {
6212 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
6213 key_freesav(sav, KEY_SADB_LOCKED);
6214 sav = NULL;
6215 }
6216 }
6217 }
6218 /* check HARD lifetime by bytes */
6219 else if (sav->lft_h->sadb_lifetime_bytes != 0
6220 && sav->lft_h->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) {
6221 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
6222 key_freesav(sav, KEY_SADB_LOCKED);
6223 sav = NULL;
6224 }
6225 }
6226
6227 /* delete entry in DEAD */
6228 for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]);
6229 sav != NULL;
6230 sav = nextsav) {
6231 dead_sav_count++;
6232 total_sav_count++;
6233 nextsav = LIST_NEXT(sav, chain);
6234
6235 /* sanity check */
6236 if (sav->state != SADB_SASTATE_DEAD) {
6237 ipseclog((LOG_DEBUG, "key_timehandler: "
6238 "invalid sav->state "
6239 "(queue: %d SA: %d): "
6240 "kill it anyway\n",
6241 SADB_SASTATE_DEAD, sav->state));
6242 }
6243
6244 /*
6245 * do not call key_freesav() here.
6246 * sav should already be freed, and sav->refcnt
6247 * shows other references to sav
6248 * (such as from SPD).
6249 */
6250 }
6251 }
6252 }
6253
6254 if (++key_timehandler_debug >= 300) {
6255 if (key_debug_level) {
6256 printf("%s: total stats for %u calls\n", __FUNCTION__, key_timehandler_debug);
6257 printf("%s: walked %u SPDs\n", __FUNCTION__, spd_count);
6258 printf("%s: walked %llu SAs: LARVAL SAs %u, MATURE SAs %u, DYING SAs %u, DEAD SAs %u\n", __FUNCTION__,
6259 total_sav_count, larval_sav_count, mature_sav_count, dying_sav_count, dead_sav_count);
6260 printf("%s: walked %u SAHs: DEAD SAHs %u, EMPTY SAHs %u\n", __FUNCTION__,
6261 sah_count, dead_sah_count, empty_sah_count);
6262 if (sah_search_calls) {
6263 printf("%s: SAH search cost %d iters per call\n", __FUNCTION__,
6264 (sah_search_count / sah_search_calls));
6265 }
6266 }
6267 spd_count = 0;
6268 sah_count = 0;
6269 dead_sah_count = 0;
6270 empty_sah_count = 0;
6271 larval_sav_count = 0;
6272 mature_sav_count = 0;
6273 dying_sav_count = 0;
6274 dead_sav_count = 0;
6275 total_sav_count = 0;
6276 sah_search_count = 0;
6277 sah_search_calls = 0;
6278 key_timehandler_debug = 0;
6279 }
6280
6281 const u_int64_t blockacq_lifetime = (u_int64_t)key_blockacq_lifetime * NSEC_PER_SEC;
6282#ifndef IPSEC_NONBLOCK_ACQUIRE
6283 /* ACQ tree */
6284 {
6285 struct secacq *acq, *nextacq;
6286
6287 for (acq = LIST_FIRST(&acqtree);
6288 acq != NULL;
6289 acq = nextacq) {
6290 stop_handler = 0;
6291 nextacq = LIST_NEXT(acq, chain);
6292
6293 if (current_time_ns - acq->created > blockacq_lifetime
6294 && __LIST_CHAINED(acq)) {
6295 LIST_REMOVE(acq, chain);
6296 kfree_type(struct secacq, acq);
6297 }
6298 }
6299 }
6300#endif
6301
6302 /* SP ACQ tree */
6303 {
6304 struct secspacq *acq, *nextacq;
6305
6306 for (acq = LIST_FIRST(&spacqtree);
6307 acq != NULL;
6308 acq = nextacq) {
6309 stop_handler = 0;
6310 nextacq = LIST_NEXT(acq, chain);
6311
6312 if (current_time_ns - acq->created > blockacq_lifetime
6313 && __LIST_CHAINED(acq)) {
6314 LIST_REMOVE(acq, chain);
6315 struct secacq *secacq_p = (struct secacq *)acq;
6316 kfree_type(struct secacq, secacq_p);
6317 }
6318 }
6319 }
6320
6321 /* initialize random seed */
6322 if (key_tick_init_random++ > key_int_random) {
6323 key_tick_init_random = 0;
6324 key_srandom();
6325 }
6326
6327 uint64_t acc_sleep_time = 0;
6328 absolutetime_to_nanoseconds(abstime: mach_absolutetime_asleep, result: &acc_sleep_time);
6329 natt_now = ++up_time + (acc_sleep_time / NSEC_PER_SEC);
6330
6331 lck_mtx_unlock(sadb_mutex);
6332
6333 /* send messages outside of sadb_mutex */
6334 if (spbuf && spcount > 0) {
6335 cnt = spcount;
6336 while (cnt--) {
6337 key_spdexpire(sp: *(--spptr));
6338 }
6339 }
6340 if (savkabuf && savkacount > 0) {
6341 struct secasvar **savkaptr_sav = savkaptr;
6342 u_int32_t cnt_send = savkacount;
6343
6344 while (cnt_send--) {
6345 if (ipsec_send_natt_keepalive(sav: *(--savkaptr))) {
6346 // <rdar://6768487> iterate (all over again) and update timestamps
6347 struct secasvar **savkaptr_update = savkaptr_sav;
6348 u_int32_t cnt_update = savkacount;
6349 while (cnt_update--) {
6350 key_update_natt_keepalive_timestamp(*savkaptr,
6351 *(--savkaptr_update));
6352 }
6353 }
6354 }
6355 }
6356 if (savexbuf && savexcount > 0) {
6357 cnt = savexcount;
6358 while (cnt--) {
6359 key_expire(*(--savexptr));
6360 }
6361 }
6362
6363 /* decrement ref counts and free buffers */
6364 lck_mtx_lock(sadb_mutex);
6365 if (spbuf) {
6366 while (spcount--) {
6367 key_freesp(sp: *spptr++, KEY_SADB_LOCKED);
6368 }
6369 kfree_type(struct secpolicy *, spbufcount, spbuf);
6370 }
6371 if (savkabuf) {
6372 while (savkacount--) {
6373 key_freesav(sav: *savkaptr++, KEY_SADB_LOCKED);
6374 }
6375 kfree_type(struct secasvar *, savbufcount, savkabuf);
6376 }
6377 if (savexbuf) {
6378 while (savexcount--) {
6379 key_freesav(sav: *savexptr++, KEY_SADB_LOCKED);
6380 }
6381 kfree_type(struct secasvar *, savbufcount, savexbuf);
6382 }
6383
6384 if (stop_handler) {
6385 key_timehandler_running = 0;
6386 /* Turn on the ipsec bypass */
6387 ipsec_bypass = 1;
6388 } else {
6389 /* do exchange to tick time !! */
6390 (void)timeout((void *)key_timehandler, arg: (void *)0, ticks: hz);
6391 }
6392
6393 lck_mtx_unlock(sadb_mutex);
6394 return;
6395}
6396
6397/*
6398 * to initialize a seed for random()
6399 */
6400static void
6401key_srandom(void)
6402{
6403#ifdef __APPLE__
6404 /* Our PRNG is based on Yarrow and doesn't need to be seeded */
6405 random();
6406#else
6407 struct timeval tv;
6408
6409 microtime(&tv);
6410
6411 srandom(tv.tv_usec);
6412#endif
6413
6414 return;
6415}
6416
6417u_int32_t
6418key_random(void)
6419{
6420 u_int32_t value;
6421
6422 key_randomfill(&value, sizeof(value));
6423 return value;
6424}
6425
6426void
6427key_randomfill(
6428 void *p,
6429 size_t l)
6430{
6431#ifdef __APPLE__
6432 cc_rand_generate(out: p, outlen: l);
6433#else
6434 size_t n;
6435 u_int32_t v;
6436 static int warn = 1;
6437
6438 n = 0;
6439 n = (size_t)read_random(p, (u_int)l);
6440 /* last resort */
6441 while (n < l) {
6442 v = random();
6443 bcopy(&v, (u_int8_t *)p + n,
6444 l - n < sizeof(v) ? l - n : sizeof(v));
6445 n += sizeof(v);
6446
6447 if (warn) {
6448 printf("WARNING: pseudo-random number generator "
6449 "used for IPsec processing\n");
6450 warn = 0;
6451 }
6452 }
6453#endif
6454}
6455
6456/*
6457 * map SADB_SATYPE_* to IPPROTO_*.
6458 * if satype == SADB_SATYPE then satype is mapped to ~0.
6459 * OUT:
6460 * 0: invalid satype.
6461 */
6462static u_int8_t
6463key_satype2proto(
6464 u_int8_t satype)
6465{
6466 switch (satype) {
6467 case SADB_SATYPE_UNSPEC:
6468 return IPSEC_PROTO_ANY;
6469 case SADB_SATYPE_AH:
6470 return IPPROTO_AH;
6471 case SADB_SATYPE_ESP:
6472 return IPPROTO_ESP;
6473 default:
6474 return 0;
6475 }
6476 /* NOTREACHED */
6477}
6478
6479/*
6480 * map IPPROTO_* to SADB_SATYPE_*
6481 * OUT:
6482 * 0: invalid protocol type.
6483 */
6484static u_int8_t
6485key_proto2satype(
6486 u_int16_t proto)
6487{
6488 switch (proto) {
6489 case IPPROTO_AH:
6490 return SADB_SATYPE_AH;
6491 case IPPROTO_ESP:
6492 return SADB_SATYPE_ESP;
6493 default:
6494 return 0;
6495 }
6496 /* NOTREACHED */
6497}
6498
6499static ifnet_t
6500key_get_ipsec_if_from_message(const struct sadb_msghdr *mhp, int message_type)
6501{
6502 struct sadb_x_ipsecif *ipsecifopts = NULL;
6503 ifnet_t ipsec_if = NULL;
6504
6505 ipsecifopts = (struct sadb_x_ipsecif *)(void *)mhp->ext[message_type];
6506 if (ipsecifopts != NULL) {
6507 if (ipsecifopts->sadb_x_ipsecif_ipsec_if[0]) {
6508 ipsecifopts->sadb_x_ipsecif_ipsec_if[IFXNAMSIZ - 1] = '\0';
6509 ifnet_find_by_name(ifname: ipsecifopts->sadb_x_ipsecif_ipsec_if, interface: &ipsec_if);
6510 }
6511 }
6512
6513 return ipsec_if;
6514}
6515
6516static u_int
6517key_get_outgoing_ifindex_from_message(const struct sadb_msghdr *mhp, int message_type)
6518{
6519 struct sadb_x_ipsecif *ipsecifopts = NULL;
6520 ifnet_t outgoing_if = NULL;
6521
6522 ipsecifopts = (struct sadb_x_ipsecif *)(void *)mhp->ext[message_type];
6523 if (ipsecifopts != NULL) {
6524 if (ipsecifopts->sadb_x_ipsecif_outgoing_if[0]) {
6525 ipsecifopts->sadb_x_ipsecif_outgoing_if[IFXNAMSIZ - 1] = '\0';
6526 ifnet_find_by_name(ifname: ipsecifopts->sadb_x_ipsecif_outgoing_if, interface: &outgoing_if);
6527 }
6528 }
6529
6530 u_int outgoing_if_index = 0;
6531 if (outgoing_if != NULL) {
6532 outgoing_if_index = outgoing_if->if_index;
6533 ifnet_release(interface: outgoing_if);
6534 }
6535
6536 return outgoing_if_index;
6537}
6538
6539/* %%% PF_KEY */
6540/*
6541 * SADB_GETSPI processing is to receive
6542 * <base, (SA2), src address, dst address, (SPI range)>
6543 * from the IKMPd, to assign a unique spi value, to hang on the INBOUND
6544 * tree with the status of LARVAL, and send
6545 * <base, SA(*), address(SD)>
6546 * to the IKMPd.
6547 *
6548 * IN: mhp: pointer to the pointer to each header.
6549 * OUT: NULL if fail.
6550 * other if success, return pointer to the message to send.
6551 */
6552static int
6553key_getspi(
6554 struct socket *so,
6555 struct mbuf *m,
6556 const struct sadb_msghdr *mhp)
6557{
6558 struct sadb_address *src0, *dst0;
6559 struct secasindex saidx;
6560 struct secashead *newsah;
6561 struct secasvar *newsav;
6562 ifnet_t ipsec_if = NULL;
6563 u_int8_t proto;
6564 u_int32_t spi;
6565 u_int8_t mode;
6566 u_int32_t reqid;
6567 int error;
6568
6569 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
6570
6571 /* sanity check */
6572 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
6573 panic("key_getspi: NULL pointer is passed.");
6574 }
6575
6576 if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
6577 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
6578 ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n"));
6579 return key_senderror(so, m, EINVAL);
6580 }
6581 if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
6582 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
6583 ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n"));
6584 return key_senderror(so, m, EINVAL);
6585 }
6586 if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
6587 mode = ((struct sadb_x_sa2 *)
6588 (void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
6589 reqid = ((struct sadb_x_sa2 *)
6590 (void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid;
6591 } else {
6592 mode = IPSEC_MODE_ANY;
6593 reqid = 0;
6594 }
6595
6596 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
6597 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
6598
6599 /* map satype to proto */
6600 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
6601 ipseclog((LOG_DEBUG, "key_getspi: invalid satype is passed.\n"));
6602 return key_senderror(so, m, EINVAL);
6603 }
6604
6605 /* make sure if port number is zero. */
6606 switch (((struct sockaddr *)(src0 + 1))->sa_family) {
6607 case AF_INET:
6608 if (((struct sockaddr *)(src0 + 1))->sa_len !=
6609 sizeof(struct sockaddr_in)) {
6610 return key_senderror(so, m, EINVAL);
6611 }
6612 ((struct sockaddr_in *)(void *)(src0 + 1))->sin_port = 0;
6613 break;
6614 case AF_INET6:
6615 if (((struct sockaddr *)(src0 + 1))->sa_len !=
6616 sizeof(struct sockaddr_in6)) {
6617 return key_senderror(so, m, EINVAL);
6618 }
6619 ((struct sockaddr_in6 *)(void *)(src0 + 1))->sin6_port = 0;
6620 break;
6621 default:
6622 ; /*???*/
6623 }
6624 switch (((struct sockaddr *)(dst0 + 1))->sa_family) {
6625 case AF_INET:
6626 if (((struct sockaddr *)(dst0 + 1))->sa_len !=
6627 sizeof(struct sockaddr_in)) {
6628 return key_senderror(so, m, EINVAL);
6629 }
6630 ((struct sockaddr_in *)(void *)(dst0 + 1))->sin_port = 0;
6631 break;
6632 case AF_INET6:
6633 if (((struct sockaddr *)(dst0 + 1))->sa_len !=
6634 sizeof(struct sockaddr_in6)) {
6635 return key_senderror(so, m, EINVAL);
6636 }
6637 ((struct sockaddr_in6 *)(void *)(dst0 + 1))->sin6_port = 0;
6638 break;
6639 default:
6640 ; /*???*/
6641 }
6642
6643 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
6644
6645 /* XXX boundary check against sa_len */
6646 KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, ipsec_if ? ipsec_if->if_index : 0, &saidx);
6647
6648 lck_mtx_lock(sadb_mutex);
6649
6650 /* SPI allocation */
6651 spi = key_do_getnewspi((struct sadb_spirange *)
6652 (void *)mhp->ext[SADB_EXT_SPIRANGE], &saidx);
6653 if (spi == 0) {
6654 lck_mtx_unlock(sadb_mutex);
6655 if (ipsec_if != NULL) {
6656 ifnet_release(interface: ipsec_if);
6657 }
6658 return key_senderror(so, m, EINVAL);
6659 }
6660
6661 /* get a SA index */
6662 if ((newsah = key_getsah(saidx: &saidx, SECURITY_ASSOCIATION_ANY)) == NULL) {
6663 /* create a new SA index: key_addspi is always used for inbound spi */
6664 if ((newsah = key_newsah(saidx: &saidx, ipsec_if, outgoing_if: key_get_outgoing_ifindex_from_message(mhp, SADB_X_EXT_IPSECIF), IPSEC_DIR_INBOUND, SECURITY_ASSOCIATION_PFKEY)) == NULL) {
6665 lck_mtx_unlock(sadb_mutex);
6666 if (ipsec_if != NULL) {
6667 ifnet_release(interface: ipsec_if);
6668 }
6669 ipseclog((LOG_DEBUG, "key_getspi: No more memory.\n"));
6670 return key_senderror(so, m, ENOBUFS);
6671 }
6672 }
6673
6674 if (ipsec_if != NULL) {
6675 ifnet_release(interface: ipsec_if);
6676 ipsec_if = NULL;
6677 }
6678
6679 // Increment use count, since key_newsav() could release sadb_mutex lock
6680 newsah->use_count++;
6681
6682 if ((newsah->flags & SECURITY_ASSOCIATION_CUSTOM_IPSEC) == SECURITY_ASSOCIATION_CUSTOM_IPSEC) {
6683 newsah->use_count--;
6684 lck_mtx_unlock(sadb_mutex);
6685 ipseclog((LOG_ERR, "key_getspi: custom ipsec exists\n"));
6686 return key_senderror(so, m, EEXIST);
6687 }
6688
6689 /* get a new SA */
6690 /* XXX rewrite */
6691 newsav = key_newsav(m, mhp, sah: newsah, errp: &error, so);
6692 if (newsav == NULL) {
6693 /* XXX don't free new SA index allocated in above. */
6694 newsah->use_count--;
6695 lck_mtx_unlock(sadb_mutex);
6696 return key_senderror(so, m, error);
6697 }
6698
6699 if (newsah->state == SADB_SASTATE_DEAD) {
6700 newsah->use_count--;
6701 key_sa_chgstate(newsav, SADB_SASTATE_DEAD);
6702 key_freesav(sav: newsav, KEY_SADB_LOCKED);
6703 lck_mtx_unlock(sadb_mutex);
6704 ipseclog((LOG_ERR, "key_getspi: security association head is dead\n"));
6705 return key_senderror(so, m, EINVAL);
6706 }
6707
6708 /* set spi */
6709 key_setspi(sav: newsav, htonl(spi));
6710
6711#ifndef IPSEC_NONBLOCK_ACQUIRE
6712 /* delete the entry in acqtree */
6713 if (mhp->msg->sadb_msg_seq != 0) {
6714 struct secacq *acq;
6715 if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) != NULL) {
6716 /* reset counter in order to deletion by timehandler. */
6717 acq->created = key_get_continuous_time_ns();
6718 acq->count = 0;
6719 }
6720 }
6721#endif
6722 newsah->use_count--;
6723 u_int32_t newsav_seq = newsav->seq;
6724 lck_mtx_unlock(sadb_mutex);
6725
6726 {
6727 struct mbuf *n, *nn;
6728 struct sadb_sa *m_sa;
6729 struct sadb_msg *newmsg;
6730 int off, len;
6731
6732 /* create new sadb_msg to reply. */
6733 len = PFKEY_ALIGN8(sizeof(struct sadb_msg)) +
6734 PFKEY_ALIGN8(sizeof(struct sadb_sa));
6735 if (len > MCLBYTES) {
6736 return key_senderror(so, m, ENOBUFS);
6737 }
6738
6739 MGETHDR(n, M_WAITOK, MT_DATA);
6740 if (n && len > MHLEN) {
6741 MCLGET(n, M_WAITOK);
6742 if ((n->m_flags & M_EXT) == 0) {
6743 m_freem(n);
6744 n = NULL;
6745 }
6746 }
6747 if (!n) {
6748 return key_senderror(so, m, ENOBUFS);
6749 }
6750
6751 n->m_len = len;
6752 n->m_next = NULL;
6753 off = 0;
6754
6755 m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off);
6756 off += PFKEY_ALIGN8(sizeof(struct sadb_msg));
6757
6758 m_sa = (struct sadb_sa *)(void *)(mtod(n, caddr_t) + off);
6759 memset(s: m_sa, c: 0, PFKEY_ALIGN8(sizeof(struct sadb_sa)));
6760 m_sa->sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa));
6761 m_sa->sadb_sa_exttype = SADB_EXT_SA;
6762 m_sa->sadb_sa_spi = htonl(spi);
6763 off += PFKEY_ALIGN8(sizeof(struct sadb_sa));
6764
6765#if DIAGNOSTIC
6766 if (off != len) {
6767 panic("length inconsistency in key_getspi");
6768 }
6769#endif
6770 {
6771 int mbufItems[] = {SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST};
6772 n->m_next = key_gather_mbuf(m, mhp, ndeep: 0, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
6773 if (!n->m_next) {
6774 m_freem(n);
6775 return key_senderror(so, m, ENOBUFS);
6776 }
6777 }
6778
6779 if (n->m_len < sizeof(struct sadb_msg)) {
6780 n = m_pullup(n, sizeof(struct sadb_msg));
6781 if (n == NULL) {
6782 return key_sendup_mbuf(so, m, KEY_SENDUP_ONE);
6783 }
6784 }
6785
6786 n->m_pkthdr.len = 0;
6787 for (nn = n; nn; nn = nn->m_next) {
6788 n->m_pkthdr.len += nn->m_len;
6789 }
6790
6791 newmsg = mtod(n, struct sadb_msg *);
6792 newmsg->sadb_msg_seq = newsav_seq;
6793 newmsg->sadb_msg_errno = 0;
6794 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
6795 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
6796
6797 m_freem(m);
6798 return key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
6799 }
6800}
6801
6802/*
6803 * allocating new SPI
6804 * called by key_getspi().
6805 * OUT:
6806 * 0: failure.
6807 * others: success.
6808 */
6809static u_int32_t
6810key_do_getnewspi(
6811 struct sadb_spirange *spirange,
6812 struct secasindex *saidx)
6813{
6814 u_int32_t newspi;
6815 u_int32_t keymin, keymax;
6816 int count = key_spi_trycnt;
6817
6818 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
6819
6820 /* set spi range to allocate */
6821 if (spirange != NULL) {
6822 keymin = spirange->sadb_spirange_min;
6823 keymax = spirange->sadb_spirange_max;
6824 } else {
6825 keymin = key_spi_minval;
6826 keymax = key_spi_maxval;
6827 }
6828 if (keymin == keymax) {
6829 if (key_checkspidup(saidx, spi: keymin) != NULL) {
6830 ipseclog((LOG_DEBUG, "key_do_getnewspi: SPI %u exists already.\n", keymin));
6831 return 0;
6832 }
6833
6834 count--; /* taking one cost. */
6835 newspi = keymin;
6836 } else {
6837 u_int32_t range = keymax - keymin + 1; /* overflow value of zero means full range */
6838
6839 /* init SPI */
6840 newspi = 0;
6841
6842 /* when requesting to allocate spi ranged */
6843 while (count--) {
6844 u_int32_t rand_val = key_random();
6845
6846 /* generate pseudo-random SPI value ranged. */
6847 newspi = (range == 0 ? rand_val : keymin + (rand_val % range));
6848
6849 if (key_checkspidup(saidx, spi: newspi) == NULL) {
6850 break;
6851 }
6852 }
6853
6854 if (count == 0 || newspi == 0) {
6855 ipseclog((LOG_DEBUG, "key_do_getnewspi: to allocate spi is failed.\n"));
6856 return 0;
6857 }
6858 }
6859
6860 /* statistics */
6861 keystat.getspi_count =
6862 (keystat.getspi_count + key_spi_trycnt - count) / 2;
6863
6864 return newspi;
6865}
6866
6867/*
6868 * SADB_UPDATE processing
6869 * receive
6870 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
6871 * key(AE), (identity(SD),) (sensitivity)>
6872 * from the ikmpd, and update a secasvar entry whose status is SADB_SASTATE_LARVAL.
6873 * and send
6874 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
6875 * (identity(SD),) (sensitivity)>
6876 * to the ikmpd.
6877 *
6878 * m will always be freed.
6879 */
6880static int
6881key_update(
6882 struct socket *so,
6883 struct mbuf *m,
6884 const struct sadb_msghdr *mhp)
6885{
6886 struct sadb_sa *sa0 = NULL;
6887 struct sadb_address *src0 = NULL, *dst0 = NULL;
6888 ifnet_t ipsec_if = NULL;
6889 struct secasindex saidx;
6890 struct secashead *sah = NULL;
6891 struct secasvar *sav = NULL;
6892 u_int8_t proto;
6893 u_int8_t mode;
6894 u_int32_t reqid;
6895 u_int16_t flags2;
6896 int error;
6897
6898 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
6899
6900 /* sanity check */
6901 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
6902 panic("key_update: NULL pointer is passed.");
6903 }
6904
6905 /* map satype to proto */
6906 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
6907 ipseclog((LOG_DEBUG, "key_update: invalid satype is passed.\n"));
6908 bzero_keys(mhp);
6909 return key_senderror(so, m, EINVAL);
6910 }
6911
6912 if (mhp->ext[SADB_EXT_SA] == NULL ||
6913 mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
6914 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
6915 (mhp->msg->sadb_msg_satype == SADB_SATYPE_ESP &&
6916 mhp->ext[SADB_EXT_KEY_ENCRYPT] == NULL) ||
6917 (mhp->msg->sadb_msg_satype == SADB_SATYPE_AH &&
6918 mhp->ext[SADB_EXT_KEY_AUTH] == NULL) ||
6919 (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL &&
6920 mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) ||
6921 (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL &&
6922 mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) {
6923 ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n"));
6924 bzero_keys(mhp);
6925 return key_senderror(so, m, EINVAL);
6926 }
6927 if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
6928 mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
6929 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
6930 ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n"));
6931 bzero_keys(mhp);
6932 return key_senderror(so, m, EINVAL);
6933 }
6934 if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
6935 mode = ((struct sadb_x_sa2 *)
6936 (void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
6937 reqid = ((struct sadb_x_sa2 *)
6938 (void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid;
6939 flags2 = ((struct sadb_x_sa2 *)(void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_flags;
6940 } else {
6941 mode = IPSEC_MODE_ANY;
6942 reqid = 0;
6943 flags2 = 0;
6944 }
6945 /* XXX boundary checking for other extensions */
6946
6947 sa0 = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
6948 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
6949 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
6950 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
6951
6952 u_int ipsec_if_index = 0;
6953 if (ipsec_if != NULL) {
6954 ipsec_if_index = ipsec_if->if_index;
6955 ifnet_release(interface: ipsec_if);
6956 ipsec_if = NULL;
6957 }
6958
6959 /* XXX boundary check against sa_len */
6960 KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, ipsec_if_index, &saidx);
6961
6962 lck_mtx_lock(sadb_mutex);
6963
6964 /* get a SA header */
6965 if ((sah = key_getsah(saidx: &saidx, SECURITY_ASSOCIATION_PFKEY)) == NULL) {
6966 lck_mtx_unlock(sadb_mutex);
6967 ipseclog((LOG_DEBUG, "key_update: no SA index found.\n"));
6968 bzero_keys(mhp);
6969 return key_senderror(so, m, ENOENT);
6970 }
6971
6972 // Increment use count, since key_setsaval() could release sadb_mutex lock
6973 sah->use_count++;
6974
6975 if ((sav = key_getsavbyspi(sah, spi: sa0->sadb_sa_spi)) == NULL) {
6976 ipseclog((LOG_DEBUG,
6977 "key_update: no such a SA found (spi:%u)\n",
6978 (u_int32_t)ntohl(sa0->sadb_sa_spi)));
6979 error = EINVAL;
6980 goto fail;
6981 }
6982
6983 // Increment reference count, since key_setsaval() could release sadb_mutex lock
6984 sav->refcnt++;
6985
6986 /* validity check */
6987 if (sav->sah->saidx.proto != proto) {
6988 ipseclog((LOG_DEBUG,
6989 "key_update: protocol mismatched (DB=%u param=%u)\n",
6990 sav->sah->saidx.proto, proto));
6991 error = EINVAL;
6992 goto fail;
6993 }
6994
6995 if (sav->pid != mhp->msg->sadb_msg_pid) {
6996 ipseclog((LOG_DEBUG,
6997 "key_update: pid mismatched (DB:%u param:%u)\n",
6998 sav->pid, mhp->msg->sadb_msg_pid));
6999 error = EINVAL;
7000 goto fail;
7001 }
7002
7003 /* copy sav values */
7004 sav->flags2 = flags2;
7005 if (flags2 & SADB_X_EXT_SA2_DELETE_ON_DETACH) {
7006 sav->so = so;
7007 }
7008
7009 error = key_setsaval(sav, m, mhp);
7010 if (error) {
7011 goto fail;
7012 }
7013
7014 if (sah->state == SADB_SASTATE_DEAD) {
7015 ipseclog((LOG_ERR,
7016 "key_update: security association head is dead\n"));
7017 error = EINVAL;
7018 goto fail;
7019 }
7020
7021 /*
7022 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
7023 * this SA is for transport mode - otherwise clear it.
7024 */
7025 if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0 &&
7026 (sav->sah->saidx.mode != IPSEC_MODE_TRANSPORT ||
7027 sav->sah->saidx.src.ss_family != AF_INET)) {
7028 sav->flags &= ~SADB_X_EXT_NATT_MULTIPLEUSERS;
7029 }
7030
7031 /* check SA values to be mature. */
7032 if ((error = key_mature(sav)) != 0) {
7033 goto fail;
7034 }
7035
7036 key_freesav(sav, KEY_SADB_LOCKED);
7037 sah->use_count--;
7038 lck_mtx_unlock(sadb_mutex);
7039
7040 {
7041 struct mbuf *n;
7042
7043 /* set msg buf from mhp */
7044 n = key_getmsgbuf_x1(m, mhp);
7045 if (n == NULL) {
7046 ipseclog((LOG_DEBUG, "key_update: No more memory.\n"));
7047 return key_senderror(so, m, ENOBUFS);
7048 }
7049
7050 bzero_keys(mhp);
7051 m_freem(m);
7052 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
7053 }
7054fail:
7055 if (sav != NULL) {
7056 key_freesav(sav, KEY_SADB_LOCKED);
7057 }
7058 if (sah != NULL) {
7059 sah->use_count--;
7060 }
7061
7062 lck_mtx_unlock(sadb_mutex);
7063 bzero_keys(mhp);
7064 return key_senderror(so, m, error);
7065}
7066
7067static int
7068key_migrate(struct socket *so,
7069 struct mbuf *m,
7070 const struct sadb_msghdr *mhp)
7071{
7072 struct sadb_sa *sa0 = NULL;
7073 struct sadb_address *src0 = NULL;
7074 struct sadb_address *dst0 = NULL;
7075 struct sadb_address *src1 = NULL;
7076 struct sadb_address *dst1 = NULL;
7077 ifnet_t ipsec_if0 = NULL;
7078 ifnet_t ipsec_if1 = NULL;
7079 struct secasindex saidx0;
7080 struct secasindex saidx1;
7081 struct secashead *sah = NULL;
7082 struct secashead *newsah = NULL;
7083 struct secasvar *sav = NULL;
7084 u_int8_t proto;
7085
7086 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
7087
7088 /* sanity check */
7089 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
7090 panic("key_migrate: NULL pointer is passed.");
7091 }
7092
7093 /* map satype to proto */
7094 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
7095 ipseclog((LOG_DEBUG, "key_migrate: invalid satype is passed.\n"));
7096 return key_senderror(so, m, EINVAL);
7097 }
7098
7099 if (mhp->ext[SADB_EXT_SA] == NULL ||
7100 mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
7101 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
7102 mhp->ext[SADB_EXT_MIGRATE_ADDRESS_SRC] == NULL ||
7103 mhp->ext[SADB_EXT_MIGRATE_ADDRESS_DST] == NULL) {
7104 ipseclog((LOG_DEBUG, "key_migrate: invalid message is passed.\n"));
7105 return key_senderror(so, m, EINVAL);
7106 }
7107
7108 if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
7109 mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
7110 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) ||
7111 mhp->extlen[SADB_EXT_MIGRATE_ADDRESS_SRC] < sizeof(struct sadb_address) ||
7112 mhp->extlen[SADB_EXT_MIGRATE_ADDRESS_DST] < sizeof(struct sadb_address)) {
7113 ipseclog((LOG_DEBUG, "key_migrate: invalid message is passed.\n"));
7114 return key_senderror(so, m, EINVAL);
7115 }
7116
7117 lck_mtx_lock(sadb_mutex);
7118
7119 sa0 = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
7120 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
7121 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
7122 src1 = (struct sadb_address *)(mhp->ext[SADB_EXT_MIGRATE_ADDRESS_SRC]);
7123 dst1 = (struct sadb_address *)(mhp->ext[SADB_EXT_MIGRATE_ADDRESS_DST]);
7124 ipsec_if0 = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
7125 ipsec_if1 = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_MIGRATE_IPSECIF);
7126
7127 u_int ipsec_if0_index = 0;
7128 if (ipsec_if0 != NULL) {
7129 ipsec_if0_index = ipsec_if0->if_index;
7130 ifnet_release(interface: ipsec_if0);
7131 ipsec_if0 = NULL;
7132 }
7133
7134 /* Find existing SAH and SAV */
7135 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, ipsec_if0_index, &saidx0);
7136
7137 LIST_FOREACH(sah, &sahtree, chain) {
7138 if (sah->state != SADB_SASTATE_MATURE) {
7139 continue;
7140 }
7141 if (key_cmpsaidx(saidx0: &sah->saidx, saidx1: &saidx0, CMP_HEAD) == 0) {
7142 continue;
7143 }
7144
7145 sav = key_getsavbyspi(sah, spi: sa0->sadb_sa_spi);
7146 if (sav && sav->state == SADB_SASTATE_MATURE) {
7147 break;
7148 }
7149 }
7150 if (sah == NULL) {
7151 lck_mtx_unlock(sadb_mutex);
7152 if (ipsec_if1 != NULL) {
7153 ifnet_release(interface: ipsec_if1);
7154 }
7155 ipseclog((LOG_DEBUG, "key_migrate: no mature SAH found.\n"));
7156 return key_senderror(so, m, ENOENT);
7157 }
7158
7159 if (sav == NULL) {
7160 lck_mtx_unlock(sadb_mutex);
7161 if (ipsec_if1 != NULL) {
7162 ifnet_release(interface: ipsec_if1);
7163 }
7164 ipseclog((LOG_DEBUG, "key_migrate: no SA found.\n"));
7165 return key_senderror(so, m, ENOENT);
7166 }
7167
7168 /* Find or create new SAH */
7169 KEY_SETSECASIDX(proto, sah->saidx.mode, sah->saidx.reqid, src1 + 1, dst1 + 1, ipsec_if1 ? ipsec_if1->if_index : 0, &saidx1);
7170
7171 if ((newsah = key_getsah(saidx: &saidx1, SECURITY_ASSOCIATION_ANY)) == NULL) {
7172 if ((newsah = key_newsah(saidx: &saidx1, ipsec_if: ipsec_if1, outgoing_if: key_get_outgoing_ifindex_from_message(mhp, SADB_X_EXT_MIGRATE_IPSECIF), dir: sah->dir, SECURITY_ASSOCIATION_PFKEY)) == NULL) {
7173 lck_mtx_unlock(sadb_mutex);
7174 if (ipsec_if1 != NULL) {
7175 ifnet_release(interface: ipsec_if1);
7176 }
7177 ipseclog((LOG_DEBUG, "key_migrate: No more memory.\n"));
7178 return key_senderror(so, m, ENOBUFS);
7179 }
7180 }
7181
7182 if (ipsec_if1 != NULL) {
7183 ifnet_release(interface: ipsec_if1);
7184 ipsec_if1 = NULL;
7185 }
7186
7187 if ((newsah->flags & SECURITY_ASSOCIATION_CUSTOM_IPSEC) == SECURITY_ASSOCIATION_CUSTOM_IPSEC) {
7188 lck_mtx_unlock(sadb_mutex);
7189 ipseclog((LOG_ERR, "key_migrate: custom ipsec exists\n"));
7190 return key_senderror(so, m, EEXIST);
7191 }
7192
7193 /* Migrate SAV in to new SAH */
7194 if (key_migratesav(sav, newsah) != 0) {
7195 lck_mtx_unlock(sadb_mutex);
7196 ipseclog((LOG_DEBUG, "key_migrate: Failed to migrate SA to new SAH.\n"));
7197 return key_senderror(so, m, EINVAL);
7198 }
7199
7200 /* Reset NAT values */
7201 sav->flags = sa0->sadb_sa_flags;
7202 sav->natt_encapsulated_src_port = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_src_port;
7203 sav->remote_ike_port = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_port;
7204 sav->natt_interval = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_interval;
7205 sav->natt_offload_interval = ((const struct sadb_sa_2*)(sa0))->sadb_sa_natt_offload_interval;
7206 sav->natt_last_activity = natt_now;
7207
7208 /*
7209 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
7210 * SADB_X_EXT_NATT is set and SADB_X_EXT_NATT_KEEPALIVE is not
7211 * set (we're not behind nat) - otherwise clear it.
7212 */
7213 if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0) {
7214 if ((sav->flags & SADB_X_EXT_NATT) == 0 ||
7215 (sav->flags & SADB_X_EXT_NATT_KEEPALIVE) != 0) {
7216 sav->flags &= ~SADB_X_EXT_NATT_MULTIPLEUSERS;
7217 }
7218 }
7219
7220 lck_mtx_unlock(sadb_mutex);
7221 {
7222 struct mbuf *n;
7223 struct sadb_msg *newmsg;
7224 int mbufItems[] = {SADB_EXT_RESERVED, SADB_EXT_SA,
7225 SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST, SADB_X_EXT_IPSECIF,
7226 SADB_EXT_MIGRATE_ADDRESS_SRC, SADB_EXT_MIGRATE_ADDRESS_DST, SADB_X_EXT_MIGRATE_IPSECIF};
7227
7228 /* create new sadb_msg to reply. */
7229 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
7230 if (!n) {
7231 return key_senderror(so, m, ENOBUFS);
7232 }
7233
7234 if (n->m_len < sizeof(struct sadb_msg)) {
7235 n = m_pullup(n, sizeof(struct sadb_msg));
7236 if (n == NULL) {
7237 return key_senderror(so, m, ENOBUFS);
7238 }
7239 }
7240 newmsg = mtod(n, struct sadb_msg *);
7241 newmsg->sadb_msg_errno = 0;
7242 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
7243 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
7244
7245 m_freem(m);
7246 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
7247 }
7248}
7249
7250/*
7251 * SADB_ADD processing
7252 * add a entry to SA database, when received
7253 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
7254 * key(AE), (identity(SD),) (sensitivity)>
7255 * from the ikmpd,
7256 * and send
7257 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
7258 * (identity(SD),) (sensitivity)>
7259 * to the ikmpd.
7260 *
7261 * IGNORE identity and sensitivity messages.
7262 *
7263 * m will always be freed.
7264 */
7265static int
7266key_add(
7267 struct socket *so,
7268 struct mbuf *m,
7269 const struct sadb_msghdr *mhp)
7270{
7271 struct sadb_sa *sa0 = NULL;
7272 struct sadb_address *src0 = NULL, *dst0 = NULL;
7273 ifnet_t ipsec_if = NULL;
7274 struct secasindex saidx;
7275 struct secashead *newsah = NULL;
7276 struct secasvar *newsav = NULL;
7277 u_int8_t proto;
7278 u_int8_t mode;
7279 u_int32_t reqid;
7280 int error;
7281
7282 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
7283
7284 /* sanity check */
7285 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
7286 panic("key_add: NULL pointer is passed.");
7287 }
7288
7289 /* map satype to proto */
7290 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
7291 ipseclog((LOG_DEBUG, "key_add: invalid satype is passed.\n"));
7292 bzero_keys(mhp);
7293 return key_senderror(so, m, EINVAL);
7294 }
7295
7296 if (mhp->ext[SADB_EXT_SA] == NULL ||
7297 mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
7298 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
7299 (mhp->msg->sadb_msg_satype == SADB_SATYPE_ESP &&
7300 mhp->ext[SADB_EXT_KEY_ENCRYPT] == NULL) ||
7301 (mhp->msg->sadb_msg_satype == SADB_SATYPE_AH &&
7302 mhp->ext[SADB_EXT_KEY_AUTH] == NULL) ||
7303 (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL &&
7304 mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) ||
7305 (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL &&
7306 mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) {
7307 ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n"));
7308 bzero_keys(mhp);
7309 return key_senderror(so, m, EINVAL);
7310 }
7311 if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
7312 mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
7313 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
7314 /* XXX need more */
7315 ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n"));
7316 bzero_keys(mhp);
7317 return key_senderror(so, m, EINVAL);
7318 }
7319 if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
7320 mode = ((struct sadb_x_sa2 *)
7321 (void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
7322 reqid = ((struct sadb_x_sa2 *)
7323 (void *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid;
7324 } else {
7325 mode = IPSEC_MODE_ANY;
7326 reqid = 0;
7327 }
7328
7329 sa0 = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
7330 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
7331 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
7332 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
7333
7334 /* XXX boundary check against sa_len */
7335 KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, ipsec_if ? ipsec_if->if_index : 0, &saidx);
7336
7337 lck_mtx_lock(sadb_mutex);
7338
7339 /* get a SA header */
7340 if ((newsah = key_getsah(saidx: &saidx, SECURITY_ASSOCIATION_ANY)) == NULL) {
7341 /* create a new SA header: key_addspi is always used for outbound spi */
7342 if ((newsah = key_newsah(saidx: &saidx, ipsec_if, outgoing_if: key_get_outgoing_ifindex_from_message(mhp, SADB_X_EXT_IPSECIF), IPSEC_DIR_OUTBOUND, SECURITY_ASSOCIATION_PFKEY)) == NULL) {
7343 ipseclog((LOG_DEBUG, "key_add: No more memory.\n"));
7344 error = ENOBUFS;
7345 goto fail;
7346 }
7347 }
7348
7349 if (ipsec_if != NULL) {
7350 ifnet_release(interface: ipsec_if);
7351 ipsec_if = NULL;
7352 }
7353
7354 // Increment use count, since key_newsav() could release sadb_mutex lock
7355 newsah->use_count++;
7356
7357 if ((newsah->flags & SECURITY_ASSOCIATION_CUSTOM_IPSEC) == SECURITY_ASSOCIATION_CUSTOM_IPSEC) {
7358 ipseclog((LOG_ERR, "key_add: custom ipsec exists\n"));
7359 error = EEXIST;
7360 goto fail;
7361 }
7362
7363 /* create new SA entry. */
7364 /* We can create new SA only if SPI is different. */
7365 if (key_getsavbyspi(sah: newsah, spi: sa0->sadb_sa_spi)) {
7366 ipseclog((LOG_DEBUG, "key_add: SA already exists.\n"));
7367 error = EEXIST;
7368 goto fail;
7369 }
7370 newsav = key_newsav(m, mhp, sah: newsah, errp: &error, so);
7371 if (newsav == NULL) {
7372 goto fail;
7373 }
7374
7375 if (newsah->state == SADB_SASTATE_DEAD) {
7376 ipseclog((LOG_ERR, "key_add: security association head is dead\n"));
7377 error = EINVAL;
7378 goto fail;
7379 }
7380
7381 /*
7382 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
7383 * this SA is for transport mode - otherwise clear it.
7384 */
7385 if ((newsav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0 &&
7386 (newsah->saidx.mode != IPSEC_MODE_TRANSPORT ||
7387 newsah->saidx.dst.ss_family != AF_INET)) {
7388 newsav->flags &= ~SADB_X_EXT_NATT_MULTIPLEUSERS;
7389 }
7390
7391 /* check SA values to be mature. */
7392 if ((error = key_mature(sav: newsav)) != 0) {
7393 goto fail;
7394 }
7395
7396 key_get_flowid(sav: newsav);
7397
7398 newsah->use_count--;
7399 lck_mtx_unlock(sadb_mutex);
7400
7401 /*
7402 * don't call key_freesav() here, as we would like to keep the SA
7403 * in the database on success.
7404 */
7405
7406 {
7407 struct mbuf *n;
7408
7409 /* set msg buf from mhp */
7410 n = key_getmsgbuf_x1(m, mhp);
7411 if (n == NULL) {
7412 ipseclog((LOG_DEBUG, "key_update: No more memory.\n"));
7413 bzero_keys(mhp);
7414 return key_senderror(so, m, ENOBUFS);
7415 }
7416
7417 // mh.ext points to the mbuf content.
7418 // Zero out Encryption and Integrity keys if present.
7419 bzero_keys(mhp);
7420 m_freem(m);
7421 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
7422 }
7423fail:
7424 if (newsav != NULL) {
7425 key_sa_chgstate(newsav, SADB_SASTATE_DEAD);
7426 key_freesav(sav: newsav, KEY_SADB_LOCKED);
7427 }
7428 if (newsah != NULL) {
7429 newsah->use_count--;
7430 }
7431 lck_mtx_unlock(sadb_mutex);
7432 if (ipsec_if != NULL) {
7433 ifnet_release(interface: ipsec_if);
7434 }
7435 bzero_keys(mhp);
7436 return key_senderror(so, m, error);
7437}
7438
7439/*
7440 * m will not be freed on return.
7441 * it is caller's responsibility to free the result.
7442 */
7443static struct mbuf *
7444key_getmsgbuf_x1(
7445 struct mbuf *m,
7446 const struct sadb_msghdr *mhp)
7447{
7448 struct mbuf *n;
7449 int mbufItems[] = {SADB_EXT_RESERVED, SADB_EXT_SA,
7450 SADB_X_EXT_SA2, SADB_EXT_ADDRESS_SRC,
7451 SADB_EXT_ADDRESS_DST, SADB_EXT_LIFETIME_HARD,
7452 SADB_EXT_LIFETIME_SOFT, SADB_EXT_IDENTITY_SRC,
7453 SADB_EXT_IDENTITY_DST};
7454
7455 /* sanity check */
7456 if (m == NULL || mhp == NULL || mhp->msg == NULL) {
7457 panic("key_getmsgbuf_x1: NULL pointer is passed.");
7458 }
7459
7460 /* create new sadb_msg to reply. */
7461 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
7462 if (!n) {
7463 return NULL;
7464 }
7465
7466 if (n->m_len < sizeof(struct sadb_msg)) {
7467 n = m_pullup(n, sizeof(struct sadb_msg));
7468 if (n == NULL) {
7469 return NULL;
7470 }
7471 }
7472 mtod(n, struct sadb_msg *)->sadb_msg_errno = 0;
7473 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
7474 mtod(n, struct sadb_msg *)->sadb_msg_len =
7475 (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
7476
7477 return n;
7478}
7479
7480static int key_delete_all(struct socket *, struct mbuf *,
7481 const struct sadb_msghdr *, u_int16_t);
7482
7483/*
7484 * SADB_DELETE processing
7485 * receive
7486 * <base, SA(*), address(SD)>
7487 * from the ikmpd, and set SADB_SASTATE_DEAD,
7488 * and send,
7489 * <base, SA(*), address(SD)>
7490 * to the ikmpd.
7491 *
7492 * m will always be freed.
7493 */
7494static int
7495key_delete(
7496 struct socket *so,
7497 struct mbuf *m,
7498 const struct sadb_msghdr *mhp)
7499{
7500 struct sadb_sa *sa0;
7501 struct sadb_address *src0, *dst0;
7502 ifnet_t ipsec_if = NULL;
7503 struct secasindex saidx;
7504 struct secashead *sah;
7505 struct secasvar *sav = NULL;
7506 u_int16_t proto;
7507
7508 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
7509
7510 /* sanity check */
7511 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
7512 panic("key_delete: NULL pointer is passed.");
7513 }
7514
7515 /* map satype to proto */
7516 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
7517 ipseclog((LOG_DEBUG, "key_delete: invalid satype is passed.\n"));
7518 return key_senderror(so, m, EINVAL);
7519 }
7520
7521 if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
7522 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
7523 ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n"));
7524 return key_senderror(so, m, EINVAL);
7525 }
7526
7527 if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
7528 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
7529 ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n"));
7530 return key_senderror(so, m, EINVAL);
7531 }
7532
7533 lck_mtx_lock(sadb_mutex);
7534
7535 if (mhp->ext[SADB_EXT_SA] == NULL) {
7536 /*
7537 * Caller wants us to delete all non-LARVAL SAs
7538 * that match the src/dst. This is used during
7539 * IKE INITIAL-CONTACT.
7540 */
7541 ipseclog((LOG_DEBUG, "key_delete: doing delete all.\n"));
7542 /* key_delete_all will unlock sadb_mutex */
7543 return key_delete_all(so, m, mhp, proto);
7544 } else if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa)) {
7545 lck_mtx_unlock(sadb_mutex);
7546 ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n"));
7547 return key_senderror(so, m, EINVAL);
7548 }
7549
7550 sa0 = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
7551 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
7552 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
7553 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
7554
7555 u_int ipsec_if_index = 0;
7556 if (ipsec_if != NULL) {
7557 ipsec_if_index = ipsec_if->if_index;
7558 ifnet_release(interface: ipsec_if);
7559 ipsec_if = NULL;
7560 }
7561
7562 /* XXX boundary check against sa_len */
7563 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, ipsec_if_index, &saidx);
7564
7565
7566 /* get a SA header */
7567 LIST_FOREACH(sah, &sahtree, chain) {
7568 if (sah->state == SADB_SASTATE_DEAD) {
7569 continue;
7570 }
7571 if (key_cmpsaidx(saidx0: &sah->saidx, saidx1: &saidx, CMP_HEAD) == 0) {
7572 continue;
7573 }
7574
7575 /* get a SA with SPI. */
7576 sav = key_getsavbyspi(sah, spi: sa0->sadb_sa_spi);
7577 if (sav) {
7578 break;
7579 }
7580 }
7581 if (sah == NULL) {
7582 lck_mtx_unlock(sadb_mutex);
7583 ipseclog((LOG_DEBUG, "key_delete: no SA found.\n"));
7584 return key_senderror(so, m, ENOENT);
7585 }
7586
7587 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
7588 key_freesav(sav, KEY_SADB_LOCKED);
7589
7590 lck_mtx_unlock(sadb_mutex);
7591 sav = NULL;
7592
7593 {
7594 struct mbuf *n;
7595 struct sadb_msg *newmsg;
7596 int mbufItems[] = {SADB_EXT_RESERVED, SADB_EXT_SA,
7597 SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST};
7598
7599 /* create new sadb_msg to reply. */
7600 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
7601 if (!n) {
7602 return key_senderror(so, m, ENOBUFS);
7603 }
7604
7605 if (n->m_len < sizeof(struct sadb_msg)) {
7606 n = m_pullup(n, sizeof(struct sadb_msg));
7607 if (n == NULL) {
7608 return key_senderror(so, m, ENOBUFS);
7609 }
7610 }
7611 newmsg = mtod(n, struct sadb_msg *);
7612 newmsg->sadb_msg_errno = 0;
7613 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
7614 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
7615
7616 m_freem(m);
7617 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
7618 }
7619}
7620
7621/*
7622 * delete all SAs for src/dst. Called from key_delete().
7623 */
7624static int
7625key_delete_all(
7626 struct socket *so,
7627 struct mbuf *m,
7628 const struct sadb_msghdr *mhp,
7629 u_int16_t proto)
7630{
7631 struct sadb_address *src0, *dst0;
7632 ifnet_t ipsec_if = NULL;
7633 struct secasindex saidx;
7634 struct secashead *sah;
7635 struct secasvar *sav, *nextsav;
7636 u_int stateidx, state;
7637
7638 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
7639
7640 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
7641 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
7642 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
7643
7644 u_int ipsec_if_index = 0;
7645 if (ipsec_if != NULL) {
7646 ipsec_if_index = ipsec_if->if_index;
7647 ifnet_release(interface: ipsec_if);
7648 ipsec_if = NULL;
7649 }
7650
7651 /* XXX boundary check against sa_len */
7652 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, ipsec_if_index, &saidx);
7653
7654 LIST_FOREACH(sah, &sahtree, chain) {
7655 if (sah->state == SADB_SASTATE_DEAD) {
7656 continue;
7657 }
7658 if (key_cmpsaidx(saidx0: &sah->saidx, saidx1: &saidx, CMP_HEAD) == 0) {
7659 continue;
7660 }
7661
7662 /* Delete all non-LARVAL SAs. */
7663 for (stateidx = 0;
7664 stateidx < _ARRAYLEN(saorder_state_alive);
7665 stateidx++) {
7666 state = saorder_state_alive[stateidx];
7667 if (state == SADB_SASTATE_LARVAL) {
7668 continue;
7669 }
7670 for (sav = LIST_FIRST(&sah->savtree[state]);
7671 sav != NULL; sav = nextsav) {
7672 nextsav = LIST_NEXT(sav, chain);
7673 /* sanity check */
7674 if (sav->state != state) {
7675 ipseclog((LOG_DEBUG, "key_delete_all: "
7676 "invalid sav->state "
7677 "(queue: %d SA: %d)\n",
7678 state, sav->state));
7679 continue;
7680 }
7681
7682 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
7683 key_freesav(sav, KEY_SADB_LOCKED);
7684 }
7685 }
7686 }
7687 lck_mtx_unlock(sadb_mutex);
7688
7689 {
7690 struct mbuf *n;
7691 struct sadb_msg *newmsg;
7692 int mbufItems[] = {SADB_EXT_RESERVED, SADB_EXT_ADDRESS_SRC,
7693 SADB_EXT_ADDRESS_DST};
7694
7695 /* create new sadb_msg to reply. */
7696 n = key_gather_mbuf(m, mhp, ndeep: 1, nitem: sizeof(mbufItems) / sizeof(int), items: mbufItems);
7697 if (!n) {
7698 return key_senderror(so, m, ENOBUFS);
7699 }
7700
7701 if (n->m_len < sizeof(struct sadb_msg)) {
7702 n = m_pullup(n, sizeof(struct sadb_msg));
7703 if (n == NULL) {
7704 return key_senderror(so, m, ENOBUFS);
7705 }
7706 }
7707 newmsg = mtod(n, struct sadb_msg *);
7708 newmsg->sadb_msg_errno = 0;
7709 VERIFY(PFKEY_UNIT64(n->m_pkthdr.len) <= UINT16_MAX);
7710 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(n->m_pkthdr.len);
7711
7712 m_freem(m);
7713 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
7714 }
7715}
7716
7717/*
7718 * SADB_GET processing
7719 * receive
7720 * <base, SA(*), address(SD)>
7721 * from the ikmpd, and get a SP and a SA to respond,
7722 * and send,
7723 * <base, SA, (lifetime(HSC),) address(SD), (address(P),) key(AE),
7724 * (identity(SD),) (sensitivity)>
7725 * to the ikmpd.
7726 *
7727 * m will always be freed.
7728 */
7729static int
7730key_get(
7731 struct socket *so,
7732 struct mbuf *m,
7733 const struct sadb_msghdr *mhp)
7734{
7735 struct sadb_sa *sa0;
7736 struct sadb_address *src0, *dst0;
7737 ifnet_t ipsec_if = NULL;
7738 struct secasindex saidx;
7739 struct secashead *sah;
7740 struct secasvar *sav = NULL;
7741 u_int16_t proto;
7742
7743 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
7744
7745 /* sanity check */
7746 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
7747 panic("key_get: NULL pointer is passed.");
7748 }
7749
7750 /* map satype to proto */
7751 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
7752 ipseclog((LOG_DEBUG, "key_get: invalid satype is passed.\n"));
7753 return key_senderror(so, m, EINVAL);
7754 }
7755
7756 if (mhp->ext[SADB_EXT_SA] == NULL ||
7757 mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
7758 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
7759 ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n"));
7760 return key_senderror(so, m, EINVAL);
7761 }
7762 if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
7763 mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
7764 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
7765 ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n"));
7766 return key_senderror(so, m, EINVAL);
7767 }
7768
7769 sa0 = (struct sadb_sa *)(void *)mhp->ext[SADB_EXT_SA];
7770 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
7771 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
7772 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
7773
7774 u_int ipsec_if_index = 0;
7775 if (ipsec_if != NULL) {
7776 ipsec_if_index = ipsec_if->if_index;
7777 ifnet_release(interface: ipsec_if);
7778 ipsec_if = NULL;
7779 }
7780
7781 /* XXX boundary check against sa_len */
7782 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, ipsec_if_index, &saidx);
7783
7784 lck_mtx_lock(sadb_mutex);
7785
7786 /* get a SA header */
7787 LIST_FOREACH(sah, &sahtree, chain) {
7788 if (sah->state == SADB_SASTATE_DEAD) {
7789 continue;
7790 }
7791 if (key_cmpsaidx(saidx0: &sah->saidx, saidx1: &saidx, CMP_HEAD) == 0) {
7792 continue;
7793 }
7794
7795 /* get a SA with SPI. */
7796 sav = key_getsavbyspi(sah, spi: sa0->sadb_sa_spi);
7797 if (sav) {
7798 break;
7799 }
7800 }
7801 if (sah == NULL) {
7802 lck_mtx_unlock(sadb_mutex);
7803 ipseclog((LOG_DEBUG, "key_get: no SA found.\n"));
7804 return key_senderror(so, m, ENOENT);
7805 }
7806
7807 {
7808 struct mbuf *n;
7809 u_int8_t satype;
7810
7811 /* map proto to satype */
7812 if ((satype = key_proto2satype(proto: sah->saidx.proto)) == 0) {
7813 lck_mtx_unlock(sadb_mutex);
7814 ipseclog((LOG_DEBUG, "key_get: there was invalid proto in SAD.\n"));
7815 return key_senderror(so, m, EINVAL);
7816 }
7817 lck_mtx_unlock(sadb_mutex);
7818
7819 /* create new sadb_msg to reply. */
7820 n = key_setdumpsa(sav, SADB_GET, satype, seq: mhp->msg->sadb_msg_seq,
7821 pid: mhp->msg->sadb_msg_pid);
7822
7823
7824
7825 if (!n) {
7826 return key_senderror(so, m, ENOBUFS);
7827 }
7828
7829 m_freem(m);
7830 return key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
7831 }
7832}
7833
7834/*
7835 * get SA stats by spi.
7836 * OUT: -1 : not found
7837 * 0 : found, arg pointer to a SA stats is updated.
7838 */
7839static int
7840key_getsastatbyspi_one(u_int32_t spi,
7841 struct sastat *stat)
7842{
7843 struct secashead *sah;
7844 struct secasvar *sav = NULL;
7845
7846 if ((void *)stat == NULL) {
7847 return -1;
7848 }
7849
7850 lck_mtx_lock(sadb_mutex);
7851
7852 /* get a SA header */
7853 LIST_FOREACH(sah, &sahtree, chain) {
7854 if (sah->state == SADB_SASTATE_DEAD) {
7855 continue;
7856 }
7857
7858 /* get a SA with SPI. */
7859 sav = key_getsavbyspi(sah, spi);
7860 if (sav) {
7861 stat->spi = sav->spi;
7862 stat->created = (u_int32_t)key_convert_continuous_time_ns(time_value: sav->created);
7863 if (sav->lft_c) {
7864 bcopy(src: sav->lft_c, dst: &stat->lft_c, n: sizeof(stat->lft_c));
7865 // Convert timestamps
7866 stat->lft_c.sadb_lifetime_addtime =
7867 key_convert_continuous_time_ns(time_value: sav->lft_c->sadb_lifetime_addtime);
7868 stat->lft_c.sadb_lifetime_usetime =
7869 key_convert_continuous_time_ns(time_value: sav->lft_c->sadb_lifetime_usetime);
7870 } else {
7871 bzero(s: &stat->lft_c, n: sizeof(stat->lft_c));
7872 }
7873 lck_mtx_unlock(sadb_mutex);
7874 return 0;
7875 }
7876 }
7877
7878 lck_mtx_unlock(sadb_mutex);
7879
7880 return -1;
7881}
7882
7883/*
7884 * get SA stats collection by indices.
7885 * OUT: -1 : not found
7886 * 0 : found, arg pointers to a SA stats and 'maximum stats' are updated.
7887 */
7888static int
7889key_getsastatbyspi(struct sastat *stat_arg,
7890 u_int32_t max_stat_arg,
7891 struct sastat *stat_res,
7892 u_int64_t stat_res_size,
7893 u_int32_t *max_stat_res)
7894{
7895 u_int32_t cur, found = 0;
7896
7897 if (stat_arg == NULL ||
7898 stat_res == NULL ||
7899 max_stat_res == NULL) {
7900 return -1;
7901 }
7902
7903 u_int64_t max_stats = stat_res_size / (sizeof(struct sastat));
7904 max_stats = ((max_stat_arg <= max_stats) ? max_stat_arg : max_stats);
7905
7906 for (cur = 0; cur < max_stats; cur++) {
7907 if (key_getsastatbyspi_one(spi: stat_arg[cur].spi,
7908 stat: &stat_res[found]) == 0) {
7909 found++;
7910 }
7911 }
7912 *max_stat_res = found;
7913
7914 if (found) {
7915 return 0;
7916 }
7917 return -1;
7918}
7919
7920/* XXX make it sysctl-configurable? */
7921static void
7922key_getcomb_setlifetime(
7923 struct sadb_comb *comb)
7924{
7925 comb->sadb_comb_soft_allocations = 1;
7926 comb->sadb_comb_hard_allocations = 1;
7927 comb->sadb_comb_soft_bytes = 0;
7928 comb->sadb_comb_hard_bytes = 0;
7929 comb->sadb_comb_hard_addtime = 86400; /* 1 day */
7930 comb->sadb_comb_soft_addtime = comb->sadb_comb_soft_addtime * 80 / 100;
7931 comb->sadb_comb_soft_usetime = 28800; /* 8 hours */
7932 comb->sadb_comb_hard_usetime = comb->sadb_comb_hard_usetime * 80 / 100;
7933}
7934
7935#if IPSEC_ESP
7936/*
7937 * XXX reorder combinations by preference
7938 * XXX no idea if the user wants ESP authentication or not
7939 */
7940static struct mbuf *
7941key_getcomb_esp(void)
7942{
7943 struct sadb_comb *comb;
7944 const struct esp_algorithm *algo;
7945 struct mbuf *result = NULL, *m, *n;
7946 u_int16_t encmin;
7947 int off, o;
7948 int totlen;
7949 u_int8_t i;
7950 const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb));
7951
7952 m = NULL;
7953 for (i = 1; i <= SADB_EALG_MAX; i++) {
7954 algo = esp_algorithm_lookup(i);
7955 if (!algo) {
7956 continue;
7957 }
7958
7959 if (algo->keymax < ipsec_esp_keymin) {
7960 continue;
7961 }
7962 if (algo->keymin < ipsec_esp_keymin) {
7963 encmin = (u_int16_t)ipsec_esp_keymin;
7964 } else {
7965 encmin = algo->keymin;
7966 }
7967
7968 if (ipsec_esp_auth) {
7969 m = key_getcomb_ah();
7970 } else {
7971#if DIAGNOSTIC
7972 if (l > MLEN) {
7973 panic("assumption failed in key_getcomb_esp");
7974 }
7975#endif
7976 MGET(m, M_WAITOK, MT_DATA);
7977 if (m) {
7978 M_ALIGN(m, l);
7979 m->m_len = l;
7980 m->m_next = NULL;
7981 bzero(mtod(m, caddr_t), n: m->m_len);
7982 }
7983 }
7984 if (!m) {
7985 goto fail;
7986 }
7987
7988 totlen = 0;
7989 for (n = m; n; n = n->m_next) {
7990 totlen += n->m_len;
7991 }
7992#if DIAGNOSTIC
7993 if (totlen % l) {
7994 panic("assumption failed in key_getcomb_esp");
7995 }
7996#endif
7997
7998 for (off = 0; off < totlen; off += l) {
7999 n = m_pulldown(m, off, l, &o);
8000 if (!n) {
8001 /* m is already freed */
8002 goto fail;
8003 }
8004 comb = (struct sadb_comb *)
8005 (void *)(mtod(n, caddr_t) + o);
8006 bzero(s: comb, n: sizeof(*comb));
8007 key_getcomb_setlifetime(comb);
8008 comb->sadb_comb_encrypt = i;
8009 comb->sadb_comb_encrypt_minbits = encmin;
8010 comb->sadb_comb_encrypt_maxbits = algo->keymax;
8011 }
8012
8013 if (!result) {
8014 result = m;
8015 } else {
8016 m_cat(result, m);
8017 }
8018 }
8019
8020 return result;
8021
8022fail:
8023 if (result) {
8024 m_freem(result);
8025 }
8026 return NULL;
8027}
8028#endif
8029
8030/*
8031 * XXX reorder combinations by preference
8032 */
8033static struct mbuf *
8034key_getcomb_ah(void)
8035{
8036 struct sadb_comb *comb;
8037 const struct ah_algorithm *algo;
8038 struct mbuf *m;
8039 u_int16_t keymin;
8040 u_int8_t i;
8041 const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb));
8042
8043 m = NULL;
8044 for (i = 1; i <= SADB_AALG_MAX; i++) {
8045#if 1
8046 /* we prefer HMAC algorithms, not old algorithms */
8047 if (i != SADB_AALG_SHA1HMAC && i != SADB_AALG_MD5HMAC) {
8048 continue;
8049 }
8050#endif
8051 algo = ah_algorithm_lookup(i);
8052 if (!algo) {
8053 continue;
8054 }
8055
8056 if (algo->keymax < ipsec_ah_keymin) {
8057 continue;
8058 }
8059 if (algo->keymin < ipsec_ah_keymin) {
8060 keymin = (u_int16_t)ipsec_ah_keymin;
8061 } else {
8062 keymin = algo->keymin;
8063 }
8064
8065 if (!m) {
8066#if DIAGNOSTIC
8067 if (l > MLEN) {
8068 panic("assumption failed in key_getcomb_ah");
8069 }
8070#endif
8071 MGET(m, M_WAITOK, MT_DATA);
8072 if (m) {
8073 M_ALIGN(m, l);
8074 m->m_len = l;
8075 m->m_next = NULL;
8076 }
8077 } else {
8078 M_PREPEND(m, l, M_WAITOK, 1);
8079 }
8080 if (!m) {
8081 return NULL;
8082 }
8083
8084 comb = mtod(m, struct sadb_comb *);
8085 bzero(s: comb, n: sizeof(*comb));
8086 key_getcomb_setlifetime(comb);
8087 comb->sadb_comb_auth = i;
8088 comb->sadb_comb_auth_minbits = keymin;
8089 comb->sadb_comb_auth_maxbits = algo->keymax;
8090 }
8091
8092 return m;
8093}
8094
8095/*
8096 * XXX no way to pass mode (transport/tunnel) to userland
8097 * XXX replay checking?
8098 * XXX sysctl interface to ipsec_{ah,esp}_keymin
8099 */
8100static struct mbuf *
8101key_getprop(
8102 const struct secasindex *saidx)
8103{
8104 struct sadb_prop *prop;
8105 struct mbuf *m, *n;
8106 const int l = PFKEY_ALIGN8(sizeof(struct sadb_prop));
8107 int totlen;
8108
8109 switch (saidx->proto) {
8110#if IPSEC_ESP
8111 case IPPROTO_ESP:
8112 m = key_getcomb_esp();
8113 break;
8114#endif
8115 case IPPROTO_AH:
8116 m = key_getcomb_ah();
8117 break;
8118 default:
8119 return NULL;
8120 }
8121
8122 if (!m) {
8123 return NULL;
8124 }
8125 M_PREPEND(m, l, M_WAITOK, 1);
8126 if (!m) {
8127 return NULL;
8128 }
8129
8130 totlen = 0;
8131 for (n = m; n; n = n->m_next) {
8132 totlen += n->m_len;
8133 }
8134
8135 prop = mtod(m, struct sadb_prop *);
8136 bzero(s: prop, n: sizeof(*prop));
8137 VERIFY(totlen <= UINT16_MAX);
8138 prop->sadb_prop_len = (u_int16_t)PFKEY_UNIT64(totlen);
8139 prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
8140 prop->sadb_prop_replay = 32; /* XXX */
8141
8142 return m;
8143}
8144
8145/*
8146 * SADB_ACQUIRE processing called by key_checkrequest() and key_acquire2().
8147 * send
8148 * <base, SA, address(SD), (address(P)), x_policy,
8149 * (identity(SD),) (sensitivity,) proposal>
8150 * to KMD, and expect to receive
8151 * <base> with SADB_ACQUIRE if error occurred,
8152 * or
8153 * <base, src address, dst address, (SPI range)> with SADB_GETSPI
8154 * from KMD by PF_KEY.
8155 *
8156 * XXX x_policy is outside of RFC2367 (KAME extension).
8157 * XXX sensitivity is not supported.
8158 *
8159 * OUT:
8160 * 0 : succeed
8161 * others: error number
8162 */
8163static int
8164key_acquire(
8165 struct secasindex *saidx,
8166 struct secpolicy *sp)
8167{
8168 struct mbuf *result = NULL, *m;
8169#ifndef IPSEC_NONBLOCK_ACQUIRE
8170 struct secacq *newacq;
8171#endif
8172 u_int8_t satype;
8173 int error = -1;
8174 u_int32_t seq;
8175
8176 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
8177
8178 /* sanity check */
8179 if (saidx == NULL) {
8180 panic("key_acquire: NULL pointer is passed.");
8181 }
8182 if ((satype = key_proto2satype(proto: saidx->proto)) == 0) {
8183 panic("key_acquire: invalid proto is passed.");
8184 }
8185
8186#ifndef IPSEC_NONBLOCK_ACQUIRE
8187 /*
8188 * We never do anything about acquirng SA. There is anather
8189 * solution that kernel blocks to send SADB_ACQUIRE message until
8190 * getting something message from IKEd. In later case, to be
8191 * managed with ACQUIRING list.
8192 */
8193 /* get a entry to check whether sending message or not. */
8194 lck_mtx_lock(sadb_mutex);
8195 if ((newacq = key_getacq(saidx)) != NULL) {
8196 if (key_blockacq_count < newacq->count) {
8197 /* reset counter and do send message. */
8198 newacq->count = 0;
8199 } else {
8200 /* increment counter and do nothing. */
8201 newacq->count++;
8202 lck_mtx_unlock(sadb_mutex);
8203 return 0;
8204 }
8205 } else {
8206 /* make new entry for blocking to send SADB_ACQUIRE. */
8207 if ((newacq = key_newacq(saidx)) == NULL) {
8208 lck_mtx_unlock(sadb_mutex);
8209 return ENOBUFS;
8210 }
8211
8212 /* add to acqtree */
8213 LIST_INSERT_HEAD(&acqtree, newacq, chain);
8214 key_start_timehandler();
8215 }
8216 seq = newacq->seq;
8217 lck_mtx_unlock(sadb_mutex);
8218
8219#else
8220 seq = (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq));
8221#endif
8222 m = key_setsadbmsg(SADB_ACQUIRE, tlen: 0, satype, seq, pid: 0, reserved: 0);
8223 if (!m) {
8224 error = ENOBUFS;
8225 goto fail;
8226 }
8227 result = m;
8228
8229 /* set sadb_address for saidx's. */
8230 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
8231 saddr: (struct sockaddr *)&saidx->src, FULLMASK, IPSEC_ULPROTO_ANY);
8232 if (!m) {
8233 error = ENOBUFS;
8234 goto fail;
8235 }
8236 m_cat(result, m);
8237
8238 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
8239 saddr: (struct sockaddr *)&saidx->dst, FULLMASK, IPSEC_ULPROTO_ANY);
8240 if (!m) {
8241 error = ENOBUFS;
8242 goto fail;
8243 }
8244 m_cat(result, m);
8245
8246 /* XXX proxy address (optional) */
8247
8248 /* set sadb_x_policy */
8249 if (sp) {
8250 m = key_setsadbxpolicy(type: (u_int16_t)sp->policy, dir: sp->spidx.dir, id: sp->id);
8251 if (!m) {
8252 error = ENOBUFS;
8253 goto fail;
8254 }
8255 m_cat(result, m);
8256 }
8257
8258 /* XXX sensitivity (optional) */
8259
8260 /* create proposal/combination extension */
8261 m = key_getprop(saidx);
8262 /*
8263 * outside of spec; make proposal/combination extension optional.
8264 */
8265 if (m) {
8266 m_cat(result, m);
8267 }
8268
8269 if ((result->m_flags & M_PKTHDR) == 0) {
8270 error = EINVAL;
8271 goto fail;
8272 }
8273
8274 if (result->m_len < sizeof(struct sadb_msg)) {
8275 result = m_pullup(result, sizeof(struct sadb_msg));
8276 if (result == NULL) {
8277 error = ENOBUFS;
8278 goto fail;
8279 }
8280 }
8281
8282 result->m_pkthdr.len = 0;
8283 for (m = result; m; m = m->m_next) {
8284 result->m_pkthdr.len += m->m_len;
8285 }
8286
8287 VERIFY(PFKEY_UNIT64(result->m_pkthdr.len) <= UINT16_MAX);
8288 mtod(result, struct sadb_msg *)->sadb_msg_len =
8289 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
8290
8291 return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
8292
8293fail:
8294 if (result) {
8295 m_freem(result);
8296 }
8297 return error;
8298}
8299
8300#ifndef IPSEC_NONBLOCK_ACQUIRE
8301static struct secacq *
8302key_newacq(
8303 struct secasindex *saidx)
8304{
8305 struct secacq *newacq;
8306
8307 /* get new entry */
8308 newacq = kalloc_type(struct secacq, Z_NOWAIT_ZERO);
8309 if (newacq == NULL) {
8310 lck_mtx_unlock(sadb_mutex);
8311 newacq = kalloc_type(struct secacq, Z_WAITOK_ZERO_NOFAIL);
8312 lck_mtx_lock(sadb_mutex);
8313 }
8314
8315 /* copy secindex */
8316 bcopy(src: saidx, dst: &newacq->saidx, n: sizeof(newacq->saidx));
8317 newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq);
8318 newacq->created = key_get_continuous_time_ns();
8319
8320 return newacq;
8321}
8322
8323static struct secacq *
8324key_getacq(
8325 struct secasindex *saidx)
8326{
8327 struct secacq *acq;
8328
8329 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
8330
8331 LIST_FOREACH(acq, &acqtree, chain) {
8332 if (key_cmpsaidx(saidx0: saidx, saidx1: &acq->saidx, CMP_EXACTLY)) {
8333 return acq;
8334 }
8335 }
8336
8337 return NULL;
8338}
8339
8340static struct secacq *
8341key_getacqbyseq(
8342 u_int32_t seq)
8343{
8344 struct secacq *acq;
8345
8346 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
8347
8348 LIST_FOREACH(acq, &acqtree, chain) {
8349 if (acq->seq == seq) {
8350 return acq;
8351 }
8352 }
8353
8354 return NULL;
8355}
8356#endif
8357
8358static struct secspacq *
8359key_newspacq(
8360 struct secpolicyindex *spidx)
8361{
8362 struct secspacq *acq;
8363
8364 /* get new entry */
8365 acq = kalloc_type(struct secspacq, Z_NOWAIT_ZERO);
8366 if (acq == NULL) {
8367 lck_mtx_unlock(sadb_mutex);
8368 acq = kalloc_type(struct secspacq, Z_WAITOK_ZERO_NOFAIL);
8369 lck_mtx_lock(sadb_mutex);
8370 }
8371
8372 /* copy secindex */
8373 bcopy(src: spidx, dst: &acq->spidx, n: sizeof(acq->spidx));
8374 acq->created = key_get_continuous_time_ns();
8375
8376 return acq;
8377}
8378
8379static struct secspacq *
8380key_getspacq(
8381 struct secpolicyindex *spidx)
8382{
8383 struct secspacq *acq;
8384
8385 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
8386
8387 LIST_FOREACH(acq, &spacqtree, chain) {
8388 if (key_cmpspidx_exactly(spidx0: spidx, spidx1: &acq->spidx)) {
8389 return acq;
8390 }
8391 }
8392
8393 return NULL;
8394}
8395
8396/*
8397 * SADB_ACQUIRE processing,
8398 * in first situation, is receiving
8399 * <base>
8400 * from the ikmpd, and clear sequence of its secasvar entry.
8401 *
8402 * In second situation, is receiving
8403 * <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal>
8404 * from a user land process, and return
8405 * <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal>
8406 * to the socket.
8407 *
8408 * m will always be freed.
8409 */
8410static int
8411key_acquire2(
8412 struct socket *so,
8413 struct mbuf *m,
8414 const struct sadb_msghdr *mhp)
8415{
8416 const struct sadb_address *src0, *dst0;
8417 ifnet_t ipsec_if = NULL;
8418 struct secasindex saidx;
8419 struct secashead *sah;
8420 u_int16_t proto;
8421 int error;
8422
8423
8424 /* sanity check */
8425 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
8426 panic("key_acquire2: NULL pointer is passed.");
8427 }
8428
8429 /*
8430 * Error message from KMd.
8431 * We assume that if error was occurred in IKEd, the length of PFKEY
8432 * message is equal to the size of sadb_msg structure.
8433 * We do not raise error even if error occurred in this function.
8434 */
8435 lck_mtx_lock(sadb_mutex);
8436
8437 if (mhp->msg->sadb_msg_len == PFKEY_UNIT64(sizeof(struct sadb_msg))) {
8438#ifndef IPSEC_NONBLOCK_ACQUIRE
8439 struct secacq *acq;
8440
8441 /* check sequence number */
8442 if (mhp->msg->sadb_msg_seq == 0) {
8443 lck_mtx_unlock(sadb_mutex);
8444 ipseclog((LOG_DEBUG, "key_acquire2: must specify sequence number.\n"));
8445 m_freem(m);
8446 return 0;
8447 }
8448
8449 if ((acq = key_getacqbyseq(seq: mhp->msg->sadb_msg_seq)) == NULL) {
8450 /*
8451 * the specified larval SA is already gone, or we got
8452 * a bogus sequence number. we can silently ignore it.
8453 */
8454 lck_mtx_unlock(sadb_mutex);
8455 m_freem(m);
8456 return 0;
8457 }
8458
8459 /* reset acq counter in order to deletion by timehander. */
8460 acq->created = key_get_continuous_time_ns();
8461 acq->count = 0;
8462#endif
8463 lck_mtx_unlock(sadb_mutex);
8464 m_freem(m);
8465 return 0;
8466 }
8467
8468 /*
8469 * This message is from user land.
8470 */
8471
8472 /* map satype to proto */
8473 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
8474 lck_mtx_unlock(sadb_mutex);
8475 ipseclog((LOG_DEBUG, "key_acquire2: invalid satype is passed.\n"));
8476 return key_senderror(so, m, EINVAL);
8477 }
8478
8479 if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
8480 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
8481 mhp->ext[SADB_EXT_PROPOSAL] == NULL) {
8482 /* error */
8483 lck_mtx_unlock(sadb_mutex);
8484 ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n"));
8485 return key_senderror(so, m, EINVAL);
8486 }
8487 if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
8488 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) ||
8489 mhp->extlen[SADB_EXT_PROPOSAL] < sizeof(struct sadb_prop)) {
8490 /* error */
8491 lck_mtx_unlock(sadb_mutex);
8492 ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n"));
8493 return key_senderror(so, m, EINVAL);
8494 }
8495
8496 src0 = (const struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
8497 dst0 = (const struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
8498 ipsec_if = key_get_ipsec_if_from_message(mhp, SADB_X_EXT_IPSECIF);
8499
8500 u_int ipsec_if_index = 0;
8501 if (ipsec_if != NULL) {
8502 ipsec_if_index = ipsec_if->if_index;
8503 ifnet_release(interface: ipsec_if);
8504 ipsec_if = NULL;
8505 }
8506
8507 /* XXX boundary check against sa_len */
8508 /* cast warnings */
8509 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, ipsec_if_index, &saidx);
8510
8511 /* get a SA index */
8512 LIST_FOREACH(sah, &sahtree, chain) {
8513 if (sah->state == SADB_SASTATE_DEAD) {
8514 continue;
8515 }
8516 if (key_cmpsaidx(saidx0: &sah->saidx, saidx1: &saidx, CMP_MODE | CMP_REQID)) {
8517 break;
8518 }
8519 }
8520 if (sah != NULL) {
8521 lck_mtx_unlock(sadb_mutex);
8522 ipseclog((LOG_DEBUG, "key_acquire2: a SA exists already.\n"));
8523 return key_senderror(so, m, EEXIST);
8524 }
8525 lck_mtx_unlock(sadb_mutex);
8526 error = key_acquire(saidx: &saidx, NULL);
8527 if (error != 0) {
8528 ipseclog((LOG_DEBUG, "key_acquire2: error %d returned "
8529 "from key_acquire.\n", mhp->msg->sadb_msg_errno));
8530 return key_senderror(so, m, error);
8531 }
8532
8533 return key_sendup_mbuf(so, m, KEY_SENDUP_REGISTERED);
8534}
8535
8536/*
8537 * SADB_REGISTER processing.
8538 * If SATYPE_UNSPEC has been passed as satype, only return sadb_supported.
8539 * receive
8540 * <base>
8541 * from the ikmpd, and register a socket to send PF_KEY messages,
8542 * and send
8543 * <base, supported>
8544 * to KMD by PF_KEY.
8545 * If socket is detached, must free from regnode.
8546 *
8547 * m will always be freed.
8548 */
8549static int
8550key_register(
8551 struct socket *so,
8552 struct mbuf *m,
8553 const struct sadb_msghdr *mhp)
8554{
8555 struct secreg *reg, *newreg = 0;
8556
8557 /* sanity check */
8558 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
8559 panic("key_register: NULL pointer is passed.");
8560 }
8561
8562 /* check for invalid register message */
8563 if (mhp->msg->sadb_msg_satype >= sizeof(regtree) / sizeof(regtree[0])) {
8564 return key_senderror(so, m, EINVAL);
8565 }
8566
8567 /* When SATYPE_UNSPEC is specified, only return sadb_supported. */
8568 if (mhp->msg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
8569 goto setmsg;
8570 }
8571
8572 /* create regnode */
8573 newreg = kalloc_type(struct secreg, Z_WAITOK_ZERO_NOFAIL);
8574
8575 lck_mtx_lock(sadb_mutex);
8576 /* check whether existing or not */
8577 LIST_FOREACH(reg, &regtree[mhp->msg->sadb_msg_satype], chain) {
8578 if (reg->so == so) {
8579 lck_mtx_unlock(sadb_mutex);
8580 ipseclog((LOG_DEBUG, "key_register: socket exists already.\n"));
8581 kfree_type(struct secreg, newreg);
8582 return key_senderror(so, m, EEXIST);
8583 }
8584 }
8585
8586 socket_lock(so, refcount: 1);
8587 newreg->so = so;
8588 ((struct keycb *)sotorawcb(so))->kp_registered++;
8589 socket_unlock(so, refcount: 1);
8590
8591 /* add regnode to regtree. */
8592 LIST_INSERT_HEAD(&regtree[mhp->msg->sadb_msg_satype], newreg, chain);
8593 lck_mtx_unlock(sadb_mutex);
8594setmsg:
8595 {
8596 struct mbuf *n;
8597 struct sadb_msg *newmsg;
8598 struct sadb_supported *sup;
8599 u_int16_t len, alen, elen;
8600 int off;
8601 u_int8_t i;
8602 struct sadb_alg *alg;
8603
8604 /* create new sadb_msg to reply. */
8605 alen = 0;
8606 for (i = 1; i <= SADB_AALG_MAX; i++) {
8607 if (ah_algorithm_lookup(i)) {
8608 alen += sizeof(struct sadb_alg);
8609 }
8610 }
8611 if (alen) {
8612 alen += sizeof(struct sadb_supported);
8613 }
8614 elen = 0;
8615#if IPSEC_ESP
8616 for (i = 1; i <= SADB_EALG_MAX; i++) {
8617 if (esp_algorithm_lookup(i)) {
8618 elen += sizeof(struct sadb_alg);
8619 }
8620 }
8621 if (elen) {
8622 elen += sizeof(struct sadb_supported);
8623 }
8624#endif
8625
8626 len = sizeof(struct sadb_msg) + alen + elen;
8627
8628 if (len > MCLBYTES) {
8629 return key_senderror(so, m, ENOBUFS);
8630 }
8631
8632 MGETHDR(n, M_WAITOK, MT_DATA);
8633 if (n && len > MHLEN) {
8634 MCLGET(n, M_WAITOK);
8635 if ((n->m_flags & M_EXT) == 0) {
8636 m_freem(n);
8637 n = NULL;
8638 }
8639 }
8640 if (!n) {
8641 return key_senderror(so, m, ENOBUFS);
8642 }
8643
8644 n->m_pkthdr.len = n->m_len = len;
8645 n->m_next = NULL;
8646 off = 0;
8647
8648 m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off);
8649 newmsg = mtod(n, struct sadb_msg *);
8650 newmsg->sadb_msg_errno = 0;
8651 VERIFY(PFKEY_UNIT64(len) <= UINT16_MAX);
8652 newmsg->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(len);
8653 off += PFKEY_ALIGN8(sizeof(struct sadb_msg));
8654
8655 /* for authentication algorithm */
8656 if (alen) {
8657 sup = (struct sadb_supported *)(void *)(mtod(n, caddr_t) + off);
8658 sup->sadb_supported_len = (u_int16_t)PFKEY_UNIT64(alen);
8659 sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_AUTH;
8660 off += PFKEY_ALIGN8(sizeof(*sup));
8661
8662 for (i = 1; i <= SADB_AALG_MAX; i++) {
8663 const struct ah_algorithm *aalgo;
8664
8665 aalgo = ah_algorithm_lookup(i);
8666 if (!aalgo) {
8667 continue;
8668 }
8669 alg = (struct sadb_alg *)
8670 (void *)(mtod(n, caddr_t) + off);
8671 alg->sadb_alg_id = i;
8672 alg->sadb_alg_ivlen = 0;
8673 alg->sadb_alg_minbits = aalgo->keymin;
8674 alg->sadb_alg_maxbits = aalgo->keymax;
8675 off += PFKEY_ALIGN8(sizeof(*alg));
8676 }
8677 }
8678
8679#if IPSEC_ESP
8680 /* for encryption algorithm */
8681 if (elen) {
8682 sup = (struct sadb_supported *)(void *)(mtod(n, caddr_t) + off);
8683 sup->sadb_supported_len = PFKEY_UNIT64(elen);
8684 sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_ENCRYPT;
8685 off += PFKEY_ALIGN8(sizeof(*sup));
8686
8687 for (i = 1; i <= SADB_EALG_MAX; i++) {
8688 const struct esp_algorithm *ealgo;
8689
8690 ealgo = esp_algorithm_lookup(i);
8691 if (!ealgo) {
8692 continue;
8693 }
8694 alg = (struct sadb_alg *)
8695 (void *)(mtod(n, caddr_t) + off);
8696 alg->sadb_alg_id = i;
8697 if (ealgo && ealgo->ivlen) {
8698 /*
8699 * give NULL to get the value preferred by
8700 * algorithm XXX SADB_X_EXT_DERIV ?
8701 */
8702 VERIFY((*ealgo->ivlen)(ealgo, NULL) <= UINT8_MAX);
8703 alg->sadb_alg_ivlen =
8704 (u_int8_t)((*ealgo->ivlen)(ealgo, NULL));
8705 } else {
8706 alg->sadb_alg_ivlen = 0;
8707 }
8708 alg->sadb_alg_minbits = ealgo->keymin;
8709 alg->sadb_alg_maxbits = ealgo->keymax;
8710 off += PFKEY_ALIGN8(sizeof(struct sadb_alg));
8711 }
8712 }
8713#endif
8714
8715#if DIAGNOSTIC
8716 if (off != len) {
8717 panic("length assumption failed in key_register");
8718 }
8719#endif
8720
8721 m_freem(m);
8722 return key_sendup_mbuf(so, n, KEY_SENDUP_REGISTERED);
8723 }
8724}
8725
8726static void
8727key_delete_all_for_socket(struct socket *so)
8728{
8729 struct secashead *sah, *nextsah;
8730 struct secasvar *sav, *nextsav;
8731 u_int stateidx;
8732 u_int state;
8733
8734 for (sah = LIST_FIRST(&sahtree);
8735 sah != NULL;
8736 sah = nextsah) {
8737 nextsah = LIST_NEXT(sah, chain);
8738 for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); stateidx++) {
8739 state = saorder_state_any[stateidx];
8740 for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) {
8741 nextsav = LIST_NEXT(sav, chain);
8742 if (sav->flags2 & SADB_X_EXT_SA2_DELETE_ON_DETACH &&
8743 sav->so == so) {
8744 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
8745 key_freesav(sav, KEY_SADB_LOCKED);
8746 }
8747 }
8748 }
8749 }
8750}
8751
8752/*
8753 * free secreg entry registered.
8754 * XXX: I want to do free a socket marked done SADB_RESIGER to socket.
8755 */
8756void
8757key_freereg(
8758 struct socket *so)
8759{
8760 struct secreg *reg;
8761 int i;
8762
8763 /* sanity check */
8764 if (so == NULL) {
8765 panic("key_freereg: NULL pointer is passed.");
8766 }
8767
8768 /*
8769 * check whether existing or not.
8770 * check all type of SA, because there is a potential that
8771 * one socket is registered to multiple type of SA.
8772 */
8773 lck_mtx_lock(sadb_mutex);
8774 key_delete_all_for_socket(so);
8775 for (i = 0; i <= SADB_SATYPE_MAX; i++) {
8776 LIST_FOREACH(reg, &regtree[i], chain) {
8777 if (reg->so == so
8778 && __LIST_CHAINED(reg)) {
8779 LIST_REMOVE(reg, chain);
8780 kfree_type(struct secreg, reg);
8781 break;
8782 }
8783 }
8784 }
8785 lck_mtx_unlock(sadb_mutex);
8786 return;
8787}
8788
8789/*
8790 * SADB_EXPIRE processing
8791 * send
8792 * <base, SA, SA2, lifetime(C and one of HS), address(SD)>
8793 * to KMD by PF_KEY.
8794 * NOTE: We send only soft lifetime extension.
8795 *
8796 * OUT: 0 : succeed
8797 * others : error number
8798 */
8799static int
8800key_expire(
8801 struct secasvar *sav)
8802{
8803 u_int8_t satype;
8804 struct mbuf *result = NULL, *m;
8805 int len;
8806 int error = -1;
8807 struct sadb_lifetime *lt;
8808
8809 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
8810
8811 /* sanity check */
8812 if (sav == NULL) {
8813 panic("key_expire: NULL pointer is passed.");
8814 }
8815 if (sav->sah == NULL) {
8816 panic("key_expire: Why was SA index in SA NULL.");
8817 }
8818 if ((satype = key_proto2satype(proto: sav->sah->saidx.proto)) == 0) {
8819 panic("key_expire: invalid proto is passed.");
8820 }
8821
8822 /* set msg header */
8823 m = key_setsadbmsg(SADB_EXPIRE, tlen: 0, satype, seq: sav->seq, pid: 0, reserved: (u_int16_t)sav->refcnt);
8824 if (!m) {
8825 error = ENOBUFS;
8826 goto fail;
8827 }
8828 result = m;
8829
8830 /* create SA extension */
8831 m = key_setsadbsa(sav);
8832 if (!m) {
8833 error = ENOBUFS;
8834 goto fail;
8835 }
8836 m_cat(result, m);
8837
8838 /* create SA extension */
8839 m = key_setsadbxsa2(mode: sav->sah->saidx.mode,
8840 seq: sav->replay[0] ? sav->replay[0]->count : 0,
8841 reqid: sav->sah->saidx.reqid,
8842 flags: sav->flags2);
8843 if (!m) {
8844 error = ENOBUFS;
8845 goto fail;
8846 }
8847 m_cat(result, m);
8848
8849 /* create lifetime extension (current and soft) */
8850 len = PFKEY_ALIGN8(sizeof(*lt)) * 2;
8851 m = key_alloc_mbuf(len);
8852 if (!m || m->m_next) { /*XXX*/
8853 if (m) {
8854 m_freem(m);
8855 }
8856 error = ENOBUFS;
8857 goto fail;
8858 }
8859 bzero(mtod(m, caddr_t), n: len);
8860 lt = mtod(m, struct sadb_lifetime *);
8861 lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
8862 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
8863 lt->sadb_lifetime_allocations = sav->lft_c->sadb_lifetime_allocations;
8864 lt->sadb_lifetime_bytes = sav->lft_c->sadb_lifetime_bytes;
8865 lt->sadb_lifetime_addtime = key_convert_continuous_time_ns(time_value: sav->lft_c->sadb_lifetime_addtime);
8866 lt->sadb_lifetime_usetime = key_convert_continuous_time_ns(time_value: sav->lft_c->sadb_lifetime_usetime);
8867 lt = (struct sadb_lifetime *)(void *)(mtod(m, caddr_t) + len / 2);
8868 bcopy(src: sav->lft_s, dst: lt, n: sizeof(*lt));
8869 m_cat(result, m);
8870
8871 /* set sadb_address for source */
8872 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
8873 saddr: (struct sockaddr *)&sav->sah->saidx.src,
8874 FULLMASK, IPSEC_ULPROTO_ANY);
8875 if (!m) {
8876 error = ENOBUFS;
8877 goto fail;
8878 }
8879 m_cat(result, m);
8880
8881 /* set sadb_address for destination */
8882 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
8883 saddr: (struct sockaddr *)&sav->sah->saidx.dst,
8884 FULLMASK, IPSEC_ULPROTO_ANY);
8885 if (!m) {
8886 error = ENOBUFS;
8887 goto fail;
8888 }
8889 m_cat(result, m);
8890
8891 if ((result->m_flags & M_PKTHDR) == 0) {
8892 error = EINVAL;
8893 goto fail;
8894 }
8895
8896 if (result->m_len < sizeof(struct sadb_msg)) {
8897 result = m_pullup(result, sizeof(struct sadb_msg));
8898 if (result == NULL) {
8899 error = ENOBUFS;
8900 goto fail;
8901 }
8902 }
8903
8904 result->m_pkthdr.len = 0;
8905 for (m = result; m; m = m->m_next) {
8906 result->m_pkthdr.len += m->m_len;
8907 }
8908
8909 VERIFY(PFKEY_UNIT64(result->m_pkthdr.len) <= UINT16_MAX);
8910 mtod(result, struct sadb_msg *)->sadb_msg_len =
8911 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
8912
8913 return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
8914
8915fail:
8916 if (result) {
8917 m_freem(result);
8918 }
8919 return error;
8920}
8921
8922/*
8923 * SADB_FLUSH processing
8924 * receive
8925 * <base>
8926 * from the ikmpd, and free all entries in secastree.
8927 * and send,
8928 * <base>
8929 * to the ikmpd.
8930 * NOTE: to do is only marking SADB_SASTATE_DEAD.
8931 *
8932 * m will always be freed.
8933 */
8934static int
8935key_flush(
8936 struct socket *so,
8937 struct mbuf *m,
8938 const struct sadb_msghdr *mhp)
8939{
8940 struct sadb_msg *newmsg;
8941 struct secashead *sah, *nextsah;
8942 struct secasvar *sav, *nextsav;
8943 u_int16_t proto;
8944 u_int state;
8945 u_int stateidx;
8946
8947 /* sanity check */
8948 if (so == NULL || mhp == NULL || mhp->msg == NULL) {
8949 panic("key_flush: NULL pointer is passed.");
8950 }
8951
8952 /* map satype to proto */
8953 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
8954 ipseclog((LOG_DEBUG, "key_flush: invalid satype is passed.\n"));
8955 return key_senderror(so, m, EINVAL);
8956 }
8957
8958 lck_mtx_lock(sadb_mutex);
8959
8960 /* no SATYPE specified, i.e. flushing all SA. */
8961 for (sah = LIST_FIRST(&sahtree);
8962 sah != NULL;
8963 sah = nextsah) {
8964 nextsah = LIST_NEXT(sah, chain);
8965
8966 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
8967 && proto != sah->saidx.proto) {
8968 continue;
8969 }
8970
8971 for (stateidx = 0;
8972 stateidx < _ARRAYLEN(saorder_state_alive);
8973 stateidx++) {
8974 state = saorder_state_any[stateidx];
8975 for (sav = LIST_FIRST(&sah->savtree[state]);
8976 sav != NULL;
8977 sav = nextsav) {
8978 nextsav = LIST_NEXT(sav, chain);
8979
8980 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
8981 key_freesav(sav, KEY_SADB_LOCKED);
8982 }
8983 }
8984
8985 sah->state = SADB_SASTATE_DEAD;
8986 }
8987 lck_mtx_unlock(sadb_mutex);
8988
8989 if (m->m_len < sizeof(struct sadb_msg) ||
8990 sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
8991 ipseclog((LOG_DEBUG, "key_flush: No more memory.\n"));
8992 return key_senderror(so, m, ENOBUFS);
8993 }
8994
8995 if (m->m_next) {
8996 m_freem(m->m_next);
8997 }
8998 m->m_next = NULL;
8999 m->m_pkthdr.len = m->m_len = sizeof(struct sadb_msg);
9000 newmsg = mtod(m, struct sadb_msg *);
9001 newmsg->sadb_msg_errno = 0;
9002 VERIFY(PFKEY_UNIT64(m->m_pkthdr.len) <= UINT16_MAX);
9003 newmsg->sadb_msg_len = (uint16_t)PFKEY_UNIT64(m->m_pkthdr.len);
9004
9005 return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
9006}
9007
9008/*
9009 * SADB_DUMP processing
9010 * dump all entries including status of DEAD in SAD.
9011 * receive
9012 * <base>
9013 * from the ikmpd, and dump all secasvar leaves
9014 * and send,
9015 * <base> .....
9016 * to the ikmpd.
9017 *
9018 * m will always be freed.
9019 */
9020
9021struct sav_dump_elem {
9022 struct secasvar *sav;
9023 u_int8_t satype;
9024};
9025
9026static int
9027key_dump(
9028 struct socket *so,
9029 struct mbuf *m,
9030 const struct sadb_msghdr *mhp)
9031{
9032 struct secashead *sah;
9033 struct secasvar *sav;
9034 struct sav_dump_elem *savbuf = NULL, *elem_ptr;
9035 u_int32_t bufcount = 0, cnt = 0, cnt2 = 0;
9036 u_int16_t proto;
9037 u_int stateidx;
9038 u_int8_t satype;
9039 u_int state;
9040 struct mbuf *n;
9041 int error = 0;
9042
9043 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
9044
9045 /* sanity check */
9046 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
9047 panic("key_dump: NULL pointer is passed.");
9048 }
9049
9050 /* map satype to proto */
9051 if ((proto = key_satype2proto(satype: mhp->msg->sadb_msg_satype)) == 0) {
9052 ipseclog((LOG_DEBUG, "key_dump: invalid satype is passed.\n"));
9053 return key_senderror(so, m, EINVAL);
9054 }
9055
9056 if ((bufcount = ipsec_sav_count) == 0) {
9057 error = ENOENT;
9058 goto end;
9059 }
9060
9061 if (os_add_overflow(bufcount, 512, &bufcount)) {
9062 ipseclog((LOG_DEBUG, "key_dump: bufcount overflow, ipsec sa count %u.\n", ipsec_sav_count));
9063 bufcount = ipsec_sav_count;
9064 }
9065
9066 savbuf = kalloc_type(struct sav_dump_elem, bufcount, Z_WAITOK);
9067 if (savbuf == NULL) {
9068 ipseclog((LOG_DEBUG, "key_dump: No more memory.\n"));
9069 error = ENOMEM;
9070 goto end;
9071 }
9072
9073 /* count sav entries to be sent to the userland. */
9074 lck_mtx_lock(sadb_mutex);
9075 elem_ptr = savbuf;
9076 LIST_FOREACH(sah, &sahtree, chain) {
9077 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
9078 && proto != sah->saidx.proto) {
9079 continue;
9080 }
9081
9082 /* map proto to satype */
9083 if ((satype = key_proto2satype(proto: sah->saidx.proto)) == 0) {
9084 lck_mtx_unlock(sadb_mutex);
9085 ipseclog((LOG_DEBUG, "key_dump: there was invalid proto in SAD.\n"));
9086 error = EINVAL;
9087 goto end;
9088 }
9089
9090 for (stateidx = 0;
9091 stateidx < _ARRAYLEN(saorder_state_any);
9092 stateidx++) {
9093 state = saorder_state_any[stateidx];
9094 LIST_FOREACH(sav, &sah->savtree[state], chain) {
9095 if (cnt == bufcount) {
9096 break; /* out of buffer space */
9097 }
9098 elem_ptr->sav = sav;
9099 elem_ptr->satype = satype;
9100 sav->refcnt++;
9101 elem_ptr++;
9102 cnt++;
9103 }
9104 }
9105 }
9106 lck_mtx_unlock(sadb_mutex);
9107
9108 if (cnt == 0) {
9109 error = ENOENT;
9110 goto end;
9111 }
9112
9113 /* send this to the userland, one at a time. */
9114 elem_ptr = savbuf;
9115 cnt2 = cnt;
9116 while (cnt2) {
9117 n = key_setdumpsa(sav: elem_ptr->sav, SADB_DUMP, satype: elem_ptr->satype,
9118 seq: --cnt2, pid: mhp->msg->sadb_msg_pid);
9119
9120 if (!n) {
9121 error = ENOBUFS;
9122 goto end;
9123 }
9124
9125 key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
9126 elem_ptr++;
9127 }
9128
9129end:
9130 if (savbuf) {
9131 if (cnt) {
9132 elem_ptr = savbuf;
9133 lck_mtx_lock(sadb_mutex);
9134 while (cnt--) {
9135 key_freesav(sav: (elem_ptr++)->sav, KEY_SADB_LOCKED);
9136 }
9137 lck_mtx_unlock(sadb_mutex);
9138 }
9139 kfree_type(struct sav_dump_elem, bufcount, savbuf);
9140 }
9141
9142 if (error) {
9143 return key_senderror(so, m, error);
9144 }
9145
9146 m_freem(m);
9147 return 0;
9148}
9149
9150/*
9151 * SADB_X_PROMISC processing
9152 *
9153 * m will always be freed.
9154 */
9155static int
9156key_promisc(
9157 struct socket *so,
9158 struct mbuf *m,
9159 const struct sadb_msghdr *mhp)
9160{
9161 int olen;
9162
9163 /* sanity check */
9164 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
9165 panic("key_promisc: NULL pointer is passed.");
9166 }
9167
9168 olen = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len);
9169
9170 if (olen < sizeof(struct sadb_msg)) {
9171#if 1
9172 return key_senderror(so, m, EINVAL);
9173#else
9174 m_freem(m);
9175 return 0;
9176#endif
9177 } else if (olen == sizeof(struct sadb_msg)) {
9178 /* enable/disable promisc mode */
9179 struct keycb *kp;
9180
9181 socket_lock(so, refcount: 1);
9182 if ((kp = (struct keycb *)sotorawcb(so)) == NULL) {
9183 return key_senderror(so, m, EINVAL);
9184 }
9185 mhp->msg->sadb_msg_errno = 0;
9186 switch (mhp->msg->sadb_msg_satype) {
9187 case 0:
9188 case 1:
9189 kp->kp_promisc = mhp->msg->sadb_msg_satype;
9190 break;
9191 default:
9192 socket_unlock(so, refcount: 1);
9193 return key_senderror(so, m, EINVAL);
9194 }
9195 socket_unlock(so, refcount: 1);
9196
9197 /* send the original message back to everyone */
9198 mhp->msg->sadb_msg_errno = 0;
9199 return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
9200 } else {
9201 /* send packet as is */
9202
9203 m_adj(m, PFKEY_ALIGN8(sizeof(struct sadb_msg)));
9204
9205 /* TODO: if sadb_msg_seq is specified, send to specific pid */
9206 return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
9207 }
9208}
9209
9210static int(*const key_typesw[])(struct socket *, struct mbuf *,
9211 const struct sadb_msghdr *) = {
9212 NULL, /* SADB_RESERVED */
9213 key_getspi, /* SADB_GETSPI */
9214 key_update, /* SADB_UPDATE */
9215 key_add, /* SADB_ADD */
9216 key_delete, /* SADB_DELETE */
9217 key_get, /* SADB_GET */
9218 key_acquire2, /* SADB_ACQUIRE */
9219 key_register, /* SADB_REGISTER */
9220 NULL, /* SADB_EXPIRE */
9221 key_flush, /* SADB_FLUSH */
9222 key_dump, /* SADB_DUMP */
9223 key_promisc, /* SADB_X_PROMISC */
9224 NULL, /* SADB_X_PCHANGE */
9225 key_spdadd, /* SADB_X_SPDUPDATE */
9226 key_spdadd, /* SADB_X_SPDADD */
9227 key_spddelete, /* SADB_X_SPDDELETE */
9228 key_spdget, /* SADB_X_SPDGET */
9229 NULL, /* SADB_X_SPDACQUIRE */
9230 key_spddump, /* SADB_X_SPDDUMP */
9231 key_spdflush, /* SADB_X_SPDFLUSH */
9232 key_spdadd, /* SADB_X_SPDSETIDX */
9233 NULL, /* SADB_X_SPDEXPIRE */
9234 key_spddelete2, /* SADB_X_SPDDELETE2 */
9235 key_getsastat, /* SADB_GETSASTAT */
9236 key_spdenable, /* SADB_X_SPDENABLE */
9237 key_spddisable, /* SADB_X_SPDDISABLE */
9238 key_migrate, /* SADB_MIGRATE */
9239};
9240
9241static void
9242bzero_mbuf(struct mbuf *m)
9243{
9244 struct mbuf *mptr = m;
9245 struct sadb_msg *msg = NULL;
9246 int offset = 0;
9247
9248 if (!mptr) {
9249 return;
9250 }
9251
9252 if (mptr->m_len >= sizeof(struct sadb_msg)) {
9253 msg = mtod(mptr, struct sadb_msg *);
9254 if (msg->sadb_msg_type != SADB_ADD &&
9255 msg->sadb_msg_type != SADB_UPDATE) {
9256 return;
9257 }
9258 offset = sizeof(struct sadb_msg);
9259 }
9260 bzero(s: m_mtod_current(m: mptr) + offset, n: mptr->m_len - offset);
9261 mptr = mptr->m_next;
9262 while (mptr != NULL) {
9263 bzero(s: m_mtod_current(m: mptr), n: mptr->m_len);
9264 mptr = mptr->m_next;
9265 }
9266}
9267
9268static void
9269bzero_keys(const struct sadb_msghdr *mh)
9270{
9271 int extlen = 0;
9272 int offset = 0;
9273
9274 if (!mh) {
9275 return;
9276 }
9277 offset = sizeof(struct sadb_key);
9278
9279 if (mh->ext[SADB_EXT_KEY_ENCRYPT]) {
9280 struct sadb_key *key = (struct sadb_key*)mh->ext[SADB_EXT_KEY_ENCRYPT];
9281 extlen = key->sadb_key_bits >> 3;
9282
9283 if (mh->extlen[SADB_EXT_KEY_ENCRYPT] >= offset + extlen) {
9284 bzero(s: (uint8_t *)mh->ext[SADB_EXT_KEY_ENCRYPT] + offset, n: extlen);
9285 } else {
9286 bzero(s: mh->ext[SADB_EXT_KEY_ENCRYPT], n: mh->extlen[SADB_EXT_KEY_ENCRYPT]);
9287 }
9288 }
9289 if (mh->ext[SADB_EXT_KEY_AUTH]) {
9290 struct sadb_key *key = (struct sadb_key*)mh->ext[SADB_EXT_KEY_AUTH];
9291 extlen = key->sadb_key_bits >> 3;
9292
9293 if (mh->extlen[SADB_EXT_KEY_AUTH] >= offset + extlen) {
9294 bzero(s: (uint8_t *)mh->ext[SADB_EXT_KEY_AUTH] + offset, n: extlen);
9295 } else {
9296 bzero(s: mh->ext[SADB_EXT_KEY_AUTH], n: mh->extlen[SADB_EXT_KEY_AUTH]);
9297 }
9298 }
9299}
9300
9301static int
9302key_validate_address_pair(struct sadb_address *src0,
9303 struct sadb_address *dst0)
9304{
9305 u_int plen = 0;
9306
9307 /* check upper layer protocol */
9308 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
9309 ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n"));
9310 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9311 return EINVAL;
9312 }
9313
9314 /* check family */
9315 if (PFKEY_ADDR_SADDR(src0)->sa_family !=
9316 PFKEY_ADDR_SADDR(dst0)->sa_family) {
9317 ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n"));
9318 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9319 return EINVAL;
9320 }
9321 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
9322 PFKEY_ADDR_SADDR(dst0)->sa_len) {
9323 ipseclog((LOG_DEBUG,
9324 "key_parse: address struct size mismatched.\n"));
9325 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9326 return EINVAL;
9327 }
9328
9329 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
9330 case AF_INET:
9331 if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in)) {
9332 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9333 return EINVAL;
9334 }
9335 break;
9336 case AF_INET6:
9337 if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in6)) {
9338 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9339 return EINVAL;
9340 }
9341 break;
9342 default:
9343 ipseclog((LOG_DEBUG,
9344 "key_parse: unsupported address family.\n"));
9345 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9346 return EAFNOSUPPORT;
9347 }
9348
9349 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
9350 case AF_INET:
9351 plen = sizeof(struct in_addr) << 3;
9352 break;
9353 case AF_INET6:
9354 plen = sizeof(struct in6_addr) << 3;
9355 break;
9356 default:
9357 plen = 0; /*fool gcc*/
9358 break;
9359 }
9360
9361 /* check max prefix length */
9362 if (src0->sadb_address_prefixlen > plen ||
9363 dst0->sadb_address_prefixlen > plen) {
9364 ipseclog((LOG_DEBUG,
9365 "key_parse: illegal prefixlen.\n"));
9366 PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
9367 return EINVAL;
9368 }
9369
9370 /*
9371 * prefixlen == 0 is valid because there can be a case when
9372 * all addresses are matched.
9373 */
9374 return 0;
9375}
9376
9377/*
9378 * parse sadb_msg buffer to process PFKEYv2,
9379 * and create a data to response if needed.
9380 * I think to be dealed with mbuf directly.
9381 * IN:
9382 * msgp : pointer to pointer to a received buffer pulluped.
9383 * This is rewrited to response.
9384 * so : pointer to socket.
9385 * OUT:
9386 * length for buffer to send to user process.
9387 */
9388int
9389key_parse(
9390 struct mbuf *m,
9391 struct socket *so)
9392{
9393 struct sadb_msg *msg;
9394 struct sadb_msghdr mh;
9395 u_int orglen;
9396 int error;
9397 int target;
9398 Boolean keyAligned = FALSE;
9399
9400 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
9401
9402 /* sanity check */
9403 if (m == NULL || so == NULL) {
9404 panic("key_parse: NULL pointer is passed.");
9405 }
9406
9407#if 0 /*kdebug_sadb assumes msg in linear buffer*/
9408 KEYDEBUG(KEYDEBUG_KEY_DUMP,
9409 ipseclog((LOG_DEBUG, "key_parse: passed sadb_msg\n"));
9410 kdebug_sadb(msg));
9411#endif
9412
9413 if (m->m_len < sizeof(struct sadb_msg)) {
9414 m = m_pullup(m, sizeof(struct sadb_msg));
9415 if (!m) {
9416 return ENOBUFS;
9417 }
9418 }
9419 msg = mtod(m, struct sadb_msg *);
9420 orglen = PFKEY_UNUNIT64(msg->sadb_msg_len);
9421 target = KEY_SENDUP_ONE;
9422
9423 if ((m->m_flags & M_PKTHDR) == 0 ||
9424 m->m_pkthdr.len != orglen) {
9425 ipseclog((LOG_DEBUG, "key_parse: invalid message length.\n"));
9426 PFKEY_STAT_INCREMENT(pfkeystat.out_invlen);
9427 error = EINVAL;
9428 goto senderror;
9429 }
9430
9431 if (msg->sadb_msg_version != PF_KEY_V2) {
9432 ipseclog((LOG_DEBUG,
9433 "key_parse: PF_KEY version %u is mismatched.\n",
9434 msg->sadb_msg_version));
9435 PFKEY_STAT_INCREMENT(pfkeystat.out_invver);
9436 error = EINVAL;
9437 goto senderror;
9438 }
9439
9440 if (msg->sadb_msg_type > SADB_MAX) {
9441 ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n",
9442 msg->sadb_msg_type));
9443 PFKEY_STAT_INCREMENT(pfkeystat.out_invmsgtype);
9444 error = EINVAL;
9445 goto senderror;
9446 }
9447
9448 /* for old-fashioned code - should be nuked */
9449 if (m->m_pkthdr.len > MCLBYTES) {
9450 m_freem(m);
9451 return ENOBUFS;
9452 }
9453 if (m->m_next) {
9454 struct mbuf *n;
9455
9456 MGETHDR(n, M_WAITOK, MT_DATA);
9457 if (n && m->m_pkthdr.len > MHLEN) {
9458 MCLGET(n, M_WAITOK);
9459 if ((n->m_flags & M_EXT) == 0) {
9460 m_free(n);
9461 n = NULL;
9462 }
9463 }
9464 if (!n) {
9465 bzero_mbuf(m);
9466 m_freem(m);
9467 return ENOBUFS;
9468 }
9469 m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
9470 n->m_pkthdr.len = n->m_len = m->m_pkthdr.len;
9471 n->m_next = NULL;
9472 bzero_mbuf(m);
9473 m_freem(m);
9474 m = n;
9475 }
9476
9477 /* align the mbuf chain so that extensions are in contiguous region. */
9478 error = key_align(m, &mh);
9479 if (error) {
9480 return error;
9481 }
9482
9483 if (m->m_next) { /*XXX*/
9484 bzero_mbuf(m);
9485 m_freem(m);
9486 return ENOBUFS;
9487 }
9488
9489 keyAligned = TRUE;
9490 msg = mh.msg;
9491
9492 /* check SA type */
9493 switch (msg->sadb_msg_satype) {
9494 case SADB_SATYPE_UNSPEC:
9495 switch (msg->sadb_msg_type) {
9496 case SADB_GETSPI:
9497 case SADB_UPDATE:
9498 case SADB_ADD:
9499 case SADB_DELETE:
9500 case SADB_GET:
9501 case SADB_ACQUIRE:
9502 case SADB_EXPIRE:
9503 ipseclog((LOG_DEBUG, "key_parse: must specify satype "
9504 "when msg type=%u.\n", msg->sadb_msg_type));
9505 PFKEY_STAT_INCREMENT(pfkeystat.out_invsatype);
9506 error = EINVAL;
9507 goto senderror;
9508 }
9509 break;
9510 case SADB_SATYPE_AH:
9511 case SADB_SATYPE_ESP:
9512 switch (msg->sadb_msg_type) {
9513 case SADB_X_SPDADD:
9514 case SADB_X_SPDDELETE:
9515 case SADB_X_SPDGET:
9516 case SADB_X_SPDDUMP:
9517 case SADB_X_SPDFLUSH:
9518 case SADB_X_SPDSETIDX:
9519 case SADB_X_SPDUPDATE:
9520 case SADB_X_SPDDELETE2:
9521 case SADB_X_SPDENABLE:
9522 case SADB_X_SPDDISABLE:
9523 ipseclog((LOG_DEBUG, "key_parse: illegal satype=%u\n",
9524 msg->sadb_msg_type));
9525 PFKEY_STAT_INCREMENT(pfkeystat.out_invsatype);
9526 error = EINVAL;
9527 goto senderror;
9528 }
9529 break;
9530 case SADB_SATYPE_RSVP:
9531 case SADB_SATYPE_OSPFV2:
9532 case SADB_SATYPE_RIPV2:
9533 case SADB_SATYPE_MIP:
9534 ipseclog((LOG_DEBUG, "key_parse: type %u isn't supported.\n",
9535 msg->sadb_msg_satype));
9536 PFKEY_STAT_INCREMENT(pfkeystat.out_invsatype);
9537 error = EOPNOTSUPP;
9538 goto senderror;
9539 case 1: /* XXX: What does it do? */
9540 if (msg->sadb_msg_type == SADB_X_PROMISC) {
9541 break;
9542 }
9543 OS_FALLTHROUGH;
9544 default:
9545 ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n",
9546 msg->sadb_msg_satype));
9547 PFKEY_STAT_INCREMENT(pfkeystat.out_invsatype);
9548 error = EINVAL;
9549 goto senderror;
9550 }
9551
9552 /* Validate address fields for matching families, lengths, etc. */
9553 void *src0 = mh.ext[SADB_EXT_ADDRESS_SRC];
9554 void *dst0 = mh.ext[SADB_EXT_ADDRESS_DST];
9555 if (mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_START] != NULL &&
9556 mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_END] != NULL) {
9557 error = key_validate_address_pair(src0: (struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_START]),
9558 dst0: (struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_END]));
9559 if (error != 0) {
9560 goto senderror;
9561 }
9562
9563 if (src0 == NULL) {
9564 src0 = mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_START];
9565 }
9566 }
9567 if (mh.ext[SADB_X_EXT_ADDR_RANGE_DST_START] != NULL &&
9568 mh.ext[SADB_X_EXT_ADDR_RANGE_DST_END] != NULL) {
9569 error = key_validate_address_pair(src0: (struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_DST_START]),
9570 dst0: (struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_DST_END]));
9571 if (error != 0) {
9572 goto senderror;
9573 }
9574
9575 if (dst0 == NULL) {
9576 dst0 = mh.ext[SADB_X_EXT_ADDR_RANGE_DST_START];
9577 }
9578 }
9579 if (src0 != NULL && dst0 != NULL) {
9580 error = key_validate_address_pair(src0: (struct sadb_address *)(src0),
9581 dst0: (struct sadb_address *)(dst0));
9582 if (error != 0) {
9583 goto senderror;
9584 }
9585 }
9586
9587 void *migrate_src = mh.ext[SADB_EXT_MIGRATE_ADDRESS_SRC];
9588 void *migrate_dst = mh.ext[SADB_EXT_MIGRATE_ADDRESS_DST];
9589 if (migrate_src != NULL && migrate_dst != NULL) {
9590 error = key_validate_address_pair(src0: (struct sadb_address *)(migrate_src),
9591 dst0: (struct sadb_address *)(migrate_dst));
9592 if (error != 0) {
9593 goto senderror;
9594 }
9595 }
9596
9597 if (msg->sadb_msg_type >= sizeof(key_typesw) / sizeof(key_typesw[0]) ||
9598 key_typesw[msg->sadb_msg_type] == NULL) {
9599 PFKEY_STAT_INCREMENT(pfkeystat.out_invmsgtype);
9600 error = EINVAL;
9601 goto senderror;
9602 }
9603
9604 error = (*key_typesw[msg->sadb_msg_type])(so, m, &mh);
9605
9606 return error;
9607
9608senderror:
9609 if (keyAligned) {
9610 bzero_keys(mh: &mh);
9611 } else {
9612 bzero_mbuf(m);
9613 }
9614 msg->sadb_msg_errno = (u_int8_t)error;
9615 return key_sendup_mbuf(so, m, target);
9616}
9617
9618static int
9619key_senderror(
9620 struct socket *so,
9621 struct mbuf *m,
9622 int code)
9623{
9624 struct sadb_msg *msg;
9625
9626 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
9627
9628 if (m->m_len < sizeof(struct sadb_msg)) {
9629 panic("invalid mbuf passed to key_senderror");
9630 }
9631
9632 msg = mtod(m, struct sadb_msg *);
9633 msg->sadb_msg_errno = (u_int8_t)code;
9634 return key_sendup_mbuf(so, m, KEY_SENDUP_ONE);
9635}
9636
9637/*
9638 * set the pointer to each header into message buffer.
9639 * m will be freed on error.
9640 * XXX larger-than-MCLBYTES extension?
9641 */
9642static int
9643key_align(
9644 struct mbuf *m,
9645 struct sadb_msghdr *mhp)
9646{
9647 struct mbuf *n;
9648 struct sadb_ext *ext;
9649 size_t end;
9650 int off, extlen;
9651 int toff;
9652
9653 /* sanity check */
9654 if (m == NULL || mhp == NULL) {
9655 panic("key_align: NULL pointer is passed.");
9656 }
9657 if (m->m_len < sizeof(struct sadb_msg)) {
9658 panic("invalid mbuf passed to key_align");
9659 }
9660
9661 /* initialize */
9662 bzero(s: mhp, n: sizeof(*mhp));
9663
9664 mhp->msg = mtod(m, struct sadb_msg *);
9665 mhp->ext[0] = (struct sadb_ext *)mhp->msg; /*XXX backward compat */
9666
9667 end = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len);
9668 extlen = (int)end; /*just in case extlen is not updated*/
9669 for (off = sizeof(struct sadb_msg); off < end; off += extlen) {
9670 n = m_pulldown(m, off, sizeof(struct sadb_ext), &toff);
9671 if (!n) {
9672 /* m is already freed */
9673 return ENOBUFS;
9674 }
9675 ext = (struct sadb_ext *)(void *)(mtod(n, caddr_t) + toff);
9676
9677 /* set pointer */
9678 switch (ext->sadb_ext_type) {
9679 case SADB_EXT_SA:
9680 case SADB_EXT_ADDRESS_SRC:
9681 case SADB_EXT_ADDRESS_DST:
9682 case SADB_EXT_ADDRESS_PROXY:
9683 case SADB_EXT_LIFETIME_CURRENT:
9684 case SADB_EXT_LIFETIME_HARD:
9685 case SADB_EXT_LIFETIME_SOFT:
9686 case SADB_EXT_KEY_AUTH:
9687 case SADB_EXT_KEY_ENCRYPT:
9688 case SADB_EXT_IDENTITY_SRC:
9689 case SADB_EXT_IDENTITY_DST:
9690 case SADB_EXT_SENSITIVITY:
9691 case SADB_EXT_PROPOSAL:
9692 case SADB_EXT_SUPPORTED_AUTH:
9693 case SADB_EXT_SUPPORTED_ENCRYPT:
9694 case SADB_EXT_SPIRANGE:
9695 case SADB_X_EXT_POLICY:
9696 case SADB_X_EXT_SA2:
9697 case SADB_EXT_SESSION_ID:
9698 case SADB_EXT_SASTAT:
9699 case SADB_X_EXT_IPSECIF:
9700 case SADB_X_EXT_ADDR_RANGE_SRC_START:
9701 case SADB_X_EXT_ADDR_RANGE_SRC_END:
9702 case SADB_X_EXT_ADDR_RANGE_DST_START:
9703 case SADB_X_EXT_ADDR_RANGE_DST_END:
9704 case SADB_EXT_MIGRATE_ADDRESS_SRC:
9705 case SADB_EXT_MIGRATE_ADDRESS_DST:
9706 case SADB_X_EXT_MIGRATE_IPSECIF:
9707 /* duplicate check */
9708 /*
9709 * XXX Are there duplication payloads of either
9710 * KEY_AUTH or KEY_ENCRYPT ?
9711 */
9712 if (mhp->ext[ext->sadb_ext_type] != NULL) {
9713 ipseclog((LOG_DEBUG,
9714 "key_align: duplicate ext_type %u "
9715 "is passed.\n", ext->sadb_ext_type));
9716 bzero_mbuf(m);
9717 m_freem(m);
9718 PFKEY_STAT_INCREMENT(pfkeystat.out_dupext);
9719 return EINVAL;
9720 }
9721 break;
9722 default:
9723 ipseclog((LOG_DEBUG,
9724 "key_align: invalid ext_type %u is passed.\n",
9725 ext->sadb_ext_type));
9726 bzero_mbuf(m);
9727 m_freem(m);
9728 PFKEY_STAT_INCREMENT(pfkeystat.out_invexttype);
9729 return EINVAL;
9730 }
9731
9732 extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
9733 if (off + extlen > end) {
9734 ipseclog((LOG_DEBUG,
9735 "key_align: ext type %u invalid ext length %d "
9736 "offset %d sadb message total len %zu is passed.\n",
9737 ext->sadb_ext_type, extlen, off, end));
9738 bzero_mbuf(m);
9739 m_freem(m);
9740 PFKEY_STAT_INCREMENT(pfkeystat.out_invlen);
9741 return EINVAL;
9742 }
9743
9744 if (key_validate_ext(ext, extlen)) {
9745 bzero_mbuf(m);
9746 m_freem(m);
9747 PFKEY_STAT_INCREMENT(pfkeystat.out_invlen);
9748 return EINVAL;
9749 }
9750
9751 n = m_pulldown(m, off, extlen, &toff);
9752 if (!n) {
9753 /* m is already freed */
9754 return ENOBUFS;
9755 }
9756 ext = (struct sadb_ext *)(void *)(mtod(n, caddr_t) + toff);
9757
9758 mhp->ext[ext->sadb_ext_type] = ext;
9759 mhp->extoff[ext->sadb_ext_type] = off;
9760 mhp->extlen[ext->sadb_ext_type] = extlen;
9761 }
9762
9763 if (off != end) {
9764 bzero_mbuf(m);
9765 m_freem(m);
9766 PFKEY_STAT_INCREMENT(pfkeystat.out_invlen);
9767 return EINVAL;
9768 }
9769
9770 return 0;
9771}
9772
9773static int
9774key_validate_ext(
9775 const struct sadb_ext *ext,
9776 int len)
9777{
9778 struct sockaddr *sa;
9779 enum { NONE, ADDR } checktype = NONE;
9780 int baselen = 0;
9781 const int sal = offsetof(struct sockaddr, sa_len) + sizeof(sa->sa_len);
9782
9783 if (len != PFKEY_UNUNIT64(ext->sadb_ext_len)) {
9784 return EINVAL;
9785 }
9786
9787 /* if it does not match minimum/maximum length, bail */
9788 if (ext->sadb_ext_type >= sizeof(minsize) / sizeof(minsize[0]) ||
9789 ext->sadb_ext_type >= sizeof(maxsize) / sizeof(maxsize[0])) {
9790 return EINVAL;
9791 }
9792 if (!minsize[ext->sadb_ext_type] || len < minsize[ext->sadb_ext_type]) {
9793 return EINVAL;
9794 }
9795 if (maxsize[ext->sadb_ext_type] && len > maxsize[ext->sadb_ext_type]) {
9796 return EINVAL;
9797 }
9798
9799 /* more checks based on sadb_ext_type XXX need more */
9800 switch (ext->sadb_ext_type) {
9801 case SADB_EXT_ADDRESS_SRC:
9802 case SADB_EXT_ADDRESS_DST:
9803 case SADB_EXT_ADDRESS_PROXY:
9804 case SADB_X_EXT_ADDR_RANGE_SRC_START:
9805 case SADB_X_EXT_ADDR_RANGE_SRC_END:
9806 case SADB_X_EXT_ADDR_RANGE_DST_START:
9807 case SADB_X_EXT_ADDR_RANGE_DST_END:
9808 case SADB_EXT_MIGRATE_ADDRESS_SRC:
9809 case SADB_EXT_MIGRATE_ADDRESS_DST:
9810 baselen = PFKEY_ALIGN8(sizeof(struct sadb_address));
9811 checktype = ADDR;
9812 break;
9813 case SADB_EXT_IDENTITY_SRC:
9814 case SADB_EXT_IDENTITY_DST:
9815 if (((struct sadb_ident *)(uintptr_t)(size_t)ext)->
9816 sadb_ident_type == SADB_X_IDENTTYPE_ADDR) {
9817 baselen = PFKEY_ALIGN8(sizeof(struct sadb_ident));
9818 checktype = ADDR;
9819 } else {
9820 checktype = NONE;
9821 }
9822 break;
9823 default:
9824 checktype = NONE;
9825 break;
9826 }
9827
9828 switch (checktype) {
9829 case NONE:
9830 break;
9831 case ADDR:
9832 sa = (struct sockaddr *)((caddr_t)(uintptr_t)ext + baselen);
9833
9834 if (len < baselen + sal) {
9835 return EINVAL;
9836 }
9837 if (baselen + PFKEY_ALIGN8(sa->sa_len) != len) {
9838 return EINVAL;
9839 }
9840 break;
9841 }
9842
9843 /* check key bits length */
9844 if (ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
9845 ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
9846 struct sadb_key *key = (struct sadb_key *)(uintptr_t)ext;
9847 if (len < (sizeof(struct sadb_key) + _KEYLEN(key))) {
9848 return EINVAL;
9849 }
9850 }
9851
9852 return 0;
9853}
9854
9855/*
9856 * XXX: maybe This function is called after INBOUND IPsec processing.
9857 *
9858 * Special check for tunnel-mode packets.
9859 * We must make some checks for consistency between inner and outer IP header.
9860 *
9861 * xxx more checks to be provided
9862 */
9863int
9864key_checktunnelsanity(
9865 struct secasvar *sav,
9866 __unused u_int family,
9867 __unused caddr_t src,
9868 __unused caddr_t dst)
9869{
9870 /* sanity check */
9871 if (sav->sah == NULL) {
9872 panic("sav->sah == NULL at key_checktunnelsanity");
9873 }
9874
9875 /* XXX: check inner IP header */
9876
9877 return 1;
9878}
9879
9880/* record data transfer on SA, and update timestamps */
9881void
9882key_sa_recordxfer(
9883 struct secasvar *sav,
9884 size_t byte_count)
9885{
9886 if (!sav) {
9887 panic("key_sa_recordxfer called with sav == NULL");
9888 }
9889 if (!sav->lft_c) {
9890 return;
9891 }
9892
9893 lck_mtx_lock(sadb_mutex);
9894 /*
9895 * XXX Currently, there is a difference of bytes size
9896 * between inbound and outbound processing.
9897 */
9898 sav->lft_c->sadb_lifetime_bytes += byte_count;
9899 /* to check bytes lifetime is done in key_timehandler(). */
9900
9901 /*
9902 * We use the number of packets as the unit of
9903 * sadb_lifetime_allocations. We increment the variable
9904 * whenever {esp,ah}_{in,out}put is called.
9905 */
9906 sav->lft_c->sadb_lifetime_allocations++;
9907 /* XXX check for expires? */
9908
9909 /*
9910 * NOTE: We record CURRENT sadb_lifetime_usetime by using mach_continuous_time,
9911 * in nanoseconds. HARD and SOFT lifetime are measured by the time difference
9912 * from sadb_lifetime_usetime.
9913 *
9914 * usetime
9915 * v expire expire
9916 * -----+-----+--------+---> t
9917 * <--------------> HARD
9918 * <-----> SOFT
9919 */
9920 sav->lft_c->sadb_lifetime_usetime = key_get_continuous_time_ns();
9921 /* XXX check for expires? */
9922 lck_mtx_unlock(sadb_mutex);
9923
9924 return;
9925}
9926
9927/* dumb version */
9928void
9929key_sa_routechange(
9930 struct sockaddr *dst)
9931{
9932 struct secashead *sah;
9933 struct route *ro;
9934
9935 lck_mtx_lock(sadb_mutex);
9936 LIST_FOREACH(sah, &sahtree, chain) {
9937 ro = (struct route *)&sah->sa_route;
9938 if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
9939 && bcmp(s1: dst, s2: &ro->ro_dst, n: dst->sa_len) == 0) {
9940 ROUTE_RELEASE(ro);
9941 }
9942 }
9943 lck_mtx_unlock(sadb_mutex);
9944
9945 return;
9946}
9947
9948void
9949key_sa_chgstate(
9950 struct secasvar *sav,
9951 u_int8_t state)
9952{
9953 if (sav == NULL) {
9954 panic("key_sa_chgstate called with sav == NULL");
9955 }
9956
9957 if (sav->state == state) {
9958 return;
9959 }
9960
9961 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
9962
9963 if (__LIST_CHAINED(sav)) {
9964 LIST_REMOVE(sav, chain);
9965 }
9966
9967 sav->state = state;
9968 LIST_INSERT_HEAD(&sav->sah->savtree[state], sav, chain);
9969}
9970
9971void
9972key_sa_stir_iv(
9973 struct secasvar *sav)
9974{
9975 lck_mtx_lock(sadb_mutex);
9976 if (!sav->iv) {
9977 panic("key_sa_stir_iv called with sav == NULL");
9978 }
9979 key_randomfill(p: sav->iv, l: sav->ivlen);
9980 lck_mtx_unlock(sadb_mutex);
9981}
9982
9983/* XXX too much? */
9984static struct mbuf *
9985key_alloc_mbuf(
9986 int l)
9987{
9988 struct mbuf *m = NULL, *n;
9989 int len, t;
9990
9991 len = l;
9992 while (len > 0) {
9993 MGET(n, M_DONTWAIT, MT_DATA);
9994 if (n && len > MLEN) {
9995 MCLGET(n, M_DONTWAIT);
9996 }
9997 if (!n) {
9998 m_freem(m);
9999 return NULL;
10000 }
10001
10002 n->m_next = NULL;
10003 n->m_len = 0;
10004 n->m_len = (int)M_TRAILINGSPACE(n);
10005 /* use the bottom of mbuf, hoping we can prepend afterwards */
10006 if (n->m_len > len) {
10007 t = (n->m_len - len) & ~(sizeof(long) - 1);
10008 n->m_data += t;
10009 n->m_len = len;
10010 }
10011
10012 len -= n->m_len;
10013
10014 if (m) {
10015 m_cat(m, n);
10016 } else {
10017 m = n;
10018 }
10019 }
10020
10021 return m;
10022}
10023
10024static struct mbuf *
10025key_setdumpsastats(u_int32_t dir,
10026 struct sastat *stats,
10027 u_int32_t max_stats,
10028 u_int64_t session_ids[],
10029 u_int32_t seq,
10030 u_int32_t pid)
10031{
10032 struct mbuf *result = NULL, *m = NULL;
10033
10034 m = key_setsadbmsg(SADB_GETSASTAT, tlen: 0, satype: 0, seq, pid, reserved: 0);
10035 if (!m) {
10036 goto fail;
10037 }
10038 result = m;
10039
10040 m = key_setsadbsession_id(session_ids);
10041 if (!m) {
10042 goto fail;
10043 }
10044 m_cat(result, m);
10045
10046 m = key_setsadbsastat(dir,
10047 stats,
10048 max_stats);
10049 if (!m) {
10050 goto fail;
10051 }
10052 m_cat(result, m);
10053
10054 if ((result->m_flags & M_PKTHDR) == 0) {
10055 goto fail;
10056 }
10057
10058 if (result->m_len < sizeof(struct sadb_msg)) {
10059 result = m_pullup(result, sizeof(struct sadb_msg));
10060 if (result == NULL) {
10061 goto fail;
10062 }
10063 }
10064
10065 result->m_pkthdr.len = 0;
10066 for (m = result; m; m = m->m_next) {
10067 result->m_pkthdr.len += m->m_len;
10068 }
10069
10070 if (PFKEY_UNIT64(result->m_pkthdr.len) > UINT16_MAX) {
10071 ipseclog((LOG_ERR, "key_setdumpsastats: length too nbug: %u", result->m_pkthdr.len));
10072 goto fail;
10073 }
10074
10075 mtod(result, struct sadb_msg *)->sadb_msg_len =
10076 (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
10077
10078 return result;
10079
10080fail:
10081 if (result) {
10082 m_freem(result);
10083 }
10084 return NULL;
10085}
10086
10087/*
10088 * SADB_GETSASTAT processing
10089 * dump all stats for matching entries in SAD.
10090 *
10091 * m will always be freed.
10092 */
10093
10094static int
10095key_getsastat(struct socket *so,
10096 struct mbuf *m,
10097 const struct sadb_msghdr *mhp)
10098{
10099 struct sadb_session_id *session_id;
10100 size_t bufsize = 0;
10101 u_int32_t arg_count, res_count;
10102 struct sadb_sastat *sa_stats_arg;
10103 struct sastat *sa_stats_sav = NULL;
10104 struct mbuf *n;
10105 int error = 0;
10106
10107 /* sanity check */
10108 if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) {
10109 panic("%s: NULL pointer is passed.", __FUNCTION__);
10110 }
10111
10112 if (mhp->ext[SADB_EXT_SESSION_ID] == NULL) {
10113 printf("%s: invalid message is passed. missing session-id.\n", __FUNCTION__);
10114 return key_senderror(so, m, EINVAL);
10115 }
10116 if (mhp->extlen[SADB_EXT_SESSION_ID] < sizeof(struct sadb_session_id)) {
10117 printf("%s: invalid message is passed. short session-id.\n", __FUNCTION__);
10118 return key_senderror(so, m, EINVAL);
10119 }
10120 if (mhp->ext[SADB_EXT_SASTAT] == NULL) {
10121 printf("%s: invalid message is passed. missing stat args.\n", __FUNCTION__);
10122 return key_senderror(so, m, EINVAL);
10123 }
10124 if (mhp->extlen[SADB_EXT_SASTAT] < sizeof(*sa_stats_arg)) {
10125 printf("%s: invalid message is passed. short stat args.\n", __FUNCTION__);
10126 return key_senderror(so, m, EINVAL);
10127 }
10128
10129 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
10130
10131 // exit early if there are no active SAs
10132 if (ipsec_sav_count == 0) {
10133 printf("%s: No active SAs.\n", __FUNCTION__);
10134 error = ENOENT;
10135 goto end;
10136 }
10137
10138 if (os_mul_overflow(ipsec_sav_count + 1, sizeof(*sa_stats_sav), &bufsize)) {
10139 panic("key_getsastat bufsize requested memory overflow %u", ipsec_sav_count);
10140 }
10141
10142 sa_stats_sav = (__typeof__(sa_stats_sav))kalloc_data(bufsize, Z_WAITOK | Z_ZERO);
10143 if (sa_stats_sav == NULL) {
10144 printf("%s: No more memory.\n", __FUNCTION__);
10145 error = ENOMEM;
10146 goto end;
10147 }
10148
10149 sa_stats_arg = (__typeof__(sa_stats_arg))
10150 (void *)mhp->ext[SADB_EXT_SASTAT];
10151 arg_count = sa_stats_arg->sadb_sastat_list_len;
10152 // exit early if there are no requested SAs
10153 if (arg_count == 0) {
10154 printf("%s: No SAs requested.\n", __FUNCTION__);
10155 error = ENOENT;
10156 goto end;
10157 }
10158 if (PFKEY_UNUNIT64(sa_stats_arg->sadb_sastat_len) < (sizeof(*sa_stats_arg) +
10159 (arg_count * sizeof(struct sastat)))) {
10160 printf("%s: invalid message is passed. sa stat extlen shorter than requested stat length.\n", __FUNCTION__);
10161 error = EINVAL;
10162 goto end;
10163 }
10164
10165 res_count = 0;
10166
10167 if (key_getsastatbyspi(stat_arg: (struct sastat *)(sa_stats_arg + 1),
10168 max_stat_arg: arg_count,
10169 stat_res: sa_stats_sav,
10170 stat_res_size: bufsize,
10171 max_stat_res: &res_count)) {
10172 printf("%s: Error finding SAs.\n", __FUNCTION__);
10173 error = ENOENT;
10174 goto end;
10175 }
10176 if (!res_count) {
10177 printf("%s: No SAs found.\n", __FUNCTION__);
10178 error = ENOENT;
10179 goto end;
10180 }
10181
10182 session_id = (__typeof__(session_id))
10183 (void *)mhp->ext[SADB_EXT_SESSION_ID];
10184
10185 /* send this to the userland. */
10186 n = key_setdumpsastats(dir: sa_stats_arg->sadb_sastat_dir,
10187 stats: sa_stats_sav,
10188 max_stats: res_count,
10189 session_ids: session_id->sadb_session_id_v,
10190 seq: mhp->msg->sadb_msg_seq,
10191 pid: mhp->msg->sadb_msg_pid);
10192 if (!n) {
10193 printf("%s: No bufs to dump stats.\n", __FUNCTION__);
10194 error = ENOBUFS;
10195 goto end;
10196 }
10197
10198 key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
10199end:
10200 if (sa_stats_sav) {
10201 kfree_data(sa_stats_sav, bufsize);
10202 }
10203
10204 if (error) {
10205 return key_senderror(so, m, code: error);
10206 }
10207
10208 m_freem(m);
10209 return 0;
10210}
10211
10212static void
10213key_update_natt_keepalive_timestamp(struct secasvar *sav_sent,
10214 struct secasvar *sav_update)
10215{
10216 struct secasindex saidx_swap_sent_addr;
10217
10218 // exit early if two SAs are identical, or if sav_update is current
10219 if (sav_sent == sav_update ||
10220 sav_update->natt_last_activity == natt_now) {
10221 return;
10222 }
10223
10224 // assuming that (sav_update->remote_ike_port != 0 && (esp_udp_encap_port & 0xFFFF) != 0)
10225
10226 bzero(s: &saidx_swap_sent_addr, n: sizeof(saidx_swap_sent_addr));
10227 memcpy(dst: &saidx_swap_sent_addr.src, src: &sav_sent->sah->saidx.dst, n: sizeof(saidx_swap_sent_addr.src));
10228 memcpy(dst: &saidx_swap_sent_addr.dst, src: &sav_sent->sah->saidx.src, n: sizeof(saidx_swap_sent_addr.dst));
10229 saidx_swap_sent_addr.proto = sav_sent->sah->saidx.proto;
10230 saidx_swap_sent_addr.mode = sav_sent->sah->saidx.mode;
10231 // we ignore reqid for split-tunnel setups
10232
10233 if (key_cmpsaidx(saidx0: &sav_sent->sah->saidx, saidx1: &sav_update->sah->saidx, CMP_MODE | CMP_PORT) ||
10234 key_cmpsaidx(saidx0: &saidx_swap_sent_addr, saidx1: &sav_update->sah->saidx, CMP_MODE | CMP_PORT)) {
10235 sav_update->natt_last_activity = natt_now;
10236 }
10237}
10238
10239static int
10240key_send_delsp(struct secpolicy *sp)
10241{
10242 struct mbuf *result = NULL, *m;
10243
10244 if (sp == NULL) {
10245 goto fail;
10246 }
10247
10248 /* set msg header */
10249 m = key_setsadbmsg(SADB_X_SPDDELETE, tlen: 0, satype: 0, seq: 0, pid: 0, reserved: 0);
10250 if (!m) {
10251 goto fail;
10252 }
10253 result = m;
10254
10255 /* set sadb_address(es) for source */
10256 if (sp->spidx.src_range.start.ss_len > 0) {
10257 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_START,
10258 saddr: (struct sockaddr *)&sp->spidx.src_range.start, prefixlen: sp->spidx.prefs,
10259 ul_proto: sp->spidx.ul_proto);
10260 if (!m) {
10261 goto fail;
10262 }
10263 m_cat(result, m);
10264
10265 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_END,
10266 saddr: (struct sockaddr *)&sp->spidx.src_range.end, prefixlen: sp->spidx.prefs,
10267 ul_proto: sp->spidx.ul_proto);
10268 if (!m) {
10269 goto fail;
10270 }
10271 m_cat(result, m);
10272 } else {
10273 m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
10274 saddr: (struct sockaddr *)&sp->spidx.src, prefixlen: sp->spidx.prefs,
10275 ul_proto: sp->spidx.ul_proto);
10276 if (!m) {
10277 goto fail;
10278 }
10279 m_cat(result, m);
10280 }
10281
10282 /* set sadb_address(es) for destination */
10283 if (sp->spidx.dst_range.start.ss_len > 0) {
10284 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_START,
10285 saddr: (struct sockaddr *)&sp->spidx.dst_range.start, prefixlen: sp->spidx.prefd,
10286 ul_proto: sp->spidx.ul_proto);
10287 if (!m) {
10288 goto fail;
10289 }
10290 m_cat(result, m);
10291
10292 m = key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_END,
10293 saddr: (struct sockaddr *)&sp->spidx.dst_range.end, prefixlen: sp->spidx.prefd,
10294 ul_proto: sp->spidx.ul_proto);
10295 if (!m) {
10296 goto fail;
10297 }
10298 m_cat(result, m);
10299 } else {
10300 m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
10301 saddr: (struct sockaddr *)&sp->spidx.dst, prefixlen: sp->spidx.prefd,
10302 ul_proto: sp->spidx.ul_proto);
10303 if (!m) {
10304 goto fail;
10305 }
10306 m_cat(result, m);
10307 }
10308
10309 /* set secpolicy */
10310 m = key_sp2msg(sp);
10311 if (!m) {
10312 goto fail;
10313 }
10314 m_cat(result, m);
10315
10316 if ((result->m_flags & M_PKTHDR) == 0) {
10317 goto fail;
10318 }
10319
10320 if (result->m_len < sizeof(struct sadb_msg)) {
10321 result = m_pullup(result, sizeof(struct sadb_msg));
10322 if (result == NULL) {
10323 goto fail;
10324 }
10325 }
10326
10327 result->m_pkthdr.len = 0;
10328 for (m = result; m; m = m->m_next) {
10329 result->m_pkthdr.len += m->m_len;
10330 }
10331
10332 if (PFKEY_UNIT64(result->m_pkthdr.len) >= UINT16_MAX) {
10333 ipseclog((LOG_ERR, "key_send_delsp: length too big: %d", result->m_pkthdr.len));
10334 goto fail;
10335 }
10336
10337 mtod(result, struct sadb_msg *)->sadb_msg_len = (u_int16_t)PFKEY_UNIT64(result->m_pkthdr.len);
10338
10339 return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
10340
10341fail:
10342 if (result) {
10343 m_free(result);
10344 }
10345 return -1;
10346}
10347
10348void
10349key_delsp_for_ipsec_if(ifnet_t ipsec_if)
10350{
10351 struct secashead *sah;
10352 struct secasvar *sav, *nextsav;
10353 u_int stateidx;
10354 u_int state;
10355 struct secpolicy *sp, *nextsp;
10356 int dir;
10357
10358 if (ipsec_if == NULL) {
10359 return;
10360 }
10361
10362 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
10363
10364 lck_mtx_lock(sadb_mutex);
10365
10366 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
10367 for (sp = LIST_FIRST(&sptree[dir]);
10368 sp != NULL;
10369 sp = nextsp) {
10370 nextsp = LIST_NEXT(sp, chain);
10371
10372 if (sp->ipsec_if == ipsec_if) {
10373 ifnet_release(interface: sp->ipsec_if);
10374 sp->ipsec_if = NULL;
10375
10376 key_send_delsp(sp);
10377
10378 sp->state = IPSEC_SPSTATE_DEAD;
10379 key_freesp(sp, KEY_SADB_LOCKED);
10380 }
10381 }
10382 }
10383
10384 LIST_FOREACH(sah, &sahtree, chain) {
10385 if (sah->ipsec_if == ipsec_if) {
10386 /* This SAH is linked to the IPsec interface. It now needs to close. */
10387 ifnet_release(interface: sah->ipsec_if);
10388 sah->ipsec_if = NULL;
10389
10390 for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); stateidx++) {
10391 state = saorder_state_any[stateidx];
10392 for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) {
10393 nextsav = LIST_NEXT(sav, chain);
10394
10395 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
10396 key_freesav(sav, KEY_SADB_LOCKED);
10397 }
10398 }
10399
10400 sah->state = SADB_SASTATE_DEAD;
10401 }
10402 }
10403
10404 lck_mtx_unlock(sadb_mutex);
10405}
10406
10407__private_extern__ u_int32_t
10408key_fill_offload_frames_for_savs(ifnet_t ifp,
10409 struct ifnet_keepalive_offload_frame *frames_array,
10410 u_int32_t frames_array_count,
10411 size_t frame_data_offset)
10412{
10413 struct secashead *sah = NULL;
10414 struct secasvar *sav = NULL;
10415 struct ifnet_keepalive_offload_frame *frame = frames_array;
10416 u_int32_t frame_index = 0;
10417
10418 if (frame == NULL || frames_array_count == 0) {
10419 return frame_index;
10420 }
10421
10422 lck_mtx_lock(sadb_mutex);
10423 LIST_FOREACH(sah, &sahtree, chain) {
10424 LIST_FOREACH(sav, &sah->savtree[SADB_SASTATE_MATURE], chain) {
10425 if (ipsec_fill_offload_frame(ifp, sav, frame, frame_data_offset)) {
10426 frame_index++;
10427 if (frame_index >= frames_array_count) {
10428 lck_mtx_unlock(sadb_mutex);
10429 return frame_index;
10430 }
10431 frame = &(frames_array[frame_index]);
10432 }
10433 }
10434 }
10435 lck_mtx_unlock(sadb_mutex);
10436
10437 return frame_index;
10438}
10439
10440#pragma mark Custom IPsec
10441
10442__private_extern__ bool
10443key_custom_ipsec_token_is_valid(void *ipsec_token)
10444{
10445 if (ipsec_token == NULL) {
10446 return false;
10447 }
10448
10449 struct secashead *sah = (struct secashead *)ipsec_token;
10450
10451 return (sah->flags & SECURITY_ASSOCIATION_CUSTOM_IPSEC) == SECURITY_ASSOCIATION_CUSTOM_IPSEC;
10452}
10453
10454__private_extern__ int
10455key_reserve_custom_ipsec(void **ipsec_token, union sockaddr_in_4_6 *src, union sockaddr_in_4_6 *dst,
10456 u_int8_t proto)
10457{
10458 if (src == NULL || dst == NULL) {
10459 ipseclog((LOG_ERR, "register custom ipsec: invalid address\n"));
10460 return EINVAL;
10461 }
10462
10463 if (src->sa.sa_family != dst->sa.sa_family) {
10464 ipseclog((LOG_ERR, "register custom ipsec: address family mismatched\n"));
10465 return EINVAL;
10466 }
10467
10468 if (src->sa.sa_len != dst->sa.sa_len) {
10469 ipseclog((LOG_ERR, "register custom ipsec: address struct size mismatched\n"));
10470 return EINVAL;
10471 }
10472
10473 if (ipsec_token == NULL) {
10474 ipseclog((LOG_ERR, "register custom ipsec: invalid ipsec token\n"));
10475 return EINVAL;
10476 }
10477
10478 switch (src->sa.sa_family) {
10479 case AF_INET:
10480 if (src->sa.sa_len != sizeof(struct sockaddr_in)) {
10481 ipseclog((LOG_ERR, "register custom esp: invalid address length\n"));
10482 return EINVAL;
10483 }
10484 break;
10485 case AF_INET6:
10486 if (src->sa.sa_len != sizeof(struct sockaddr_in6)) {
10487 ipseclog((LOG_ERR, "register custom esp: invalid address length\n"));
10488 return EINVAL;
10489 }
10490 break;
10491 default:
10492 ipseclog((LOG_ERR, "register custom esp: invalid address length\n"));
10493 return EAFNOSUPPORT;
10494 }
10495
10496 if (proto != IPPROTO_ESP && proto != IPPROTO_AH) {
10497 ipseclog((LOG_ERR, "register custom esp: invalid proto %u\n", proto));
10498 return EINVAL;
10499 }
10500
10501 struct secasindex saidx = {};
10502 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, &src->sa, &dst->sa, 0, &saidx);
10503
10504 lck_mtx_lock(sadb_mutex);
10505
10506 struct secashead *sah = NULL;
10507 if ((sah = key_getsah(saidx: &saidx, SECURITY_ASSOCIATION_ANY)) != NULL) {
10508 lck_mtx_unlock(sadb_mutex);
10509 ipseclog((LOG_ERR, "register custom esp: SA exists\n"));
10510 return EEXIST;
10511 }
10512
10513 if ((sah = key_newsah(saidx: &saidx, NULL, outgoing_if: 0, IPSEC_DIR_ANY, SECURITY_ASSOCIATION_CUSTOM_IPSEC)) == NULL) {
10514 lck_mtx_unlock(sadb_mutex);
10515 ipseclog((LOG_DEBUG, "register custom esp: No more memory.\n"));
10516 return ENOBUFS;
10517 }
10518
10519 *ipsec_token = (void *)sah;
10520
10521 lck_mtx_unlock(sadb_mutex);
10522 return 0;
10523}
10524
10525__private_extern__ void
10526key_release_custom_ipsec(void **ipsec_token)
10527{
10528 struct secashead *sah = *ipsec_token;
10529 VERIFY(sah != NULL);
10530
10531 lck_mtx_lock(sadb_mutex);
10532
10533 VERIFY((sah->flags & SECURITY_ASSOCIATION_CUSTOM_IPSEC) == SECURITY_ASSOCIATION_CUSTOM_IPSEC);
10534
10535 bool sa_present = true;
10536 if (LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]) == NULL &&
10537 LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]) == NULL &&
10538 LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]) == NULL &&
10539 LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]) == NULL) {
10540 sa_present = false;
10541 }
10542 VERIFY(sa_present == false);
10543
10544 key_delsah(sah);
10545
10546 lck_mtx_unlock(sadb_mutex);
10547
10548 *ipsec_token = NULL;
10549 return;
10550}
10551