2 * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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 $ */
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
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.
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
62 * This code is referd to RFC 2367
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>
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>
79 #include <sys/queue.h>
80 #include <sys/syslog.h>
81 #include <sys/mcache.h>
83 #include <kern/locks.h>
86 #include <net/route.h>
87 #include <net/raw_cb.h>
89 #include <netinet/in.h>
90 #include <netinet/in_systm.h>
91 #include <netinet/ip.h>
92 #include <netinet/in_var.h>
95 #include <netinet/ip6.h>
96 #include <netinet6/in6_var.h>
97 #include <netinet6/ip6_var.h>
100 #include <net/pfkeyv2.h>
101 #include <netkey/keydb.h>
102 #include <netkey/key.h>
103 #include <netkey/keysock.h>
104 #include <netkey/key_debug.h>
106 #include <libkern/crypto/rand.h>
108 #include <netinet6/ipsec.h>
110 #include <netinet6/ipsec6.h>
112 #include <netinet6/ah.h>
114 #include <netinet6/ah6.h>
117 #include <netinet6/esp.h>
119 #include <netinet6/esp6.h>
122 #include <netinet6/ipcomp.h>
124 #include <netinet6/ipcomp6.h>
129 #include <sys/random.h>
131 #include <net/net_osdep.h>
133 #define FULLMASK 0xff
135 lck_grp_t
*sadb_mutex_grp
;
136 lck_grp_attr_t
*sadb_mutex_grp_attr
;
137 lck_attr_t
*sadb_mutex_attr
;
138 decl_lck_mtx_data(, sadb_mutex_data
);
139 lck_mtx_t
*sadb_mutex
= &sadb_mutex_data
;
141 lck_grp_t
*pfkey_stat_mutex_grp
;
142 lck_grp_attr_t
*pfkey_stat_mutex_grp_attr
;
143 lck_attr_t
*pfkey_stat_mutex_attr
;
144 decl_lck_mtx_data(, pfkey_stat_mutex_data
);
145 lck_mtx_t
*pfkey_stat_mutex
= &pfkey_stat_mutex_data
;
148 * Note on SA reference counting:
149 * - SAs that are not in DEAD state will have (total external reference + 1)
150 * following value in reference count field. they cannot be freed and are
151 * referenced from SA header.
152 * - SAs that are in DEAD state will have (total external reference)
153 * in reference count field. they are ready to be freed. reference from
154 * SA header will be removed in key_delsav(), when the reference count
155 * field hits 0 (= no external reference other than from SA header.
158 u_int32_t key_debug_level
= 0; //### our sysctl is not dynamic
159 static int key_timehandler_running
= 0;
160 static u_int key_spi_trycnt
= 1000;
161 static u_int32_t key_spi_minval
= 0x100;
162 static u_int32_t key_spi_maxval
= 0x0fffffff; /* XXX */
163 static u_int32_t policy_id
= 0;
164 static u_int key_int_random
= 60; /*interval to initialize randseed,1(m)*/
165 static u_int key_larval_lifetime
= 30; /* interval to expire acquiring, 30(s)*/
166 static int key_blockacq_count
= 10; /* counter for blocking SADB_ACQUIRE.*/
167 static int key_blockacq_lifetime
= 20; /* lifetime for blocking SADB_ACQUIRE.*/
168 static int key_preferred_oldsa
= 0; /* preferred old sa rather than new sa.*/
169 __private_extern__
int natt_keepalive_interval
= 20; /* interval between natt keepalives.*/
170 __private_extern__
int ipsec_policy_count
= 0;
171 static int ipsec_sav_count
= 0;
173 static u_int32_t acq_seq
= 0;
174 static int key_tick_init_random
= 0;
175 static u_int64_t up_time
= 0;
176 __private_extern__ u_int64_t natt_now
= 0;
178 static LIST_HEAD(_sptree
, secpolicy
) sptree
[IPSEC_DIR_MAX
]; /* SPD */
179 static LIST_HEAD(_sahtree
, secashead
) sahtree
; /* SAD */
180 static LIST_HEAD(_regtree
, secreg
) regtree
[SADB_SATYPE_MAX
+ 1];
183 #define SPIHASHSIZE 128
184 #define SPIHASH(x) (((x) ^ ((x) >> 16)) % SPIHASHSIZE)
185 static LIST_HEAD(_spihash
, secasvar
) spihash
[SPIHASHSIZE
];
187 #ifndef IPSEC_NONBLOCK_ACQUIRE
188 static LIST_HEAD(_acqtree
, secacq
) acqtree
; /* acquiring list */
190 static LIST_HEAD(_spacqtree
, secspacq
) spacqtree
; /* SP acquiring list */
192 struct key_cb key_cb
;
194 /* search order for SAs */
195 static const u_int saorder_state_valid_prefer_old
[] = {
196 SADB_SASTATE_DYING
, SADB_SASTATE_MATURE
,
198 static const u_int saorder_state_valid_prefer_new
[] = {
199 SADB_SASTATE_MATURE
, SADB_SASTATE_DYING
,
201 static const u_int saorder_state_alive
[] = {
203 SADB_SASTATE_MATURE
, SADB_SASTATE_DYING
, SADB_SASTATE_LARVAL
205 static const u_int saorder_state_any
[] = {
206 SADB_SASTATE_MATURE
, SADB_SASTATE_DYING
,
207 SADB_SASTATE_LARVAL
, SADB_SASTATE_DEAD
210 static const int minsize
[] = {
211 sizeof(struct sadb_msg
), /* SADB_EXT_RESERVED */
212 sizeof(struct sadb_sa
), /* SADB_EXT_SA */
213 sizeof(struct sadb_lifetime
), /* SADB_EXT_LIFETIME_CURRENT */
214 sizeof(struct sadb_lifetime
), /* SADB_EXT_LIFETIME_HARD */
215 sizeof(struct sadb_lifetime
), /* SADB_EXT_LIFETIME_SOFT */
216 sizeof(struct sadb_address
), /* SADB_EXT_ADDRESS_SRC */
217 sizeof(struct sadb_address
), /* SADB_EXT_ADDRESS_DST */
218 sizeof(struct sadb_address
), /* SADB_EXT_ADDRESS_PROXY */
219 sizeof(struct sadb_key
), /* SADB_EXT_KEY_AUTH */
220 sizeof(struct sadb_key
), /* SADB_EXT_KEY_ENCRYPT */
221 sizeof(struct sadb_ident
), /* SADB_EXT_IDENTITY_SRC */
222 sizeof(struct sadb_ident
), /* SADB_EXT_IDENTITY_DST */
223 sizeof(struct sadb_sens
), /* SADB_EXT_SENSITIVITY */
224 sizeof(struct sadb_prop
), /* SADB_EXT_PROPOSAL */
225 sizeof(struct sadb_supported
), /* SADB_EXT_SUPPORTED_AUTH */
226 sizeof(struct sadb_supported
), /* SADB_EXT_SUPPORTED_ENCRYPT */
227 sizeof(struct sadb_spirange
), /* SADB_EXT_SPIRANGE */
228 0, /* SADB_X_EXT_KMPRIVATE */
229 sizeof(struct sadb_x_policy
), /* SADB_X_EXT_POLICY */
230 sizeof(struct sadb_x_sa2
), /* SADB_X_SA2 */
231 sizeof(struct sadb_session_id
), /* SADB_EXT_SESSION_ID */
232 sizeof(struct sadb_sastat
), /* SADB_EXT_SASTAT */
233 sizeof(struct sadb_x_ipsecif
), /* SADB_X_EXT_IPSECIF */
234 sizeof(struct sadb_address
), /* SADB_X_EXT_ADDR_RANGE_SRC_START */
235 sizeof(struct sadb_address
), /* SADB_X_EXT_ADDR_RANGE_SRC_END */
236 sizeof(struct sadb_address
), /* SADB_X_EXT_ADDR_RANGE_DST_START */
237 sizeof(struct sadb_address
), /* SADB_X_EXT_ADDR_RANGE_DST_END */
238 sizeof(struct sadb_address
), /* SADB_EXT_MIGRATE_ADDRESS_SRC */
239 sizeof(struct sadb_address
), /* SADB_EXT_MIGRATE_ADDRESS_DST */
240 sizeof(struct sadb_x_ipsecif
), /* SADB_X_EXT_MIGRATE_IPSECIF */
242 static const int maxsize
[] = {
243 sizeof(struct sadb_msg
), /* SADB_EXT_RESERVED */
244 sizeof(struct sadb_sa_2
), /* SADB_EXT_SA */
245 sizeof(struct sadb_lifetime
), /* SADB_EXT_LIFETIME_CURRENT */
246 sizeof(struct sadb_lifetime
), /* SADB_EXT_LIFETIME_HARD */
247 sizeof(struct sadb_lifetime
), /* SADB_EXT_LIFETIME_SOFT */
248 0, /* SADB_EXT_ADDRESS_SRC */
249 0, /* SADB_EXT_ADDRESS_DST */
250 0, /* SADB_EXT_ADDRESS_PROXY */
251 0, /* SADB_EXT_KEY_AUTH */
252 0, /* SADB_EXT_KEY_ENCRYPT */
253 0, /* SADB_EXT_IDENTITY_SRC */
254 0, /* SADB_EXT_IDENTITY_DST */
255 0, /* SADB_EXT_SENSITIVITY */
256 0, /* SADB_EXT_PROPOSAL */
257 0, /* SADB_EXT_SUPPORTED_AUTH */
258 0, /* SADB_EXT_SUPPORTED_ENCRYPT */
259 sizeof(struct sadb_spirange
), /* SADB_EXT_SPIRANGE */
260 0, /* SADB_X_EXT_KMPRIVATE */
261 0, /* SADB_X_EXT_POLICY */
262 sizeof(struct sadb_x_sa2
), /* SADB_X_SA2 */
263 0, /* SADB_EXT_SESSION_ID */
264 0, /* SADB_EXT_SASTAT */
265 sizeof(struct sadb_x_ipsecif
), /* SADB_X_EXT_IPSECIF */
266 0, /* SADB_X_EXT_ADDR_RANGE_SRC_START */
267 0, /* SADB_X_EXT_ADDR_RANGE_SRC_END */
268 0, /* SADB_X_EXT_ADDR_RANGE_DST_START */
269 0, /* SADB_X_EXT_ADDR_RANGE_DST_END */
270 0, /* SADB_EXT_MIGRATE_ADDRESS_SRC */
271 0, /* SADB_EXT_MIGRATE_ADDRESS_DST */
272 sizeof(struct sadb_x_ipsecif
), /* SADB_X_EXT_MIGRATE_IPSECIF */
275 static int ipsec_esp_keymin
= 256;
276 static int ipsec_esp_auth
= 0;
277 static int ipsec_ah_keymin
= 128;
279 SYSCTL_DECL(_net_key
);
280 /* Thread safe: no accumulated state */
281 SYSCTL_INT(_net_key
, KEYCTL_DEBUG_LEVEL
, debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
282 &key_debug_level
, 0, "");
285 /* max count of trial for the decision of spi value */
286 SYSCTL_INT(_net_key
, KEYCTL_SPI_TRY
, spi_trycnt
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
287 &key_spi_trycnt
, 0, "");
289 /* minimum spi value to allocate automatically. */
290 SYSCTL_INT(_net_key
, KEYCTL_SPI_MIN_VALUE
, spi_minval
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
291 &key_spi_minval
, 0, "");
293 /* maximun spi value to allocate automatically. */
294 SYSCTL_INT(_net_key
, KEYCTL_SPI_MAX_VALUE
, spi_maxval
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
295 &key_spi_maxval
, 0, "");
297 /* interval to initialize randseed */
298 SYSCTL_INT(_net_key
, KEYCTL_RANDOM_INT
, int_random
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
299 &key_int_random
, 0, "");
301 /* lifetime for larval SA; thread safe due to > compare */
302 SYSCTL_INT(_net_key
, KEYCTL_LARVAL_LIFETIME
, larval_lifetime
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
303 &key_larval_lifetime
, 0, "");
305 /* counter for blocking to send SADB_ACQUIRE to IKEd */
306 SYSCTL_INT(_net_key
, KEYCTL_BLOCKACQ_COUNT
, blockacq_count
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
307 &key_blockacq_count
, 0, "");
309 /* lifetime for blocking to send SADB_ACQUIRE to IKEd: Thread safe, > compare */
310 SYSCTL_INT(_net_key
, KEYCTL_BLOCKACQ_LIFETIME
, blockacq_lifetime
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
311 &key_blockacq_lifetime
, 0, "");
314 SYSCTL_INT(_net_key
, KEYCTL_ESP_AUTH
, esp_auth
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
315 &ipsec_esp_auth
, 0, "");
317 /* minimum ESP key length */
318 SYSCTL_INT(_net_key
, KEYCTL_ESP_KEYMIN
, esp_keymin
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
319 &ipsec_esp_keymin
, 0, "");
321 /* minimum AH key length */
322 SYSCTL_INT(_net_key
, KEYCTL_AH_KEYMIN
, ah_keymin
, CTLFLAG_RW
| CTLFLAG_LOCKED
, \
323 &ipsec_ah_keymin
, 0, "");
325 /* perfered old SA rather than new SA */
326 SYSCTL_INT(_net_key
, KEYCTL_PREFERED_OLDSA
, prefered_oldsa
, CTLFLAG_RW
| CTLFLAG_LOCKED
,\
327 &key_preferred_oldsa
, 0, "");
329 /* time between NATT keepalives in seconds, 0 disabled */
330 SYSCTL_INT(_net_key
, KEYCTL_NATT_KEEPALIVE_INTERVAL
, natt_keepalive_interval
, CTLFLAG_RW
| CTLFLAG_LOCKED
,\
331 &natt_keepalive_interval
, 0, "");
333 /* PF_KEY statistics */
334 SYSCTL_STRUCT(_net_key
, KEYCTL_PFKEYSTAT
, pfkeystat
, CTLFLAG_RD
| CTLFLAG_LOCKED
,\
335 &pfkeystat
, pfkeystat
, "");
338 #define LIST_FOREACH(elm, head, field) \
339 for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field))
341 #define __LIST_CHAINED(elm) \
342 (!((elm)->chain.le_next == NULL && (elm)->chain.le_prev == NULL))
343 #define LIST_INSERT_TAIL(head, elm, type, field) \
345 struct type *curelm = LIST_FIRST(head); \
346 if (curelm == NULL) {\
347 LIST_INSERT_HEAD(head, elm, field); \
349 while (LIST_NEXT(curelm, field)) \
350 curelm = LIST_NEXT(curelm, field);\
351 LIST_INSERT_AFTER(curelm, elm, field);\
355 #define KEY_CHKSASTATE(head, sav, name) \
357 if ((head) != (sav)) { \
358 ipseclog((LOG_DEBUG, "%s: state mismatched (TREE=%d SA=%d)\n", \
359 (name), (head), (sav))); \
364 #define KEY_CHKSPDIR(head, sp, name) \
366 if ((head) != (sp)) { \
367 ipseclog((LOG_DEBUG, "%s: direction mismatched (TREE=%d SP=%d), " \
368 "anyway continue.\n", \
369 (name), (head), (sp))); \
374 #define KMALLOC_WAIT(p, t, n) \
375 ((p) = (t) _MALLOC((u_int32_t)(n), M_SECA, M_WAITOK))
376 #define KMALLOC_NOWAIT(p, t, n) \
377 ((p) = (t) _MALLOC((u_int32_t)(n), M_SECA, M_NOWAIT))
379 _FREE((caddr_t)(p), M_SECA);
381 #define KMALLOC_WAIT(p, t, n) \
383 ((p) = (t)_MALLOC((u_int32_t)(n), M_SECA, M_WAITOK)); \
384 printf("%s %d: %p <- KMALLOC_WAIT(%s, %d)\n", \
385 __FILE__, __LINE__, (p), #t, n); \
387 #define KMALLOC_NOWAIT(p, t, n) \
389 ((p) = (t)_MALLOC((u_int32_t)(n), M_SECA, M_NOWAIT)); \
390 printf("%s %d: %p <- KMALLOC_NOWAIT(%s, %d)\n", \
391 __FILE__, __LINE__, (p), #t, n); \
396 printf("%s %d: %p -> KFREE()\n", __FILE__, __LINE__, (p)); \
397 _FREE((caddr_t)(p), M_SECA); \
402 * set parameters into secpolicyindex buffer.
403 * Must allocate secpolicyindex buffer passed to this function.
405 #define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, ifp, s_s, s_e, d_s, d_e, idx) \
407 bzero((idx), sizeof(struct secpolicyindex)); \
408 (idx)->dir = (_dir); \
409 (idx)->prefs = (ps); \
410 (idx)->prefd = (pd); \
411 (idx)->ul_proto = (ulp); \
412 (idx)->internal_if = (ifp); \
413 if (s) bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len); \
414 if (d) bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len); \
415 if (s_s) bcopy((s_s), &(idx)->src_range.start, ((struct sockaddr *)(s_s))->sa_len); \
416 if (s_e) bcopy((s_e), &(idx)->src_range.end, ((struct sockaddr *)(s_e))->sa_len); \
417 if (d_s) bcopy((d_s), &(idx)->dst_range.start, ((struct sockaddr *)(d_s))->sa_len); \
418 if (d_e) bcopy((d_e), &(idx)->dst_range.end, ((struct sockaddr *)(d_e))->sa_len); \
422 * set parameters into secasindex buffer.
423 * Must allocate secasindex buffer before calling this function.
425 #define KEY_SETSECASIDX(p, m, r, s, d, ifi, idx) \
427 bzero((idx), sizeof(struct secasindex)); \
428 (idx)->proto = (p); \
430 (idx)->reqid = (r); \
431 bcopy((s), &(idx)->src, ((const struct sockaddr *)(s))->sa_len); \
432 bcopy((d), &(idx)->dst, ((const struct sockaddr *)(d))->sa_len); \
433 (idx)->ipsec_ifindex = (ifi); \
438 u_int32_t getspi_count
; /* the avarage of count to try to get new SPI */
442 struct sadb_msg
*msg
;
443 struct sadb_ext
*ext
[SADB_EXT_MAX
+ 1];
444 int extoff
[SADB_EXT_MAX
+ 1];
445 int extlen
[SADB_EXT_MAX
+ 1];
448 static struct secpolicy
*__key_getspbyid(u_int32_t id
);
449 static struct secasvar
*key_do_allocsa_policy(struct secashead
*, u_int
, u_int16_t
);
450 static int key_do_get_translated_port(struct secashead
*, struct secasvar
*, u_int
);
451 static void key_delsp(struct secpolicy
*);
452 static struct secpolicy
*key_getsp(struct secpolicyindex
*);
453 static u_int32_t
key_newreqid(void);
454 static struct mbuf
*key_gather_mbuf(struct mbuf
*,
455 const struct sadb_msghdr
*, int, int, int *);
456 static int key_spdadd(struct socket
*, struct mbuf
*,
457 const struct sadb_msghdr
*);
458 static u_int32_t
key_getnewspid(void);
459 static int key_spddelete(struct socket
*, struct mbuf
*,
460 const struct sadb_msghdr
*);
461 static int key_spddelete2(struct socket
*, struct mbuf
*,
462 const struct sadb_msghdr
*);
463 static int key_spdenable(struct socket
*, struct mbuf
*,
464 const struct sadb_msghdr
*);
465 static int key_spddisable(struct socket
*, struct mbuf
*,
466 const struct sadb_msghdr
*);
467 static int key_spdget(struct socket
*, struct mbuf
*,
468 const struct sadb_msghdr
*);
469 static int key_spdflush(struct socket
*, struct mbuf
*,
470 const struct sadb_msghdr
*);
471 static int key_spddump(struct socket
*, struct mbuf
*,
472 const struct sadb_msghdr
*);
473 static struct mbuf
*key_setdumpsp(struct secpolicy
*,
474 u_int8_t
, u_int32_t
, u_int32_t
);
475 static u_int
key_getspreqmsglen(struct secpolicy
*);
476 static int key_spdexpire(struct secpolicy
*);
477 static struct secashead
*key_newsah(struct secasindex
*, ifnet_t
, u_int
, u_int8_t
);
478 static struct secasvar
*key_newsav(struct mbuf
*,
479 const struct sadb_msghdr
*, struct secashead
*, int *,
481 static struct secashead
*key_getsah(struct secasindex
*);
482 static struct secasvar
*key_checkspidup(struct secasindex
*, u_int32_t
);
483 static void key_setspi
__P((struct secasvar
*, u_int32_t
));
484 static struct secasvar
*key_getsavbyspi(struct secashead
*, u_int32_t
);
485 static int key_setsaval(struct secasvar
*, struct mbuf
*,
486 const struct sadb_msghdr
*);
487 static int key_mature(struct secasvar
*);
488 static struct mbuf
*key_setdumpsa(struct secasvar
*, u_int8_t
,
489 u_int8_t
, u_int32_t
, u_int32_t
);
490 static struct mbuf
*key_setsadbmsg(u_int8_t
, u_int16_t
, u_int8_t
,
491 u_int32_t
, pid_t
, u_int16_t
);
492 static struct mbuf
*key_setsadbsa(struct secasvar
*);
493 static struct mbuf
*key_setsadbaddr(u_int16_t
,
494 struct sockaddr
*, u_int8_t
, u_int16_t
);
495 static struct mbuf
*key_setsadbipsecif(ifnet_t
, ifnet_t
, ifnet_t
, int);
497 static struct mbuf
*key_setsadbident(u_int16_t
, u_int16_t
, caddr_t
,
500 static struct mbuf
*key_setsadbxsa2(u_int8_t
, u_int32_t
, u_int32_t
, u_int16_t
);
501 static struct mbuf
*key_setsadbxpolicy(u_int16_t
, u_int8_t
,
503 static void *key_newbuf(const void *, u_int
);
505 static int key_ismyaddr6(struct sockaddr_in6
*);
507 static void key_update_natt_keepalive_timestamp(struct secasvar
*, struct secasvar
*);
509 /* flags for key_cmpsaidx() */
510 #define CMP_HEAD 0x1 /* protocol, addresses. */
511 #define CMP_PORT 0x2 /* additionally HEAD, reqid, mode. */
512 #define CMP_REQID 0x4 /* additionally HEAD, reqid. */
513 #define CMP_MODE 0x8 /* additionally mode. */
514 #define CMP_EXACTLY 0xF /* all elements. */
515 static int key_cmpsaidx(struct secasindex
*, struct secasindex
*, int);
517 static int key_cmpspidx_exactly(struct secpolicyindex
*,
518 struct secpolicyindex
*);
519 static int key_cmpspidx_withmask(struct secpolicyindex
*,
520 struct secpolicyindex
*);
521 static int key_sockaddrcmp(struct sockaddr
*, struct sockaddr
*, int);
522 static int key_is_addr_in_range(struct sockaddr_storage
*, struct secpolicyaddrrange
*);
523 static int key_bbcmp(caddr_t
, caddr_t
, u_int
);
524 static void key_srandom(void);
525 static u_int16_t
key_satype2proto(u_int8_t
);
526 static u_int8_t
key_proto2satype(u_int16_t
);
528 static int key_getspi(struct socket
*, struct mbuf
*,
529 const struct sadb_msghdr
*);
530 static u_int32_t
key_do_getnewspi(struct sadb_spirange
*, struct secasindex
*);
531 static int key_update(struct socket
*, struct mbuf
*,
532 const struct sadb_msghdr
*);
534 static struct secasvar
*key_getsavbyseq(struct secashead
*, u_int32_t
);
536 static int key_add(struct socket
*, struct mbuf
*, const struct sadb_msghdr
*);
537 static int key_setident(struct secashead
*, struct mbuf
*,
538 const struct sadb_msghdr
*);
539 static struct mbuf
*key_getmsgbuf_x1(struct mbuf
*, const struct sadb_msghdr
*);
540 static int key_delete(struct socket
*, struct mbuf
*,
541 const struct sadb_msghdr
*);
542 static int key_get(struct socket
*, struct mbuf
*, const struct sadb_msghdr
*);
544 static void key_getcomb_setlifetime(struct sadb_comb
*);
546 static struct mbuf
*key_getcomb_esp(void);
548 static struct mbuf
*key_getcomb_ah(void);
549 static struct mbuf
*key_getcomb_ipcomp(void);
550 static struct mbuf
*key_getprop(const struct secasindex
*);
552 static int key_acquire(struct secasindex
*, struct secpolicy
*);
553 #ifndef IPSEC_NONBLOCK_ACQUIRE
554 static struct secacq
*key_newacq(struct secasindex
*);
555 static struct secacq
*key_getacq(struct secasindex
*);
556 static struct secacq
*key_getacqbyseq(u_int32_t
);
558 static struct secspacq
*key_newspacq(struct secpolicyindex
*);
559 static struct secspacq
*key_getspacq(struct secpolicyindex
*);
560 static int key_acquire2(struct socket
*, struct mbuf
*,
561 const struct sadb_msghdr
*);
562 static int key_register(struct socket
*, struct mbuf
*,
563 const struct sadb_msghdr
*);
564 static int key_expire(struct secasvar
*);
565 static int key_flush(struct socket
*, struct mbuf
*,
566 const struct sadb_msghdr
*);
567 static int key_dump(struct socket
*, struct mbuf
*, const struct sadb_msghdr
*);
568 static int key_promisc(struct socket
*, struct mbuf
*,
569 const struct sadb_msghdr
*);
570 static int key_senderror(struct socket
*, struct mbuf
*, int);
571 static int key_validate_ext(const struct sadb_ext
*, int);
572 static int key_align(struct mbuf
*, struct sadb_msghdr
*);
573 static struct mbuf
*key_alloc_mbuf(int);
574 static int key_getsastat (struct socket
*, struct mbuf
*, const struct sadb_msghdr
*);
575 static int key_migrate (struct socket
*, struct mbuf
*, const struct sadb_msghdr
*);
576 static int key_setsaval2(struct secasvar
*sav
,
582 struct sadb_key
*key_auth
,
583 u_int16_t key_auth_len
,
584 struct sadb_key
*key_enc
,
585 u_int16_t key_enc_len
,
590 struct sadb_lifetime
*lifetime_hard
,
591 struct sadb_lifetime
*lifetime_soft
);
592 static void bzero_keys(const struct sadb_msghdr
*);
594 extern int ipsec_bypass
;
595 extern int esp_udp_encap_port
;
596 int ipsec_send_natt_keepalive(struct secasvar
*sav
);
597 bool ipsec_fill_offload_frame(ifnet_t ifp
, struct secasvar
*sav
, struct ifnet_keepalive_offload_frame
*frame
, size_t frame_data_offset
);
599 void key_init(struct protosw
*, struct domain
*);
603 * setup locks, call raw_init(), and then init timer and associated data
607 key_init(struct protosw
*pp
, struct domain
*dp
)
609 static int key_initialized
= 0;
612 VERIFY((pp
->pr_flags
& (PR_INITIALIZED
|PR_ATTACHED
)) == PR_ATTACHED
);
614 _CASSERT(PFKEY_ALIGN8(sizeof(struct sadb_msg
)) <= _MHLEN
);
620 sadb_mutex_grp_attr
= lck_grp_attr_alloc_init();
621 sadb_mutex_grp
= lck_grp_alloc_init("sadb", sadb_mutex_grp_attr
);
622 sadb_mutex_attr
= lck_attr_alloc_init();
624 lck_mtx_init(sadb_mutex
, sadb_mutex_grp
, sadb_mutex_attr
);
626 pfkey_stat_mutex_grp_attr
= lck_grp_attr_alloc_init();
627 pfkey_stat_mutex_grp
= lck_grp_alloc_init("pfkey_stat", pfkey_stat_mutex_grp_attr
);
628 pfkey_stat_mutex_attr
= lck_attr_alloc_init();
630 lck_mtx_init(pfkey_stat_mutex
, pfkey_stat_mutex_grp
, pfkey_stat_mutex_attr
);
632 for (i
= 0; i
< SPIHASHSIZE
; i
++)
633 LIST_INIT(&spihash
[i
]);
637 bzero((caddr_t
)&key_cb
, sizeof(key_cb
));
639 for (i
= 0; i
< IPSEC_DIR_MAX
; i
++) {
640 LIST_INIT(&sptree
[i
]);
642 ipsec_policy_count
= 0;
646 for (i
= 0; i
<= SADB_SATYPE_MAX
; i
++) {
647 LIST_INIT(®tree
[i
]);
651 #ifndef IPSEC_NONBLOCK_ACQUIRE
654 LIST_INIT(&spacqtree
);
658 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
659 ip4_def_policy
.refcnt
++; /*never reclaim this*/
662 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
663 ip6_def_policy
.refcnt
++; /*never reclaim this*/
666 key_timehandler_running
= 0;
668 /* initialize key statistics */
669 keystat
.getspi_count
= 1;
672 printf("IPsec: Initialized Security Association Processing.\n");
677 key_start_timehandler(void)
679 /* must be called while locked */
680 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
681 if (key_timehandler_running
== 0) {
682 key_timehandler_running
= 1;
683 (void)timeout((void *)key_timehandler
, (void *)0, hz
);
686 /* Turn off the ipsec bypass */
687 if (ipsec_bypass
!= 0)
691 /* %%% IPsec policy management */
693 * allocating a SP for OUTBOUND or INBOUND packet.
694 * Must call key_freesp() later.
695 * OUT: NULL: not found
696 * others: found and return the pointer.
700 struct secpolicyindex
*spidx
,
703 struct secpolicy
*sp
;
706 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
709 panic("key_allocsp: NULL pointer is passed.\n");
711 /* check direction */
713 case IPSEC_DIR_INBOUND
:
714 case IPSEC_DIR_OUTBOUND
:
717 panic("key_allocsp: Invalid direction is passed.\n");
721 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
722 printf("*** objects\n");
723 kdebug_secpolicyindex(spidx
));
725 lck_mtx_lock(sadb_mutex
);
726 LIST_FOREACH(sp
, &sptree
[dir
], chain
) {
727 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
728 printf("*** in SPD\n");
729 kdebug_secpolicyindex(&sp
->spidx
));
731 if (sp
->state
== IPSEC_SPSTATE_DEAD
)
734 /* If the policy is disabled, skip */
735 if (sp
->disabled
> 0)
738 /* If the incoming spidx specifies bound if,
739 ignore unbound policies*/
740 if (spidx
->internal_if
!= NULL
741 && (sp
->spidx
.internal_if
== NULL
|| sp
->ipsec_if
== NULL
))
744 if (key_cmpspidx_withmask(&sp
->spidx
, spidx
))
747 lck_mtx_unlock(sadb_mutex
);
752 /* found a SPD entry */
754 sp
->lastused
= tv
.tv_sec
;
756 lck_mtx_unlock(sadb_mutex
);
759 KEY_CHKSPDIR(sp
->spidx
.dir
, dir
, "key_allocsp");
760 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
761 printf("DP key_allocsp cause refcnt++:%d SP:0x%llx\n",
762 sp
->refcnt
, (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
767 * return a policy that matches this particular inbound packet.
772 struct sockaddr
*osrc
,
773 struct sockaddr
*odst
,
774 struct sockaddr
*isrc
,
775 struct sockaddr
*idst
)
777 struct secpolicy
*sp
;
778 const int dir
= IPSEC_DIR_INBOUND
;
780 struct ipsecrequest
*r1
, *r2
, *p
;
781 struct sockaddr
*os
, *od
, *is
, *id
;
782 struct secpolicyindex spidx
;
784 if (isrc
->sa_family
!= idst
->sa_family
) {
785 ipseclog((LOG_ERR
, "protocol family mismatched %d != %d\n.",
786 isrc
->sa_family
, idst
->sa_family
));
790 lck_mtx_lock(sadb_mutex
);
791 LIST_FOREACH(sp
, &sptree
[dir
], chain
) {
792 if (sp
->state
== IPSEC_SPSTATE_DEAD
)
796 for (p
= sp
->req
; p
; p
= p
->next
) {
797 if (p
->saidx
.mode
!= IPSEC_MODE_TUNNEL
)
804 /* here we look at address matches only */
806 if (isrc
->sa_len
> sizeof(spidx
.src
) ||
807 idst
->sa_len
> sizeof(spidx
.dst
))
809 bcopy(isrc
, &spidx
.src
, isrc
->sa_len
);
810 bcopy(idst
, &spidx
.dst
, idst
->sa_len
);
811 if (!key_cmpspidx_withmask(&sp
->spidx
, &spidx
))
814 is
= (struct sockaddr
*)&r1
->saidx
.src
;
815 id
= (struct sockaddr
*)&r1
->saidx
.dst
;
816 if (key_sockaddrcmp(is
, isrc
, 0) ||
817 key_sockaddrcmp(id
, idst
, 0))
821 os
= (struct sockaddr
*)&r2
->saidx
.src
;
822 od
= (struct sockaddr
*)&r2
->saidx
.dst
;
823 if (key_sockaddrcmp(os
, osrc
, 0) ||
824 key_sockaddrcmp(od
, odst
, 0))
830 lck_mtx_unlock(sadb_mutex
);
835 sp
->lastused
= tv
.tv_sec
;
837 lck_mtx_unlock(sadb_mutex
);
841 struct secasvar
*key_alloc_outbound_sav_for_interface(ifnet_t interface
, int family
)
843 struct secashead
*sah
;
844 struct secasvar
*sav
;
847 const u_int
*saorder_state_valid
;
849 struct sockaddr_in
*sin
;
852 if (interface
== NULL
)
855 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
857 lck_mtx_lock(sadb_mutex
);
859 LIST_FOREACH(sah
, &sahtree
, chain
) {
860 if (sah
->state
== SADB_SASTATE_DEAD
) {
863 if (sah
->ipsec_if
== interface
&&
864 (family
== AF_INET6
|| family
== AF_INET
) &&
865 sah
->dir
== IPSEC_DIR_OUTBOUND
) {
866 /* This SAH is linked to the IPSec interface, and the right family. We found it! */
867 if (key_preferred_oldsa
) {
868 saorder_state_valid
= saorder_state_valid_prefer_old
;
869 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_old
);
871 saorder_state_valid
= saorder_state_valid_prefer_new
;
872 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_new
);
875 sin
= (struct sockaddr_in
*)&sah
->saidx
.dst
;
876 dstport
= sin
->sin_port
;
877 if (sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
878 sin
->sin_port
= IPSEC_PORT_ANY
;
880 for (stateidx
= 0; stateidx
< arraysize
; stateidx
++) {
881 state
= saorder_state_valid
[stateidx
];
882 sav
= key_do_allocsa_policy(sah
, state
, dstport
);
884 lck_mtx_unlock(sadb_mutex
);
893 lck_mtx_unlock(sadb_mutex
);
898 * allocating an SA entry for an *OUTBOUND* packet.
899 * checking each request entries in SP, and acquire an SA if need.
900 * OUT: 0: there are valid requests.
901 * ENOENT: policy may be valid, but SA with REQUIRE is on acquiring.
905 struct ipsecrequest
*isr
,
906 struct secasindex
*saidx
,
907 struct secasvar
**sav
)
911 struct sockaddr_in
*sin
;
913 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
918 if (isr
== NULL
|| saidx
== NULL
)
919 panic("key_checkrequest: NULL pointer is passed.\n");
922 switch (saidx
->mode
) {
923 case IPSEC_MODE_TRANSPORT
:
924 case IPSEC_MODE_TUNNEL
:
928 panic("key_checkrequest: Invalid policy defined.\n");
931 /* get current level */
932 level
= ipsec_get_reqlevel(isr
);
936 * key_allocsa_policy should allocate the oldest SA available.
937 * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt.
940 *sav
= key_allocsa_policy(saidx
);
942 /* When there is SA. */
948 * Remove dst port - used for special natt support - don't call
949 * key_acquire with it.
951 if (saidx
->mode
== IPSEC_MODE_TRANSPORT
) {
952 sin
= (struct sockaddr_in
*)&saidx
->dst
;
953 sin
->sin_port
= IPSEC_PORT_ANY
;
955 if ((error
= key_acquire(saidx
, isr
->sp
)) != 0) {
956 /* XXX What should I do ? */
957 ipseclog((LOG_DEBUG
, "key_checkrequest: error %d returned "
958 "from key_acquire.\n", error
));
962 return level
== IPSEC_LEVEL_REQUIRE
? ENOENT
: 0;
966 * allocating a SA for policy entry from SAD.
967 * NOTE: searching SAD of aliving state.
968 * OUT: NULL: not found.
969 * others: found and return the pointer.
971 u_int32_t sah_search_calls
= 0;
972 u_int32_t sah_search_count
= 0;
975 struct secasindex
*saidx
)
977 struct secashead
*sah
;
978 struct secasvar
*sav
;
979 u_int stateidx
, state
;
980 const u_int
*saorder_state_valid
;
982 struct sockaddr_in
*sin
;
985 lck_mtx_lock(sadb_mutex
);
987 LIST_FOREACH(sah
, &sahtree
, chain
) {
989 if (sah
->state
== SADB_SASTATE_DEAD
)
991 if (key_cmpsaidx(&sah
->saidx
, saidx
, CMP_MODE
| CMP_REQID
))
994 lck_mtx_unlock(sadb_mutex
);
1000 * search a valid state list for outbound packet.
1001 * This search order is important.
1003 if (key_preferred_oldsa
) {
1004 saorder_state_valid
= saorder_state_valid_prefer_old
;
1005 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_old
);
1007 saorder_state_valid
= saorder_state_valid_prefer_new
;
1008 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_new
);
1012 sin
= (struct sockaddr_in
*)&saidx
->dst
;
1013 dstport
= sin
->sin_port
;
1014 if (saidx
->mode
== IPSEC_MODE_TRANSPORT
)
1015 sin
->sin_port
= IPSEC_PORT_ANY
;
1017 for (stateidx
= 0; stateidx
< arraysize
; stateidx
++) {
1019 state
= saorder_state_valid
[stateidx
];
1021 sav
= key_do_allocsa_policy(sah
, state
, dstport
);
1023 lck_mtx_unlock(sadb_mutex
);
1027 lck_mtx_unlock(sadb_mutex
);
1032 key_send_delete (struct secasvar
*sav
)
1034 struct mbuf
*m
, *result
;
1037 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
1039 if ((satype
= key_proto2satype(sav
->sah
->saidx
.proto
)) == 0)
1040 panic("key_do_allocsa_policy: invalid proto is passed.\n");
1042 m
= key_setsadbmsg(SADB_DELETE
, 0,
1043 satype
, 0, 0, sav
->refcnt
- 1);
1048 /* set sadb_address for saidx's. */
1049 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
1050 (struct sockaddr
*)&sav
->sah
->saidx
.src
,
1051 sav
->sah
->saidx
.src
.ss_len
<< 3,
1057 /* set sadb_address for saidx's. */
1058 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
1059 (struct sockaddr
*)&sav
->sah
->saidx
.dst
,
1060 sav
->sah
->saidx
.src
.ss_len
<< 3,
1066 /* create SA extension */
1067 m
= key_setsadbsa(sav
);
1072 if (result
->m_len
< sizeof(struct sadb_msg
)) {
1073 result
= m_pullup(result
,
1074 sizeof(struct sadb_msg
));
1079 result
->m_pkthdr
.len
= 0;
1080 for (m
= result
; m
; m
= m
->m_next
)
1081 result
->m_pkthdr
.len
+= m
->m_len
;
1082 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
1083 PFKEY_UNIT64(result
->m_pkthdr
.len
);
1085 if (key_sendup_mbuf(NULL
, result
,
1086 KEY_SENDUP_REGISTERED
))
1089 key_freesav(sav
, KEY_SADB_LOCKED
);
1093 * searching SAD with direction, protocol, mode and state.
1094 * called by key_allocsa_policy().
1097 * others : found, pointer to a SA.
1099 static struct secasvar
*
1100 key_do_allocsa_policy(
1101 struct secashead
*sah
,
1105 struct secasvar
*sav
, *nextsav
, *candidate
, *natt_candidate
, *no_natt_candidate
, *d
;
1107 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1111 natt_candidate
= NULL
;
1112 no_natt_candidate
= NULL
;
1114 for (sav
= LIST_FIRST(&sah
->savtree
[state
]);
1118 nextsav
= LIST_NEXT(sav
, chain
);
1121 KEY_CHKSASTATE(sav
->state
, state
, "key_do_allocsa_policy");
1123 if (sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
&& dstport
&&
1124 ((sav
->flags
& SADB_X_EXT_NATT
) != 0) &&
1125 ntohs(dstport
) != sav
->remote_ike_port
)
1128 if (sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
&&
1129 ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0) &&
1130 ntohs(dstport
) != sav
->remote_ike_port
)
1131 continue; /* skip this one - not a match - or not UDP */
1133 if ((sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
&&
1134 ((sav
->flags
& SADB_X_EXT_NATT
) != 0)) ||
1135 (sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
&&
1136 ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0))) {
1137 if (natt_candidate
== NULL
) {
1138 natt_candidate
= sav
;
1141 candidate
= natt_candidate
;
1143 if (no_natt_candidate
== NULL
) {
1144 no_natt_candidate
= sav
;
1147 candidate
= no_natt_candidate
;
1150 /* Which SA is the better ? */
1152 /* sanity check 2 */
1153 if (candidate
->lft_c
== NULL
|| sav
->lft_c
== NULL
)
1154 panic("key_do_allocsa_policy: "
1155 "lifetime_current is NULL.\n");
1157 /* What the best method is to compare ? */
1158 if (key_preferred_oldsa
) {
1159 if (candidate
->lft_c
->sadb_lifetime_addtime
>
1160 sav
->lft_c
->sadb_lifetime_addtime
) {
1161 if ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0)
1162 natt_candidate
= sav
;
1164 no_natt_candidate
= sav
;
1170 /* prefered new sa rather than old sa */
1171 if (candidate
->lft_c
->sadb_lifetime_addtime
<
1172 sav
->lft_c
->sadb_lifetime_addtime
) {
1174 if ((sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
&&
1175 ((sav
->flags
& SADB_X_EXT_NATT
) != 0)) ||
1176 (sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
&&
1177 ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0))) {
1178 natt_candidate
= sav
;
1180 no_natt_candidate
= sav
;
1187 * prepared to delete the SA when there is more
1188 * suitable candidate and the lifetime of the SA is not
1191 if (d
->lft_c
->sadb_lifetime_addtime
!= 0) {
1196 /* choose latest if both types present */
1197 if (natt_candidate
== NULL
)
1198 candidate
= no_natt_candidate
;
1199 else if (no_natt_candidate
== NULL
)
1200 candidate
= natt_candidate
;
1201 else if (sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
&& dstport
)
1202 candidate
= natt_candidate
;
1203 else if (natt_candidate
->lft_c
->sadb_lifetime_addtime
>
1204 no_natt_candidate
->lft_c
->sadb_lifetime_addtime
)
1205 candidate
= natt_candidate
;
1207 candidate
= no_natt_candidate
;
1210 candidate
->refcnt
++;
1211 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
1212 printf("DP allocsa_policy cause "
1213 "refcnt++:%d SA:0x%llx\n", candidate
->refcnt
,
1214 (uint64_t)VM_KERNEL_ADDRPERM(candidate
)));
1220 * allocating a SA entry for a *INBOUND* packet.
1221 * Must call key_freesav() later.
1222 * OUT: positive: pointer to a sav.
1223 * NULL: not found, or error occurred.
1225 * In the comparison, source address will be ignored for RFC2401 conformance.
1226 * To quote, from section 4.1:
1227 * A security association is uniquely identified by a triple consisting
1228 * of a Security Parameter Index (SPI), an IP Destination Address, and a
1229 * security protocol (AH or ESP) identifier.
1230 * Note that, however, we do need to keep source address in IPsec SA.
1231 * IKE specification and PF_KEY specification do assume that we
1232 * keep source address in IPsec SA. We see a tricky situation here.
1242 return key_allocsa_extended(family
, src
, dst
, proto
, spi
, NULL
);
1246 key_allocsa_extended(u_int family
,
1253 struct secasvar
*sav
, *match
;
1254 u_int stateidx
, state
, tmpidx
, matchidx
;
1255 struct sockaddr_in sin
;
1256 struct sockaddr_in6 sin6
;
1257 const u_int
*saorder_state_valid
;
1260 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1263 if (src
== NULL
|| dst
== NULL
)
1264 panic("key_allocsa: NULL pointer is passed.\n");
1267 * when both systems employ similar strategy to use a SA.
1268 * the search order is important even in the inbound case.
1270 if (key_preferred_oldsa
) {
1271 saorder_state_valid
= saorder_state_valid_prefer_old
;
1272 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_old
);
1274 saorder_state_valid
= saorder_state_valid_prefer_new
;
1275 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_new
);
1280 * XXX: to be checked internal IP header somewhere. Also when
1281 * IPsec tunnel packet is received. But ESP tunnel mode is
1282 * encrypted so we can't check internal IP header.
1285 * search a valid state list for inbound packet.
1286 * the search order is not important.
1289 matchidx
= arraysize
;
1290 lck_mtx_lock(sadb_mutex
);
1291 LIST_FOREACH(sav
, &spihash
[SPIHASH(spi
)], spihash
) {
1292 if (sav
->spi
!= spi
)
1294 if (interface
!= NULL
&&
1295 sav
->sah
->ipsec_if
!= interface
) {
1298 if (proto
!= sav
->sah
->saidx
.proto
)
1300 if (family
!= sav
->sah
->saidx
.src
.ss_family
||
1301 family
!= sav
->sah
->saidx
.dst
.ss_family
)
1304 for (stateidx
= 0; stateidx
< matchidx
; stateidx
++) {
1305 state
= saorder_state_valid
[stateidx
];
1306 if (sav
->state
== state
) {
1311 if (tmpidx
>= matchidx
)
1314 #if 0 /* don't check src */
1315 /* check src address */
1318 bzero(&sin
, sizeof(sin
));
1319 sin
.sin_family
= AF_INET
;
1320 sin
.sin_len
= sizeof(sin
);
1321 bcopy(src
, &sin
.sin_addr
,
1322 sizeof(sin
.sin_addr
));
1323 if (key_sockaddrcmp((struct sockaddr
*)&sin
,
1324 (struct sockaddr
*)&sav
->sah
->saidx
.src
, 0) != 0)
1328 bzero(&sin6
, sizeof(sin6
));
1329 sin6
.sin6_family
= AF_INET6
;
1330 sin6
.sin6_len
= sizeof(sin6
);
1331 bcopy(src
, &sin6
.sin6_addr
,
1332 sizeof(sin6
.sin6_addr
));
1333 if (IN6_IS_SCOPE_LINKLOCAL(&sin6
.sin6_addr
)) {
1334 /* kame fake scopeid */
1335 sin6
.sin6_scope_id
=
1336 ntohs(sin6
.sin6_addr
.s6_addr16
[1]);
1337 sin6
.sin6_addr
.s6_addr16
[1] = 0;
1339 if (key_sockaddrcmp((struct sockaddr
*)&sin6
,
1340 (struct sockaddr
*)&sav
->sah
->saidx
.src
, 0) != 0)
1344 ipseclog((LOG_DEBUG
, "key_allocsa: "
1345 "unknown address family=%d.\n",
1351 /* check dst address */
1354 bzero(&sin
, sizeof(sin
));
1355 sin
.sin_family
= AF_INET
;
1356 sin
.sin_len
= sizeof(sin
);
1357 bcopy(dst
, &sin
.sin_addr
,
1358 sizeof(sin
.sin_addr
));
1359 if (key_sockaddrcmp((struct sockaddr
*)&sin
,
1360 (struct sockaddr
*)&sav
->sah
->saidx
.dst
, 0) != 0)
1365 bzero(&sin6
, sizeof(sin6
));
1366 sin6
.sin6_family
= AF_INET6
;
1367 sin6
.sin6_len
= sizeof(sin6
);
1368 bcopy(dst
, &sin6
.sin6_addr
,
1369 sizeof(sin6
.sin6_addr
));
1370 if (IN6_IS_SCOPE_LINKLOCAL(&sin6
.sin6_addr
)) {
1371 /* kame fake scopeid */
1372 sin6
.sin6_scope_id
=
1373 ntohs(sin6
.sin6_addr
.s6_addr16
[1]);
1374 sin6
.sin6_addr
.s6_addr16
[1] = 0;
1376 if (key_sockaddrcmp((struct sockaddr
*)&sin6
,
1377 (struct sockaddr
*)&sav
->sah
->saidx
.dst
, 0) != 0)
1381 ipseclog((LOG_DEBUG
, "key_allocsa: "
1382 "unknown address family=%d.\n", family
));
1393 lck_mtx_unlock(sadb_mutex
);
1398 lck_mtx_unlock(sadb_mutex
);
1399 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
1400 printf("DP allocsa cause refcnt++:%d SA:0x%llx\n",
1401 match
->refcnt
, (uint64_t)VM_KERNEL_ADDRPERM(match
)));
1406 key_natt_get_translated_port(
1407 struct secasvar
*outsav
)
1410 struct secasindex saidx
;
1411 struct secashead
*sah
;
1412 u_int stateidx
, state
;
1413 const u_int
*saorder_state_valid
;
1416 /* get sa for incoming */
1417 saidx
.mode
= outsav
->sah
->saidx
.mode
;
1419 saidx
.proto
= outsav
->sah
->saidx
.proto
;
1420 bcopy(&outsav
->sah
->saidx
.src
, &saidx
.dst
, sizeof(struct sockaddr_in
));
1421 bcopy(&outsav
->sah
->saidx
.dst
, &saidx
.src
, sizeof(struct sockaddr_in
));
1423 lck_mtx_lock(sadb_mutex
);
1424 LIST_FOREACH(sah
, &sahtree
, chain
) {
1425 if (sah
->state
== SADB_SASTATE_DEAD
)
1427 if (key_cmpsaidx(&sah
->saidx
, &saidx
, CMP_MODE
))
1430 lck_mtx_unlock(sadb_mutex
);
1435 * Found sah - now go thru list of SAs and find
1436 * matching remote ike port. If found - set
1437 * sav->natt_encapsulated_src_port and return the port.
1440 * search a valid state list for outbound packet.
1441 * This search order is important.
1443 if (key_preferred_oldsa
) {
1444 saorder_state_valid
= saorder_state_valid_prefer_old
;
1445 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_old
);
1447 saorder_state_valid
= saorder_state_valid_prefer_new
;
1448 arraysize
= _ARRAYLEN(saorder_state_valid_prefer_new
);
1451 for (stateidx
= 0; stateidx
< arraysize
; stateidx
++) {
1452 state
= saorder_state_valid
[stateidx
];
1453 if (key_do_get_translated_port(sah
, outsav
, state
)) {
1454 lck_mtx_unlock(sadb_mutex
);
1455 return outsav
->natt_encapsulated_src_port
;
1458 lck_mtx_unlock(sadb_mutex
);
1463 key_do_get_translated_port(
1464 struct secashead
*sah
,
1465 struct secasvar
*outsav
,
1468 struct secasvar
*currsav
, *nextsav
, *candidate
;
1471 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1476 for (currsav
= LIST_FIRST(&sah
->savtree
[state
]);
1478 currsav
= nextsav
) {
1480 nextsav
= LIST_NEXT(currsav
, chain
);
1483 KEY_CHKSASTATE(currsav
->state
, state
, "key_do_get_translated_port");
1485 if ((currsav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) == 0 ||
1486 currsav
->remote_ike_port
!= outsav
->remote_ike_port
)
1489 if (candidate
== NULL
) {
1490 candidate
= currsav
;
1494 /* Which SA is the better ? */
1496 /* sanity check 2 */
1497 if (candidate
->lft_c
== NULL
|| currsav
->lft_c
== NULL
)
1498 panic("key_do_get_translated_port: "
1499 "lifetime_current is NULL.\n");
1501 /* What the best method is to compare ? */
1502 if (key_preferred_oldsa
) {
1503 if (candidate
->lft_c
->sadb_lifetime_addtime
>
1504 currsav
->lft_c
->sadb_lifetime_addtime
) {
1505 candidate
= currsav
;
1511 /* prefered new sa rather than old sa */
1512 if (candidate
->lft_c
->sadb_lifetime_addtime
<
1513 currsav
->lft_c
->sadb_lifetime_addtime
)
1514 candidate
= currsav
;
1518 outsav
->natt_encapsulated_src_port
= candidate
->natt_encapsulated_src_port
;
1526 * Must be called after calling key_allocsp().
1530 struct secpolicy
*sp
,
1536 panic("key_freesp: NULL pointer is passed.\n");
1539 lck_mtx_lock(sadb_mutex
);
1541 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1543 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
1544 printf("DP freesp cause refcnt--:%d SP:0x%llx\n",
1545 sp
->refcnt
, (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
1547 if (sp
->refcnt
== 0)
1550 lck_mtx_unlock(sadb_mutex
);
1555 * Must be called after calling key_allocsa().
1556 * This function is called by key_freesp() to free some SA allocated
1561 struct secasvar
*sav
,
1567 panic("key_freesav: NULL pointer is passed.\n");
1570 lck_mtx_lock(sadb_mutex
);
1572 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1574 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
1575 printf("DP freesav cause refcnt--:%d SA:0x%llx SPI %u\n",
1576 sav
->refcnt
, (uint64_t)VM_KERNEL_ADDRPERM(sav
),
1577 (u_int32_t
)ntohl(sav
->spi
)));
1579 if (sav
->refcnt
== 0)
1582 lck_mtx_unlock(sadb_mutex
);
1586 /* %%% SPD management */
1588 * free security policy entry.
1592 struct secpolicy
*sp
)
1597 panic("key_delsp: NULL pointer is passed.\n");
1599 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1600 sp
->state
= IPSEC_SPSTATE_DEAD
;
1603 return; /* can't free */
1605 /* remove from SP index */
1606 if (__LIST_CHAINED(sp
)) {
1607 LIST_REMOVE(sp
, chain
);
1608 ipsec_policy_count
--;
1611 if (sp
->spidx
.internal_if
) {
1612 ifnet_release(sp
->spidx
.internal_if
);
1613 sp
->spidx
.internal_if
= NULL
;
1617 ifnet_release(sp
->ipsec_if
);
1618 sp
->ipsec_if
= NULL
;
1621 if (sp
->outgoing_if
) {
1622 ifnet_release(sp
->outgoing_if
);
1623 sp
->outgoing_if
= NULL
;
1627 struct ipsecrequest
*isr
= sp
->req
, *nextisr
;
1629 while (isr
!= NULL
) {
1630 nextisr
= isr
->next
;
1635 keydb_delsecpolicy(sp
);
1642 * OUT: NULL : not found
1643 * others : found, pointer to a SP.
1645 static struct secpolicy
*
1647 struct secpolicyindex
*spidx
)
1649 struct secpolicy
*sp
;
1651 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1655 panic("key_getsp: NULL pointer is passed.\n");
1657 LIST_FOREACH(sp
, &sptree
[spidx
->dir
], chain
) {
1658 if (sp
->state
== IPSEC_SPSTATE_DEAD
)
1660 if (key_cmpspidx_exactly(spidx
, &sp
->spidx
)) {
1671 * OUT: NULL : not found
1672 * others : found, pointer to a SP.
1678 struct secpolicy
*sp
;
1680 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1682 lck_mtx_lock(sadb_mutex
);
1683 sp
= __key_getspbyid(id
);
1684 lck_mtx_unlock(sadb_mutex
);
1689 static struct secpolicy
*
1690 __key_getspbyid(u_int32_t id
)
1692 struct secpolicy
*sp
;
1694 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
1696 LIST_FOREACH(sp
, &sptree
[IPSEC_DIR_INBOUND
], chain
) {
1697 if (sp
->state
== IPSEC_SPSTATE_DEAD
)
1705 LIST_FOREACH(sp
, &sptree
[IPSEC_DIR_OUTBOUND
], chain
) {
1706 if (sp
->state
== IPSEC_SPSTATE_DEAD
)
1720 struct secpolicy
*newsp
= NULL
;
1722 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1723 newsp
= keydb_newsecpolicy();
1734 * create secpolicy structure from sadb_x_policy structure.
1735 * NOTE: `state', `secpolicyindex' in secpolicy structure are not set,
1736 * so must be set properly later.
1740 struct sadb_x_policy
*xpl0
,
1744 struct secpolicy
*newsp
;
1746 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1750 panic("key_msg2sp: NULL pointer was passed.\n");
1751 if (len
< sizeof(*xpl0
))
1752 panic("key_msg2sp: invalid length.\n");
1753 if (len
!= PFKEY_EXTLEN(xpl0
)) {
1754 ipseclog((LOG_DEBUG
, "key_msg2sp: Invalid msg length.\n"));
1759 if ((newsp
= key_newsp()) == NULL
) {
1764 newsp
->spidx
.dir
= xpl0
->sadb_x_policy_dir
;
1765 newsp
->policy
= xpl0
->sadb_x_policy_type
;
1768 switch (xpl0
->sadb_x_policy_type
) {
1769 case IPSEC_POLICY_DISCARD
:
1770 case IPSEC_POLICY_GENERATE
:
1771 case IPSEC_POLICY_NONE
:
1772 case IPSEC_POLICY_ENTRUST
:
1773 case IPSEC_POLICY_BYPASS
:
1777 case IPSEC_POLICY_IPSEC
:
1780 struct sadb_x_ipsecrequest
*xisr
;
1781 struct ipsecrequest
**p_isr
= &newsp
->req
;
1783 /* validity check */
1784 if (PFKEY_EXTLEN(xpl0
) < sizeof(*xpl0
)) {
1785 ipseclog((LOG_DEBUG
,
1786 "key_msg2sp: Invalid msg length.\n"));
1787 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1792 tlen
= PFKEY_EXTLEN(xpl0
) - sizeof(*xpl0
);
1793 xisr
= (struct sadb_x_ipsecrequest
*)(xpl0
+ 1);
1796 if (tlen
< sizeof(*xisr
)) {
1797 ipseclog((LOG_DEBUG
, "key_msg2sp: "
1798 "invalid ipsecrequest.\n"));
1799 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1805 if (xisr
->sadb_x_ipsecrequest_len
< sizeof(*xisr
)) {
1806 ipseclog((LOG_DEBUG
, "key_msg2sp: "
1807 "invalid ipsecrequest length.\n"));
1808 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1813 /* allocate request buffer */
1814 KMALLOC_WAIT(*p_isr
, struct ipsecrequest
*, sizeof(**p_isr
));
1815 if ((*p_isr
) == NULL
) {
1816 ipseclog((LOG_DEBUG
,
1817 "key_msg2sp: No more memory.\n"));
1818 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1822 bzero(*p_isr
, sizeof(**p_isr
));
1825 (*p_isr
)->next
= NULL
;
1827 switch (xisr
->sadb_x_ipsecrequest_proto
) {
1830 case IPPROTO_IPCOMP
:
1833 ipseclog((LOG_DEBUG
,
1834 "key_msg2sp: invalid proto type=%u\n",
1835 xisr
->sadb_x_ipsecrequest_proto
));
1836 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1837 *error
= EPROTONOSUPPORT
;
1840 (*p_isr
)->saidx
.proto
= xisr
->sadb_x_ipsecrequest_proto
;
1842 switch (xisr
->sadb_x_ipsecrequest_mode
) {
1843 case IPSEC_MODE_TRANSPORT
:
1844 case IPSEC_MODE_TUNNEL
:
1846 case IPSEC_MODE_ANY
:
1848 ipseclog((LOG_DEBUG
,
1849 "key_msg2sp: invalid mode=%u\n",
1850 xisr
->sadb_x_ipsecrequest_mode
));
1851 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1855 (*p_isr
)->saidx
.mode
= xisr
->sadb_x_ipsecrequest_mode
;
1857 switch (xisr
->sadb_x_ipsecrequest_level
) {
1858 case IPSEC_LEVEL_DEFAULT
:
1859 case IPSEC_LEVEL_USE
:
1860 case IPSEC_LEVEL_REQUIRE
:
1862 case IPSEC_LEVEL_UNIQUE
:
1863 /* validity check */
1865 * If range violation of reqid, kernel will
1866 * update it, don't refuse it.
1868 if (xisr
->sadb_x_ipsecrequest_reqid
1869 > IPSEC_MANUAL_REQID_MAX
) {
1870 ipseclog((LOG_DEBUG
,
1871 "key_msg2sp: reqid=%d range "
1872 "violation, updated by kernel.\n",
1873 xisr
->sadb_x_ipsecrequest_reqid
));
1874 xisr
->sadb_x_ipsecrequest_reqid
= 0;
1877 /* allocate new reqid id if reqid is zero. */
1878 if (xisr
->sadb_x_ipsecrequest_reqid
== 0) {
1880 if ((reqid
= key_newreqid()) == 0) {
1881 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1885 (*p_isr
)->saidx
.reqid
= reqid
;
1886 xisr
->sadb_x_ipsecrequest_reqid
= reqid
;
1888 /* set it for manual keying. */
1889 (*p_isr
)->saidx
.reqid
=
1890 xisr
->sadb_x_ipsecrequest_reqid
;
1895 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid level=%u\n",
1896 xisr
->sadb_x_ipsecrequest_level
));
1897 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1901 (*p_isr
)->level
= xisr
->sadb_x_ipsecrequest_level
;
1903 /* set IP addresses if there */
1904 if (xisr
->sadb_x_ipsecrequest_len
> sizeof(*xisr
)) {
1905 struct sockaddr
*paddr
;
1907 if (tlen
< xisr
->sadb_x_ipsecrequest_len
) {
1908 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid request "
1909 "address length.\n"));
1910 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1915 paddr
= (struct sockaddr
*)(xisr
+ 1);
1916 uint8_t src_len
= paddr
->sa_len
;
1918 if (xisr
->sadb_x_ipsecrequest_len
< src_len
) {
1919 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid request "
1920 "invalid source address length.\n"));
1921 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1926 /* validity check */
1928 > sizeof((*p_isr
)->saidx
.src
)) {
1929 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid request "
1930 "address length.\n"));
1931 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1936 bcopy(paddr
, &(*p_isr
)->saidx
.src
,
1937 MIN(paddr
->sa_len
, sizeof((*p_isr
)->saidx
.src
)));
1939 paddr
= (struct sockaddr
*)((caddr_t
)paddr
+ paddr
->sa_len
);
1940 uint8_t dst_len
= paddr
->sa_len
;
1942 if (xisr
->sadb_x_ipsecrequest_len
< (src_len
+ dst_len
)) {
1943 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid request "
1944 "invalid dest address length.\n"));
1945 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1950 /* validity check */
1952 > sizeof((*p_isr
)->saidx
.dst
)) {
1953 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid request "
1954 "address length.\n"));
1955 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1960 bcopy(paddr
, &(*p_isr
)->saidx
.dst
,
1961 MIN(paddr
->sa_len
, sizeof((*p_isr
)->saidx
.dst
)));
1964 (*p_isr
)->sp
= newsp
;
1966 /* initialization for the next. */
1967 p_isr
= &(*p_isr
)->next
;
1968 tlen
-= xisr
->sadb_x_ipsecrequest_len
;
1970 /* validity check */
1972 ipseclog((LOG_DEBUG
, "key_msg2sp: becoming tlen < 0.\n"));
1973 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1978 xisr
= (struct sadb_x_ipsecrequest
*)(void *)
1979 ((caddr_t
)xisr
+ xisr
->sadb_x_ipsecrequest_len
);
1984 ipseclog((LOG_DEBUG
, "key_msg2sp: invalid policy type.\n"));
1985 key_freesp(newsp
, KEY_SADB_UNLOCKED
);
1997 lck_mtx_lock(sadb_mutex
);
1998 static u_int32_t auto_reqid
= IPSEC_MANUAL_REQID_MAX
+ 1;
2001 /* The reqid must be limited to 16 bits because the PF_KEY message format only uses
2002 16 bits for this field. Once it becomes larger than 16 bits - ipsec fails to
2003 work anymore. Changing the PF_KEY message format would introduce compatibility
2004 issues. This code now tests to see if the tentative reqid is in use */
2007 struct secpolicy
*sp
;
2008 struct ipsecrequest
*isr
;
2011 auto_reqid
= (auto_reqid
== 0xFFFF
2012 ? IPSEC_MANUAL_REQID_MAX
+ 1 : auto_reqid
+ 1);
2014 /* check for uniqueness */
2016 for (dir
= 0; dir
< IPSEC_DIR_MAX
; dir
++) {
2017 LIST_FOREACH(sp
, &sptree
[dir
], chain
) {
2018 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
2019 if (isr
->saidx
.reqid
== auto_reqid
) {
2032 lck_mtx_unlock(sadb_mutex
);
2037 * copy secpolicy struct to sadb_x_policy structure indicated.
2041 struct secpolicy
*sp
)
2043 struct sadb_x_policy
*xpl
;
2050 panic("key_sp2msg: NULL pointer was passed.\n");
2052 tlen
= key_getspreqmsglen(sp
);
2054 m
= key_alloc_mbuf(tlen
);
2055 if (!m
|| m
->m_next
) { /*XXX*/
2063 xpl
= mtod(m
, struct sadb_x_policy
*);
2066 xpl
->sadb_x_policy_len
= PFKEY_UNIT64(tlen
);
2067 xpl
->sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
2068 xpl
->sadb_x_policy_type
= sp
->policy
;
2069 xpl
->sadb_x_policy_dir
= sp
->spidx
.dir
;
2070 xpl
->sadb_x_policy_id
= sp
->id
;
2071 p
= (caddr_t
)xpl
+ sizeof(*xpl
);
2073 /* if is the policy for ipsec ? */
2074 if (sp
->policy
== IPSEC_POLICY_IPSEC
) {
2075 struct sadb_x_ipsecrequest
*xisr
;
2076 struct ipsecrequest
*isr
;
2078 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
2080 xisr
= (struct sadb_x_ipsecrequest
*)(void *)p
;
2082 xisr
->sadb_x_ipsecrequest_proto
= isr
->saidx
.proto
;
2083 xisr
->sadb_x_ipsecrequest_mode
= isr
->saidx
.mode
;
2084 xisr
->sadb_x_ipsecrequest_level
= isr
->level
;
2085 xisr
->sadb_x_ipsecrequest_reqid
= isr
->saidx
.reqid
;
2088 bcopy(&isr
->saidx
.src
, p
, isr
->saidx
.src
.ss_len
);
2089 p
+= isr
->saidx
.src
.ss_len
;
2090 bcopy(&isr
->saidx
.dst
, p
, isr
->saidx
.dst
.ss_len
);
2091 p
+= isr
->saidx
.src
.ss_len
;
2093 xisr
->sadb_x_ipsecrequest_len
=
2094 PFKEY_ALIGN8(sizeof(*xisr
)
2095 + isr
->saidx
.src
.ss_len
2096 + isr
->saidx
.dst
.ss_len
);
2103 /* m will not be freed nor modified */
2104 static struct mbuf
*
2105 key_gather_mbuf(struct mbuf
*m
, const struct sadb_msghdr
*mhp
,
2106 int ndeep
, int nitem
, int *items
)
2110 struct mbuf
*result
= NULL
, *n
;
2113 if (m
== NULL
|| mhp
== NULL
)
2114 panic("null pointer passed to key_gather");
2116 for (i
= 0; i
< nitem
; i
++) {
2118 if (idx
< 0 || idx
> SADB_EXT_MAX
)
2120 /* don't attempt to pull empty extension */
2121 if (idx
== SADB_EXT_RESERVED
&& mhp
->msg
== NULL
)
2123 if (idx
!= SADB_EXT_RESERVED
&&
2124 (mhp
->ext
[idx
] == NULL
|| mhp
->extlen
[idx
] == 0))
2127 if (idx
== SADB_EXT_RESERVED
) {
2128 len
= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
2129 MGETHDR(n
, M_WAITOK
, MT_DATA
); // sadb_msg len < MHLEN - enforced by _CASSERT
2134 m_copydata(m
, 0, sizeof(struct sadb_msg
),
2136 } else if (i
< ndeep
) {
2137 len
= mhp
->extlen
[idx
];
2138 n
= key_alloc_mbuf(len
);
2139 if (!n
|| n
->m_next
) { /*XXX*/
2144 m_copydata(m
, mhp
->extoff
[idx
], mhp
->extlen
[idx
],
2147 n
= m_copym(m
, mhp
->extoff
[idx
], mhp
->extlen
[idx
],
2159 if ((result
->m_flags
& M_PKTHDR
) != 0) {
2160 result
->m_pkthdr
.len
= 0;
2161 for (n
= result
; n
; n
= n
->m_next
)
2162 result
->m_pkthdr
.len
+= n
->m_len
;
2173 * SADB_X_SPDADD, SADB_X_SPDSETIDX or SADB_X_SPDUPDATE processing
2174 * add a entry to SP database, when received
2175 * <base, address(SD), (lifetime(H),) policy>
2177 * Adding to SP database,
2179 * <base, address(SD), (lifetime(H),) policy>
2180 * to the socket which was send.
2182 * SPDADD set a unique policy entry.
2183 * SPDSETIDX like SPDADD without a part of policy requests.
2184 * SPDUPDATE replace a unique policy entry.
2186 * m will always be freed.
2192 const struct sadb_msghdr
*mhp
)
2194 struct sadb_address
*src0
, *dst0
, *src1
= NULL
, *dst1
= NULL
;
2195 struct sadb_x_policy
*xpl0
, *xpl
;
2196 struct sadb_lifetime
*lft
= NULL
;
2197 struct secpolicyindex spidx
;
2198 struct secpolicy
*newsp
;
2200 ifnet_t internal_if
= NULL
;
2201 char *outgoing_if
= NULL
;
2202 char *ipsec_if
= NULL
;
2203 struct sadb_x_ipsecif
*ipsecifopts
= NULL
;
2205 int use_src_range
= 0;
2206 int use_dst_range
= 0;
2207 int init_disabled
= 0;
2208 int address_family
, address_len
;
2210 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2213 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
2214 panic("key_spdadd: NULL pointer is passed.\n");
2216 if (mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
] != NULL
&& mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_END
] != NULL
) {
2219 if (mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_START
] != NULL
&& mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_END
] != NULL
) {
2223 if ((!use_src_range
&& mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
) ||
2224 (!use_dst_range
&& mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
) ||
2225 mhp
->ext
[SADB_X_EXT_POLICY
] == NULL
) {
2226 ipseclog((LOG_DEBUG
, "key_spdadd: invalid message is passed.\n"));
2227 return key_senderror(so
, m
, EINVAL
);
2229 if ((use_src_range
&& (mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_SRC_START
] < sizeof(struct sadb_address
)
2230 || mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_SRC_END
] < sizeof(struct sadb_address
))) ||
2231 (!use_src_range
&& mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
)) ||
2232 (use_dst_range
&& (mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_DST_START
] < sizeof(struct sadb_address
)
2233 || mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_DST_END
] < sizeof(struct sadb_address
))) ||
2234 (!use_dst_range
&& mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) ||
2235 mhp
->extlen
[SADB_X_EXT_POLICY
] < sizeof(struct sadb_x_policy
)) {
2236 ipseclog((LOG_DEBUG
, "key_spdadd: invalid message is passed.\n"));
2237 return key_senderror(so
, m
, EINVAL
);
2239 if (mhp
->ext
[SADB_EXT_LIFETIME_HARD
] != NULL
) {
2240 if (mhp
->extlen
[SADB_EXT_LIFETIME_HARD
]
2241 < sizeof(struct sadb_lifetime
)) {
2242 ipseclog((LOG_DEBUG
, "key_spdadd: invalid message is passed.\n"));
2243 return key_senderror(so
, m
, EINVAL
);
2245 lft
= (struct sadb_lifetime
*)
2246 (void *)mhp
->ext
[SADB_EXT_LIFETIME_HARD
];
2248 if (mhp
->ext
[SADB_X_EXT_IPSECIF
] != NULL
) {
2249 if (mhp
->extlen
[SADB_X_EXT_IPSECIF
] < sizeof(struct sadb_x_ipsecif
)) {
2250 ipseclog((LOG_DEBUG
, "key_spdadd: invalid message is passed.\n"));
2251 return key_senderror(so
, m
, EINVAL
);
2255 if (use_src_range
) {
2256 src0
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
];
2257 src1
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_END
];
2259 src0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_SRC
];
2261 if (use_dst_range
) {
2262 dst0
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_START
];
2263 dst1
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_END
];
2265 dst0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_DST
];
2267 xpl0
= (struct sadb_x_policy
*)(void *)mhp
->ext
[SADB_X_EXT_POLICY
];
2268 ipsecifopts
= (struct sadb_x_ipsecif
*)(void *)mhp
->ext
[SADB_X_EXT_IPSECIF
];
2270 /* check addresses */
2271 address_family
= ((struct sockaddr
*)(src0
+ 1))->sa_family
;
2272 address_len
= ((struct sockaddr
*)(src0
+ 1))->sa_len
;
2273 if (use_src_range
) {
2274 if (((struct sockaddr
*)(src1
+ 1))->sa_family
!= address_family
||
2275 ((struct sockaddr
*)(src1
+ 1))->sa_len
!= address_len
) {
2276 return key_senderror(so
, m
, EINVAL
);
2279 if (((struct sockaddr
*)(dst0
+ 1))->sa_family
!= address_family
||
2280 ((struct sockaddr
*)(dst0
+ 1))->sa_len
!= address_len
) {
2281 return key_senderror(so
, m
, EINVAL
);
2283 if (use_dst_range
) {
2284 if (((struct sockaddr
*)(dst1
+ 1))->sa_family
!= address_family
||
2285 ((struct sockaddr
*)(dst1
+ 1))->sa_len
!= address_len
) {
2286 return key_senderror(so
, m
, EINVAL
);
2290 /* checking the direction. */
2291 switch (xpl0
->sadb_x_policy_dir
) {
2292 case IPSEC_DIR_INBOUND
:
2293 case IPSEC_DIR_OUTBOUND
:
2296 ipseclog((LOG_DEBUG
, "key_spdadd: Invalid SP direction.\n"));
2297 mhp
->msg
->sadb_msg_errno
= EINVAL
;
2302 /* key_spdadd() accepts DISCARD, NONE and IPSEC. */
2303 if (xpl0
->sadb_x_policy_type
== IPSEC_POLICY_ENTRUST
2304 || xpl0
->sadb_x_policy_type
== IPSEC_POLICY_BYPASS
) {
2305 ipseclog((LOG_DEBUG
, "key_spdadd: Invalid policy type.\n"));
2306 return key_senderror(so
, m
, EINVAL
);
2309 /* policy requests are mandatory when action is ipsec. */
2310 if (mhp
->msg
->sadb_msg_type
!= SADB_X_SPDSETIDX
2311 && xpl0
->sadb_x_policy_type
== IPSEC_POLICY_IPSEC
2312 && mhp
->extlen
[SADB_X_EXT_POLICY
] <= sizeof(*xpl0
)) {
2313 ipseclog((LOG_DEBUG
, "key_spdadd: some policy requests part required.\n"));
2314 return key_senderror(so
, m
, EINVAL
);
2317 /* Process interfaces */
2318 if (ipsecifopts
!= NULL
) {
2319 if (ipsecifopts
->sadb_x_ipsecif_internal_if
[0]) {
2320 ifnet_find_by_name(ipsecifopts
->sadb_x_ipsecif_internal_if
, &internal_if
);
2322 if (ipsecifopts
->sadb_x_ipsecif_outgoing_if
[0]) {
2323 outgoing_if
= ipsecifopts
->sadb_x_ipsecif_outgoing_if
;
2325 if (ipsecifopts
->sadb_x_ipsecif_ipsec_if
[0]) {
2326 ipsec_if
= ipsecifopts
->sadb_x_ipsecif_ipsec_if
;
2328 init_disabled
= ipsecifopts
->sadb_x_ipsecif_init_disabled
;
2332 /* XXX boundary check against sa_len */
2333 KEY_SETSECSPIDX(xpl0
->sadb_x_policy_dir
,
2336 src0
->sadb_address_prefixlen
,
2337 dst0
->sadb_address_prefixlen
,
2338 src0
->sadb_address_proto
,
2340 use_src_range
? src0
+ 1 : NULL
,
2341 use_src_range
? src1
+ 1 : NULL
,
2342 use_dst_range
? dst0
+ 1 : NULL
,
2343 use_dst_range
? dst1
+ 1 : NULL
,
2347 * checking there is SP already or not.
2348 * SPDUPDATE doesn't depend on whether there is a SP or not.
2349 * If the type is either SPDADD or SPDSETIDX AND a SP is found,
2352 lck_mtx_lock(sadb_mutex
);
2353 newsp
= key_getsp(&spidx
);
2354 if (mhp
->msg
->sadb_msg_type
== SADB_X_SPDUPDATE
) {
2356 newsp
->state
= IPSEC_SPSTATE_DEAD
;
2357 key_freesp(newsp
, KEY_SADB_LOCKED
);
2360 if (newsp
!= NULL
) {
2361 key_freesp(newsp
, KEY_SADB_LOCKED
);
2362 ipseclog((LOG_DEBUG
, "key_spdadd: a SP entry exists already.\n"));
2363 lck_mtx_unlock(sadb_mutex
);
2365 ifnet_release(internal_if
);
2368 return key_senderror(so
, m
, EEXIST
);
2371 lck_mtx_unlock(sadb_mutex
);
2373 /* allocation new SP entry */
2374 if ((newsp
= key_msg2sp(xpl0
, PFKEY_EXTLEN(xpl0
), &error
)) == NULL
) {
2376 ifnet_release(internal_if
);
2379 return key_senderror(so
, m
, error
);
2382 if ((newsp
->id
= key_getnewspid()) == 0) {
2383 keydb_delsecpolicy(newsp
);
2385 ifnet_release(internal_if
);
2388 return key_senderror(so
, m
, ENOBUFS
);
2391 /* XXX boundary check against sa_len */
2392 KEY_SETSECSPIDX(xpl0
->sadb_x_policy_dir
,
2395 src0
->sadb_address_prefixlen
,
2396 dst0
->sadb_address_prefixlen
,
2397 src0
->sadb_address_proto
,
2399 use_src_range
? src0
+ 1 : NULL
,
2400 use_src_range
? src1
+ 1 : NULL
,
2401 use_dst_range
? dst0
+ 1 : NULL
,
2402 use_dst_range
? dst1
+ 1 : NULL
,
2407 * allow IPv6 over IPv4 or IPv4 over IPv6 tunnels using ESP -
2408 * otherwise reject if inner and outer address families not equal
2410 if (newsp
->req
&& newsp
->req
->saidx
.src
.ss_family
) {
2411 struct sockaddr
*sa
;
2412 sa
= (struct sockaddr
*)(src0
+ 1);
2413 if (sa
->sa_family
!= newsp
->req
->saidx
.src
.ss_family
) {
2414 if (newsp
->req
->saidx
.mode
!= IPSEC_MODE_TUNNEL
|| newsp
->req
->saidx
.proto
!= IPPROTO_ESP
) {
2415 keydb_delsecpolicy(newsp
);
2417 ifnet_release(internal_if
);
2420 return key_senderror(so
, m
, EINVAL
);
2424 if (newsp
->req
&& newsp
->req
->saidx
.dst
.ss_family
) {
2425 struct sockaddr
*sa
;
2426 sa
= (struct sockaddr
*)(dst0
+ 1);
2427 if (sa
->sa_family
!= newsp
->req
->saidx
.dst
.ss_family
) {
2428 if (newsp
->req
->saidx
.mode
!= IPSEC_MODE_TUNNEL
|| newsp
->req
->saidx
.proto
!= IPPROTO_ESP
) {
2429 keydb_delsecpolicy(newsp
);
2431 ifnet_release(internal_if
);
2434 return key_senderror(so
, m
, EINVAL
);
2441 newsp
->created
= tv
.tv_sec
;
2442 newsp
->lastused
= tv
.tv_sec
;
2443 newsp
->lifetime
= lft
? lft
->sadb_lifetime_addtime
: 0;
2444 newsp
->validtime
= lft
? lft
->sadb_lifetime_usetime
: 0;
2446 if (outgoing_if
!= NULL
) {
2447 ifnet_find_by_name(outgoing_if
, &newsp
->outgoing_if
);
2449 if (ipsec_if
!= NULL
) {
2450 ifnet_find_by_name(ipsec_if
, &newsp
->ipsec_if
);
2452 if (init_disabled
> 0) {
2453 newsp
->disabled
= 1;
2456 newsp
->refcnt
= 1; /* do not reclaim until I say I do */
2457 newsp
->state
= IPSEC_SPSTATE_ALIVE
;
2458 lck_mtx_lock(sadb_mutex
);
2460 * policies of type generate should be at the end of the SPD
2461 * because they function as default discard policies
2462 * Don't start timehandler for generate policies
2464 if (newsp
->policy
== IPSEC_POLICY_GENERATE
)
2465 LIST_INSERT_TAIL(&sptree
[newsp
->spidx
.dir
], newsp
, secpolicy
, chain
);
2466 else { /* XXX until we have policy ordering in the kernel */
2467 struct secpolicy
*tmpsp
;
2469 LIST_FOREACH(tmpsp
, &sptree
[newsp
->spidx
.dir
], chain
)
2470 if (tmpsp
->policy
== IPSEC_POLICY_GENERATE
)
2473 LIST_INSERT_BEFORE(tmpsp
, newsp
, chain
);
2475 LIST_INSERT_TAIL(&sptree
[newsp
->spidx
.dir
], newsp
, secpolicy
, chain
);
2476 key_start_timehandler();
2479 ipsec_policy_count
++;
2480 /* Turn off the ipsec bypass */
2481 if (ipsec_bypass
!= 0)
2484 /* delete the entry in spacqtree */
2485 if (mhp
->msg
->sadb_msg_type
== SADB_X_SPDUPDATE
) {
2486 struct secspacq
*spacq
;
2487 if ((spacq
= key_getspacq(&spidx
)) != NULL
) {
2488 /* reset counter in order to deletion by timehandler. */
2490 spacq
->created
= tv
.tv_sec
;
2494 lck_mtx_unlock(sadb_mutex
);
2497 struct mbuf
*n
, *mpolicy
;
2498 struct sadb_msg
*newmsg
;
2501 /* create new sadb_msg to reply. */
2503 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_X_EXT_POLICY
,
2504 SADB_EXT_LIFETIME_HARD
, SADB_EXT_ADDRESS_SRC
,
2505 SADB_EXT_ADDRESS_DST
, SADB_X_EXT_ADDR_RANGE_SRC_START
, SADB_X_EXT_ADDR_RANGE_SRC_END
,
2506 SADB_X_EXT_ADDR_RANGE_DST_START
, SADB_X_EXT_ADDR_RANGE_DST_END
};
2507 n
= key_gather_mbuf(m
, mhp
, 2, sizeof(mbufItems
)/sizeof(int), mbufItems
);
2509 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_X_EXT_POLICY
,
2510 SADB_EXT_ADDRESS_SRC
, SADB_EXT_ADDRESS_DST
,
2511 SADB_X_EXT_ADDR_RANGE_SRC_START
, SADB_X_EXT_ADDR_RANGE_SRC_END
,
2512 SADB_X_EXT_ADDR_RANGE_DST_START
, SADB_X_EXT_ADDR_RANGE_DST_END
};
2513 n
= key_gather_mbuf(m
, mhp
, 2, sizeof(mbufItems
)/sizeof(int), mbufItems
);
2516 return key_senderror(so
, m
, ENOBUFS
);
2518 if (n
->m_len
< sizeof(*newmsg
)) {
2519 n
= m_pullup(n
, sizeof(*newmsg
));
2521 return key_senderror(so
, m
, ENOBUFS
);
2523 newmsg
= mtod(n
, struct sadb_msg
*);
2524 newmsg
->sadb_msg_errno
= 0;
2525 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
2528 mpolicy
= m_pulldown(n
, PFKEY_ALIGN8(sizeof(struct sadb_msg
)),
2529 sizeof(*xpl
), &off
);
2530 if (mpolicy
== NULL
) {
2531 /* n is already freed */
2532 return key_senderror(so
, m
, ENOBUFS
);
2534 xpl
= (struct sadb_x_policy
*)(void *)(mtod(mpolicy
, caddr_t
) + off
);
2535 if (xpl
->sadb_x_policy_exttype
!= SADB_X_EXT_POLICY
) {
2537 return key_senderror(so
, m
, EINVAL
);
2539 xpl
->sadb_x_policy_id
= newsp
->id
;
2542 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
2547 * get new policy id.
2553 key_getnewspid(void)
2555 u_int32_t newid
= 0;
2556 int count
= key_spi_trycnt
; /* XXX */
2557 struct secpolicy
*sp
;
2559 /* when requesting to allocate spi ranged */
2560 lck_mtx_lock(sadb_mutex
);
2562 newid
= (policy_id
= (policy_id
== ~0 ? 1 : policy_id
+ 1));
2564 if ((sp
= __key_getspbyid(newid
)) == NULL
)
2567 key_freesp(sp
, KEY_SADB_LOCKED
);
2569 lck_mtx_unlock(sadb_mutex
);
2570 if (count
== 0 || newid
== 0) {
2571 ipseclog((LOG_DEBUG
, "key_getnewspid: to allocate policy id is failed.\n"));
2579 * SADB_SPDDELETE processing
2581 * <base, address(SD), policy(*)>
2582 * from the user(?), and set SADB_SASTATE_DEAD,
2584 * <base, address(SD), policy(*)>
2586 * policy(*) including direction of policy.
2588 * m will always be freed.
2594 const struct sadb_msghdr
*mhp
)
2596 struct sadb_address
*src0
, *dst0
, *src1
= NULL
, *dst1
= NULL
;
2597 struct sadb_x_policy
*xpl0
;
2598 struct secpolicyindex spidx
;
2599 struct secpolicy
*sp
;
2600 ifnet_t internal_if
= NULL
;
2601 struct sadb_x_ipsecif
*ipsecifopts
= NULL
;
2602 int use_src_range
= 0;
2603 int use_dst_range
= 0;
2605 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2608 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
2609 panic("key_spddelete: NULL pointer is passed.\n");
2611 if (mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
] != NULL
&& mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_END
] != NULL
) {
2614 if (mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_START
] != NULL
&& mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_END
] != NULL
) {
2618 if ((!use_src_range
&& mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
) ||
2619 (!use_dst_range
&& mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
) ||
2620 mhp
->ext
[SADB_X_EXT_POLICY
] == NULL
) {
2621 ipseclog((LOG_DEBUG
, "key_spddelete: invalid message is passed.\n"));
2622 return key_senderror(so
, m
, EINVAL
);
2624 if ((use_src_range
&& (mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_SRC_START
] < sizeof(struct sadb_address
)
2625 || mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_SRC_END
] < sizeof(struct sadb_address
))) ||
2626 (!use_src_range
&& mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
)) ||
2627 (use_dst_range
&& (mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_DST_START
] < sizeof(struct sadb_address
)
2628 || mhp
->extlen
[SADB_X_EXT_ADDR_RANGE_DST_END
] < sizeof(struct sadb_address
))) ||
2629 (!use_dst_range
&& mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) ||
2630 mhp
->extlen
[SADB_X_EXT_POLICY
] < sizeof(struct sadb_x_policy
)) {
2631 ipseclog((LOG_DEBUG
, "key_spddelete: invalid message is passed.\n"));
2632 return key_senderror(so
, m
, EINVAL
);
2635 if (use_src_range
) {
2636 src0
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
];
2637 src1
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_SRC_END
];
2639 src0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_SRC
];
2641 if (use_dst_range
) {
2642 dst0
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_START
];
2643 dst1
= (struct sadb_address
*)mhp
->ext
[SADB_X_EXT_ADDR_RANGE_DST_END
];
2645 dst0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_DST
];
2647 xpl0
= (struct sadb_x_policy
*)(void *)mhp
->ext
[SADB_X_EXT_POLICY
];
2648 ipsecifopts
= (struct sadb_x_ipsecif
*)(void *)mhp
->ext
[SADB_X_EXT_IPSECIF
];
2650 /* checking the direction. */
2651 switch (xpl0
->sadb_x_policy_dir
) {
2652 case IPSEC_DIR_INBOUND
:
2653 case IPSEC_DIR_OUTBOUND
:
2656 ipseclog((LOG_DEBUG
, "key_spddelete: Invalid SP direction.\n"));
2657 return key_senderror(so
, m
, EINVAL
);
2660 /* Process interfaces */
2661 if (ipsecifopts
!= NULL
) {
2662 if (ipsecifopts
->sadb_x_ipsecif_internal_if
[0]) {
2663 ifnet_find_by_name(ipsecifopts
->sadb_x_ipsecif_internal_if
, &internal_if
);
2668 /* XXX boundary check against sa_len */
2669 KEY_SETSECSPIDX(xpl0
->sadb_x_policy_dir
,
2672 src0
->sadb_address_prefixlen
,
2673 dst0
->sadb_address_prefixlen
,
2674 src0
->sadb_address_proto
,
2676 use_src_range
? src0
+ 1 : NULL
,
2677 use_src_range
? src1
+ 1 : NULL
,
2678 use_dst_range
? dst0
+ 1 : NULL
,
2679 use_dst_range
? dst1
+ 1 : NULL
,
2682 /* Is there SP in SPD ? */
2683 lck_mtx_lock(sadb_mutex
);
2684 if ((sp
= key_getsp(&spidx
)) == NULL
) {
2685 ipseclog((LOG_DEBUG
, "key_spddelete: no SP found.\n"));
2686 lck_mtx_unlock(sadb_mutex
);
2688 ifnet_release(internal_if
);
2691 return key_senderror(so
, m
, EINVAL
);
2695 ifnet_release(internal_if
);
2699 /* save policy id to buffer to be returned. */
2700 xpl0
->sadb_x_policy_id
= sp
->id
;
2702 sp
->state
= IPSEC_SPSTATE_DEAD
;
2703 key_freesp(sp
, KEY_SADB_LOCKED
);
2704 lck_mtx_unlock(sadb_mutex
);
2709 struct sadb_msg
*newmsg
;
2710 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_X_EXT_POLICY
,
2711 SADB_EXT_ADDRESS_SRC
, SADB_EXT_ADDRESS_DST
,
2712 SADB_X_EXT_ADDR_RANGE_SRC_START
, SADB_X_EXT_ADDR_RANGE_SRC_END
,
2713 SADB_X_EXT_ADDR_RANGE_DST_START
, SADB_X_EXT_ADDR_RANGE_DST_END
};
2715 /* create new sadb_msg to reply. */
2716 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
2718 return key_senderror(so
, m
, ENOBUFS
);
2720 newmsg
= mtod(n
, struct sadb_msg
*);
2721 newmsg
->sadb_msg_errno
= 0;
2722 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
2725 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
2730 * SADB_SPDDELETE2 processing
2733 * from the user(?), and set SADB_SASTATE_DEAD,
2737 * policy(*) including direction of policy.
2739 * m will always be freed.
2745 const struct sadb_msghdr
*mhp
)
2748 struct secpolicy
*sp
;
2750 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2753 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
2754 panic("key_spddelete2: NULL pointer is passed.\n");
2756 if (mhp
->ext
[SADB_X_EXT_POLICY
] == NULL
||
2757 mhp
->extlen
[SADB_X_EXT_POLICY
] < sizeof(struct sadb_x_policy
)) {
2758 ipseclog((LOG_DEBUG
, "key_spddelete2: invalid message is passed.\n"));
2759 key_senderror(so
, m
, EINVAL
);
2763 id
= ((struct sadb_x_policy
*)
2764 (void *)mhp
->ext
[SADB_X_EXT_POLICY
])->sadb_x_policy_id
;
2766 /* Is there SP in SPD ? */
2767 lck_mtx_lock(sadb_mutex
);
2768 if ((sp
= __key_getspbyid(id
)) == NULL
) {
2769 lck_mtx_unlock(sadb_mutex
);
2770 ipseclog((LOG_DEBUG
, "key_spddelete2: no SP found id:%u.\n", id
));
2771 return key_senderror(so
, m
, EINVAL
);
2774 sp
->state
= IPSEC_SPSTATE_DEAD
;
2775 key_freesp(sp
, KEY_SADB_LOCKED
);
2776 lck_mtx_unlock(sadb_mutex
);
2779 struct mbuf
*n
, *nn
;
2780 struct sadb_msg
*newmsg
;
2783 /* create new sadb_msg to reply. */
2784 len
= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
2787 return key_senderror(so
, m
, ENOBUFS
);
2788 MGETHDR(n
, M_WAITOK
, MT_DATA
);
2789 if (n
&& len
> MHLEN
) {
2790 MCLGET(n
, M_WAITOK
);
2791 if ((n
->m_flags
& M_EXT
) == 0) {
2797 return key_senderror(so
, m
, ENOBUFS
);
2803 m_copydata(m
, 0, sizeof(struct sadb_msg
), mtod(n
, caddr_t
) + off
);
2804 off
+= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
2808 panic("length inconsistency in key_spddelete2");
2811 n
->m_next
= m_copym(m
, mhp
->extoff
[SADB_X_EXT_POLICY
],
2812 mhp
->extlen
[SADB_X_EXT_POLICY
], M_WAITOK
);
2815 return key_senderror(so
, m
, ENOBUFS
);
2818 n
->m_pkthdr
.len
= 0;
2819 for (nn
= n
; nn
; nn
= nn
->m_next
)
2820 n
->m_pkthdr
.len
+= nn
->m_len
;
2822 newmsg
= mtod(n
, struct sadb_msg
*);
2823 newmsg
->sadb_msg_errno
= 0;
2824 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
2827 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
2835 const struct sadb_msghdr
*mhp
)
2838 struct secpolicy
*sp
;
2840 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2843 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
2844 panic("key_spdenable: NULL pointer is passed.\n");
2846 if (mhp
->ext
[SADB_X_EXT_POLICY
] == NULL
||
2847 mhp
->extlen
[SADB_X_EXT_POLICY
] < sizeof(struct sadb_x_policy
)) {
2848 ipseclog((LOG_DEBUG
, "key_spdenable: invalid message is passed.\n"));
2849 key_senderror(so
, m
, EINVAL
);
2853 id
= ((struct sadb_x_policy
*)
2854 (void *)mhp
->ext
[SADB_X_EXT_POLICY
])->sadb_x_policy_id
;
2856 /* Is there SP in SPD ? */
2857 lck_mtx_lock(sadb_mutex
);
2858 if ((sp
= __key_getspbyid(id
)) == NULL
) {
2859 lck_mtx_unlock(sadb_mutex
);
2860 ipseclog((LOG_DEBUG
, "key_spdenable: no SP found id:%u.\n", id
));
2861 return key_senderror(so
, m
, EINVAL
);
2865 lck_mtx_unlock(sadb_mutex
);
2869 struct sadb_msg
*newmsg
;
2870 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_X_EXT_POLICY
};
2872 /* create new sadb_msg to reply. */
2873 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
2875 return key_senderror(so
, m
, ENOBUFS
);
2877 if (n
->m_len
< sizeof(struct sadb_msg
)) {
2878 n
= m_pullup(n
, sizeof(struct sadb_msg
));
2880 return key_senderror(so
, m
, ENOBUFS
);
2882 newmsg
= mtod(n
, struct sadb_msg
*);
2883 newmsg
->sadb_msg_errno
= 0;
2884 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
2887 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
2895 const struct sadb_msghdr
*mhp
)
2898 struct secpolicy
*sp
;
2900 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2903 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
2904 panic("key_spddisable: NULL pointer is passed.\n");
2906 if (mhp
->ext
[SADB_X_EXT_POLICY
] == NULL
||
2907 mhp
->extlen
[SADB_X_EXT_POLICY
] < sizeof(struct sadb_x_policy
)) {
2908 ipseclog((LOG_DEBUG
, "key_spddisable: invalid message is passed.\n"));
2909 key_senderror(so
, m
, EINVAL
);
2913 id
= ((struct sadb_x_policy
*)
2914 (void *)mhp
->ext
[SADB_X_EXT_POLICY
])->sadb_x_policy_id
;
2916 /* Is there SP in SPD ? */
2917 lck_mtx_lock(sadb_mutex
);
2918 if ((sp
= __key_getspbyid(id
)) == NULL
) {
2919 lck_mtx_unlock(sadb_mutex
);
2920 ipseclog((LOG_DEBUG
, "key_spddisable: no SP found id:%u.\n", id
));
2921 return key_senderror(so
, m
, EINVAL
);
2925 lck_mtx_unlock(sadb_mutex
);
2929 struct sadb_msg
*newmsg
;
2930 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_X_EXT_POLICY
};
2932 /* create new sadb_msg to reply. */
2933 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
2935 return key_senderror(so
, m
, ENOBUFS
);
2937 if (n
->m_len
< sizeof(struct sadb_msg
)) {
2938 n
= m_pullup(n
, sizeof(struct sadb_msg
));
2940 return key_senderror(so
, m
, ENOBUFS
);
2942 newmsg
= mtod(n
, struct sadb_msg
*);
2943 newmsg
->sadb_msg_errno
= 0;
2944 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
2947 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
2952 * SADB_X_GET processing
2957 * <base, address(SD), policy>
2959 * policy(*) including direction of policy.
2961 * m will always be freed.
2967 const struct sadb_msghdr
*mhp
)
2970 struct secpolicy
*sp
;
2973 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2976 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
2977 panic("key_spdget: NULL pointer is passed.\n");
2979 if (mhp
->ext
[SADB_X_EXT_POLICY
] == NULL
||
2980 mhp
->extlen
[SADB_X_EXT_POLICY
] < sizeof(struct sadb_x_policy
)) {
2981 ipseclog((LOG_DEBUG
, "key_spdget: invalid message is passed.\n"));
2982 return key_senderror(so
, m
, EINVAL
);
2985 id
= ((struct sadb_x_policy
*)
2986 (void *)mhp
->ext
[SADB_X_EXT_POLICY
])->sadb_x_policy_id
;
2988 /* Is there SP in SPD ? */
2989 lck_mtx_lock(sadb_mutex
);
2990 if ((sp
= __key_getspbyid(id
)) == NULL
) {
2991 ipseclog((LOG_DEBUG
, "key_spdget: no SP found id:%u.\n", id
));
2992 lck_mtx_unlock(sadb_mutex
);
2993 return key_senderror(so
, m
, ENOENT
);
2995 lck_mtx_unlock(sadb_mutex
);
2996 n
= key_setdumpsp(sp
, SADB_X_SPDGET
, 0, mhp
->msg
->sadb_msg_pid
);
2999 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ONE
);
3001 return key_senderror(so
, m
, ENOBUFS
);
3005 * SADB_X_SPDACQUIRE processing.
3006 * Acquire policy and SA(s) for a *OUTBOUND* packet.
3009 * to KMD, and expect to receive
3010 * <base> with SADB_X_SPDACQUIRE if error occurred,
3013 * with SADB_X_SPDUPDATE from KMD by PF_KEY.
3014 * policy(*) is without policy requests.
3017 * others: error number
3021 struct secpolicy
*sp
)
3023 struct mbuf
*result
= NULL
, *m
;
3024 struct secspacq
*newspacq
;
3027 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3031 panic("key_spdacquire: NULL pointer is passed.\n");
3032 if (sp
->req
!= NULL
)
3033 panic("key_spdacquire: called but there is request.\n");
3034 if (sp
->policy
!= IPSEC_POLICY_IPSEC
)
3035 panic("key_spdacquire: policy mismathed. IPsec is expected.\n");
3037 /* get a entry to check whether sent message or not. */
3038 lck_mtx_lock(sadb_mutex
);
3039 if ((newspacq
= key_getspacq(&sp
->spidx
)) != NULL
) {
3040 if (key_blockacq_count
< newspacq
->count
) {
3041 /* reset counter and do send message. */
3042 newspacq
->count
= 0;
3044 /* increment counter and do nothing. */
3046 lck_mtx_unlock(sadb_mutex
);
3050 /* make new entry for blocking to send SADB_ACQUIRE. */
3051 if ((newspacq
= key_newspacq(&sp
->spidx
)) == NULL
) {
3052 lck_mtx_unlock(sadb_mutex
);
3055 /* add to acqtree */
3056 LIST_INSERT_HEAD(&spacqtree
, newspacq
, chain
);
3057 key_start_timehandler();
3059 lck_mtx_unlock(sadb_mutex
);
3060 /* create new sadb_msg to reply. */
3061 m
= key_setsadbmsg(SADB_X_SPDACQUIRE
, 0, 0, 0, 0, 0);
3068 result
->m_pkthdr
.len
= 0;
3069 for (m
= result
; m
; m
= m
->m_next
)
3070 result
->m_pkthdr
.len
+= m
->m_len
;
3072 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
3073 PFKEY_UNIT64(result
->m_pkthdr
.len
);
3075 return key_sendup_mbuf(NULL
, m
, KEY_SENDUP_REGISTERED
);
3084 * SADB_SPDFLUSH processing
3087 * from the user, and free all entries in secpctree.
3091 * NOTE: what to do is only marking SADB_SASTATE_DEAD.
3093 * m will always be freed.
3099 const struct sadb_msghdr
*mhp
)
3101 struct sadb_msg
*newmsg
;
3102 struct secpolicy
*sp
;
3106 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
3107 panic("key_spdflush: NULL pointer is passed.\n");
3109 if (m
->m_len
!= PFKEY_ALIGN8(sizeof(struct sadb_msg
)))
3110 return key_senderror(so
, m
, EINVAL
);
3112 lck_mtx_lock(sadb_mutex
);
3113 for (dir
= 0; dir
< IPSEC_DIR_MAX
; dir
++) {
3114 LIST_FOREACH(sp
, &sptree
[dir
], chain
) {
3115 sp
->state
= IPSEC_SPSTATE_DEAD
;
3118 lck_mtx_unlock(sadb_mutex
);
3120 if (sizeof(struct sadb_msg
) > m
->m_len
+ M_TRAILINGSPACE(m
)) {
3121 ipseclog((LOG_DEBUG
, "key_spdflush: No more memory.\n"));
3122 return key_senderror(so
, m
, ENOBUFS
);
3128 m
->m_pkthdr
.len
= m
->m_len
= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
3129 newmsg
= mtod(m
, struct sadb_msg
*);
3130 newmsg
->sadb_msg_errno
= 0;
3131 newmsg
->sadb_msg_len
= PFKEY_UNIT64(m
->m_pkthdr
.len
);
3133 return key_sendup_mbuf(so
, m
, KEY_SENDUP_ALL
);
3137 * SADB_SPDDUMP processing
3140 * from the user, and dump all SP leaves
3145 * m will always be freed.
3152 const struct sadb_msghdr
*mhp
)
3154 struct secpolicy
*sp
, **spbuf
= NULL
, **sp_ptr
;
3155 int cnt
= 0, bufcount
;
3161 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
3162 panic("key_spddump: NULL pointer is passed.\n");
3164 if ((bufcount
= ipsec_policy_count
) == 0) {
3168 bufcount
+= 256; /* extra */
3169 KMALLOC_WAIT(spbuf
, struct secpolicy
**, bufcount
* sizeof(struct secpolicy
*));
3170 if (spbuf
== NULL
) {
3171 ipseclog((LOG_DEBUG
, "key_spddump: No more memory.\n"));
3175 lck_mtx_lock(sadb_mutex
);
3176 /* search SPD entry, make list. */
3178 for (dir
= 0; dir
< IPSEC_DIR_MAX
; dir
++) {
3179 LIST_FOREACH(sp
, &sptree
[dir
], chain
) {
3180 if (cnt
== bufcount
)
3181 break; /* buffer full */
3187 lck_mtx_unlock(sadb_mutex
);
3197 n
= key_setdumpsp(*sp_ptr
++, SADB_X_SPDDUMP
, cnt
,
3198 mhp
->msg
->sadb_msg_pid
);
3201 key_sendup_mbuf(so
, n
, KEY_SENDUP_ONE
);
3204 lck_mtx_lock(sadb_mutex
);
3205 while (sp_ptr
> spbuf
)
3206 key_freesp(*(--sp_ptr
), KEY_SADB_LOCKED
);
3207 lck_mtx_unlock(sadb_mutex
);
3213 return key_senderror(so
, m
, error
);
3220 static struct mbuf
*
3222 struct secpolicy
*sp
,
3227 struct mbuf
*result
= NULL
, *m
;
3229 m
= key_setsadbmsg(type
, 0, SADB_SATYPE_UNSPEC
, seq
, pid
, sp
->refcnt
);
3234 if (sp
->spidx
.src_range
.start
.ss_len
> 0) {
3235 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_START
,
3236 (struct sockaddr
*)&sp
->spidx
.src_range
.start
, sp
->spidx
.prefs
,
3237 sp
->spidx
.ul_proto
);
3242 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_END
,
3243 (struct sockaddr
*)&sp
->spidx
.src_range
.end
, sp
->spidx
.prefs
,
3244 sp
->spidx
.ul_proto
);
3249 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
3250 (struct sockaddr
*)&sp
->spidx
.src
, sp
->spidx
.prefs
,
3251 sp
->spidx
.ul_proto
);
3257 if (sp
->spidx
.dst_range
.start
.ss_len
> 0) {
3258 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_START
,
3259 (struct sockaddr
*)&sp
->spidx
.dst_range
.start
, sp
->spidx
.prefd
,
3260 sp
->spidx
.ul_proto
);
3265 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_END
,
3266 (struct sockaddr
*)&sp
->spidx
.dst_range
.end
, sp
->spidx
.prefd
,
3267 sp
->spidx
.ul_proto
);
3272 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
3273 (struct sockaddr
*)&sp
->spidx
.dst
, sp
->spidx
.prefd
,
3274 sp
->spidx
.ul_proto
);
3280 if (sp
->spidx
.internal_if
|| sp
->outgoing_if
|| sp
->ipsec_if
|| sp
->disabled
) {
3281 m
= key_setsadbipsecif(sp
->spidx
.internal_if
, sp
->outgoing_if
, sp
->ipsec_if
, sp
->disabled
);
3292 if ((result
->m_flags
& M_PKTHDR
) == 0)
3295 if (result
->m_len
< sizeof(struct sadb_msg
)) {
3296 result
= m_pullup(result
, sizeof(struct sadb_msg
));
3301 result
->m_pkthdr
.len
= 0;
3302 for (m
= result
; m
; m
= m
->m_next
)
3303 result
->m_pkthdr
.len
+= m
->m_len
;
3305 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
3306 PFKEY_UNIT64(result
->m_pkthdr
.len
);
3316 * get PFKEY message length for security policy and request.
3320 struct secpolicy
*sp
)
3324 tlen
= sizeof(struct sadb_x_policy
);
3326 /* if is the policy for ipsec ? */
3327 if (sp
->policy
!= IPSEC_POLICY_IPSEC
)
3330 /* get length of ipsec requests */
3332 struct ipsecrequest
*isr
;
3335 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
3336 len
= sizeof(struct sadb_x_ipsecrequest
)
3337 + isr
->saidx
.src
.ss_len
3338 + isr
->saidx
.dst
.ss_len
;
3340 tlen
+= PFKEY_ALIGN8(len
);
3348 * SADB_SPDEXPIRE processing
3350 * <base, address(SD), lifetime(CH), policy>
3354 * others : error number
3358 struct secpolicy
*sp
)
3360 struct mbuf
*result
= NULL
, *m
;
3363 struct sadb_lifetime
*lt
;
3365 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3369 panic("key_spdexpire: NULL pointer is passed.\n");
3371 /* set msg header */
3372 m
= key_setsadbmsg(SADB_X_SPDEXPIRE
, 0, 0, 0, 0, 0);
3379 /* create lifetime extension (current and hard) */
3380 len
= PFKEY_ALIGN8(sizeof(*lt
)) * 2;
3381 m
= key_alloc_mbuf(len
);
3382 if (!m
|| m
->m_next
) { /*XXX*/
3388 bzero(mtod(m
, caddr_t
), len
);
3389 lt
= mtod(m
, struct sadb_lifetime
*);
3390 lt
->sadb_lifetime_len
= PFKEY_UNIT64(sizeof(struct sadb_lifetime
));
3391 lt
->sadb_lifetime_exttype
= SADB_EXT_LIFETIME_CURRENT
;
3392 lt
->sadb_lifetime_allocations
= 0;
3393 lt
->sadb_lifetime_bytes
= 0;
3394 lt
->sadb_lifetime_addtime
= sp
->created
;
3395 lt
->sadb_lifetime_usetime
= sp
->lastused
;
3396 lt
= (struct sadb_lifetime
*)(void *)(mtod(m
, caddr_t
) + len
/ 2);
3397 lt
->sadb_lifetime_len
= PFKEY_UNIT64(sizeof(struct sadb_lifetime
));
3398 lt
->sadb_lifetime_exttype
= SADB_EXT_LIFETIME_HARD
;
3399 lt
->sadb_lifetime_allocations
= 0;
3400 lt
->sadb_lifetime_bytes
= 0;
3401 lt
->sadb_lifetime_addtime
= sp
->lifetime
;
3402 lt
->sadb_lifetime_usetime
= sp
->validtime
;
3405 /* set sadb_address(es) for source */
3406 if (sp
->spidx
.src_range
.start
.ss_len
> 0) {
3407 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_START
,
3408 (struct sockaddr
*)&sp
->spidx
.src_range
.start
, sp
->spidx
.prefs
,
3409 sp
->spidx
.ul_proto
);
3416 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_END
,
3417 (struct sockaddr
*)&sp
->spidx
.src_range
.end
, sp
->spidx
.prefs
,
3418 sp
->spidx
.ul_proto
);
3425 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
3426 (struct sockaddr
*)&sp
->spidx
.src
, sp
->spidx
.prefs
,
3427 sp
->spidx
.ul_proto
);
3435 /* set sadb_address(es) for dest */
3436 if (sp
->spidx
.dst_range
.start
.ss_len
> 0) {
3437 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_START
,
3438 (struct sockaddr
*)&sp
->spidx
.dst_range
.start
, sp
->spidx
.prefd
,
3439 sp
->spidx
.ul_proto
);
3446 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_END
,
3447 (struct sockaddr
*)&sp
->spidx
.dst_range
.end
, sp
->spidx
.prefd
,
3448 sp
->spidx
.ul_proto
);
3455 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
3456 (struct sockaddr
*)&sp
->spidx
.dst
, sp
->spidx
.prefd
,
3457 sp
->spidx
.ul_proto
);
3473 if ((result
->m_flags
& M_PKTHDR
) == 0) {
3478 if (result
->m_len
< sizeof(struct sadb_msg
)) {
3479 result
= m_pullup(result
, sizeof(struct sadb_msg
));
3480 if (result
== NULL
) {
3486 result
->m_pkthdr
.len
= 0;
3487 for (m
= result
; m
; m
= m
->m_next
)
3488 result
->m_pkthdr
.len
+= m
->m_len
;
3490 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
3491 PFKEY_UNIT64(result
->m_pkthdr
.len
);
3493 return key_sendup_mbuf(NULL
, result
, KEY_SENDUP_REGISTERED
);
3501 /* %%% SAD management */
3503 * allocating a memory for new SA head, and copy from the values of mhp.
3504 * OUT: NULL : failure due to the lack of memory.
3505 * others : pointer to new SA head.
3507 static struct secashead
*
3508 key_newsah(struct secasindex
*saidx
,
3513 struct secashead
*newsah
;
3517 panic("key_newsaidx: NULL pointer is passed.\n");
3519 newsah
= keydb_newsecashead();
3523 bcopy(saidx
, &newsah
->saidx
, sizeof(newsah
->saidx
));
3525 /* remove the ports */
3526 switch (saidx
->src
.ss_family
) {
3528 ((struct sockaddr_in
*)(&newsah
->saidx
.src
))->sin_port
= IPSEC_PORT_ANY
;
3531 ((struct sockaddr_in6
*)(&newsah
->saidx
.src
))->sin6_port
= IPSEC_PORT_ANY
;
3536 switch (saidx
->dst
.ss_family
) {
3538 ((struct sockaddr_in
*)(&newsah
->saidx
.dst
))->sin_port
= IPSEC_PORT_ANY
;
3541 ((struct sockaddr_in6
*)(&newsah
->saidx
.dst
))->sin6_port
= IPSEC_PORT_ANY
;
3547 newsah
->outgoing_if
= outgoing_if
;
3549 ifnet_reference(ipsec_if
);
3550 newsah
->ipsec_if
= ipsec_if
;
3553 /* add to saidxtree */
3554 newsah
->state
= SADB_SASTATE_MATURE
;
3555 LIST_INSERT_HEAD(&sahtree
, newsah
, chain
);
3556 key_start_timehandler();
3562 * delete SA index and all SA registerd.
3566 struct secashead
*sah
)
3568 struct secasvar
*sav
, *nextsav
;
3569 u_int stateidx
, state
;
3572 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
3576 panic("key_delsah: NULL pointer is passed.\n");
3578 /* searching all SA registerd in the secindex. */
3580 stateidx
< _ARRAYLEN(saorder_state_any
);
3583 state
= saorder_state_any
[stateidx
];
3584 for (sav
= (struct secasvar
*)LIST_FIRST(&sah
->savtree
[state
]);
3588 nextsav
= LIST_NEXT(sav
, chain
);
3590 if (sav
->refcnt
> 0) {
3591 /* give up to delete this sa */
3597 KEY_CHKSASTATE(state
, sav
->state
, "key_delsah");
3599 key_freesav(sav
, KEY_SADB_LOCKED
);
3601 /* remove back pointer */
3607 /* don't delete sah only if there are savs. */
3611 ROUTE_RELEASE(&sah
->sa_route
);
3613 if (sah
->ipsec_if
) {
3614 ifnet_release(sah
->ipsec_if
);
3615 sah
->ipsec_if
= NULL
;
3626 /* remove from tree of SA index */
3627 if (__LIST_CHAINED(sah
))
3628 LIST_REMOVE(sah
, chain
);
3636 * allocating a new SA with LARVAL state. key_add() and key_getspi() call,
3637 * and copy the values of mhp into new buffer.
3638 * When SAD message type is GETSPI:
3639 * to set sequence number from acq_seq++,
3640 * to set zero to SPI.
3641 * not to call key_setsava().
3643 * others : pointer to new secasvar.
3645 * does not modify mbuf. does not free mbuf on error.
3647 static struct secasvar
*
3650 const struct sadb_msghdr
*mhp
,
3651 struct secashead
*sah
,
3655 struct secasvar
*newsav
;
3656 const struct sadb_sa
*xsa
;
3658 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
3661 if (m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
|| sah
== NULL
)
3662 panic("key_newsa: NULL pointer is passed.\n");
3664 KMALLOC_NOWAIT(newsav
, struct secasvar
*, sizeof(struct secasvar
));
3665 if (newsav
== NULL
) {
3666 lck_mtx_unlock(sadb_mutex
);
3667 KMALLOC_WAIT(newsav
, struct secasvar
*, sizeof(struct secasvar
));
3668 lck_mtx_lock(sadb_mutex
);
3669 if (newsav
== NULL
) {
3670 ipseclog((LOG_DEBUG
, "key_newsa: No more memory.\n"));
3675 bzero((caddr_t
)newsav
, sizeof(struct secasvar
));
3677 switch (mhp
->msg
->sadb_msg_type
) {
3679 key_setspi(newsav
, 0);
3681 #if IPSEC_DOSEQCHECK
3682 /* sync sequence number */
3683 if (mhp
->msg
->sadb_msg_seq
== 0)
3685 (acq_seq
= (acq_seq
== ~0 ? 1 : ++acq_seq
));
3688 newsav
->seq
= mhp
->msg
->sadb_msg_seq
;
3693 if (mhp
->ext
[SADB_EXT_SA
] == NULL
) {
3695 ipseclog((LOG_DEBUG
, "key_newsa: invalid message is passed.\n"));
3699 xsa
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
3700 key_setspi(newsav
, xsa
->sadb_sa_spi
);
3701 newsav
->seq
= mhp
->msg
->sadb_msg_seq
;
3709 if (mhp
->ext
[SADB_X_EXT_SA2
] != NULL
) {
3710 if (((struct sadb_x_sa2
*)(void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_alwaysexpire
)
3711 newsav
->always_expire
= 1;
3712 newsav
->flags2
= ((struct sadb_x_sa2
*)(void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_flags
;
3713 if (newsav
->flags2
& SADB_X_EXT_SA2_DELETE_ON_DETACH
) {
3718 /* copy sav values */
3719 if (mhp
->msg
->sadb_msg_type
!= SADB_GETSPI
) {
3720 *errp
= key_setsaval(newsav
, m
, mhp
);
3726 /* For get SPI, if has a hard lifetime, apply */
3727 const struct sadb_lifetime
*lft0
;
3730 lft0
= (struct sadb_lifetime
*)(void *)mhp
->ext
[SADB_EXT_LIFETIME_HARD
];
3732 /* make lifetime for CURRENT */
3733 KMALLOC_NOWAIT(newsav
->lft_c
, struct sadb_lifetime
*,
3734 sizeof(struct sadb_lifetime
));
3735 if (newsav
->lft_c
== NULL
) {
3736 lck_mtx_unlock(sadb_mutex
);
3737 KMALLOC_WAIT(newsav
->lft_c
, struct sadb_lifetime
*,
3738 sizeof(struct sadb_lifetime
));
3739 lck_mtx_lock(sadb_mutex
);
3740 if (newsav
->lft_c
== NULL
) {
3741 ipseclog((LOG_DEBUG
, "key_newsa: No more memory.\n"));
3750 newsav
->lft_c
->sadb_lifetime_len
= PFKEY_UNIT64(sizeof(struct sadb_lifetime
));
3751 newsav
->lft_c
->sadb_lifetime_exttype
= SADB_EXT_LIFETIME_CURRENT
;
3752 newsav
->lft_c
->sadb_lifetime_allocations
= 0;
3753 newsav
->lft_c
->sadb_lifetime_bytes
= 0;
3754 newsav
->lft_c
->sadb_lifetime_addtime
= tv
.tv_sec
;
3755 newsav
->lft_c
->sadb_lifetime_usetime
= 0;
3757 if (mhp
->extlen
[SADB_EXT_LIFETIME_HARD
] < sizeof(*lft0
)) {
3758 ipseclog((LOG_DEBUG
, "key_newsa: invalid hard lifetime ext len.\n"));
3763 newsav
->lft_h
= (struct sadb_lifetime
*)key_newbuf(lft0
, sizeof(*lft0
));
3764 if (newsav
->lft_h
== NULL
) {
3765 ipseclog((LOG_DEBUG
, "key_newsa: No more memory.\n"));
3777 newsav
->created
= tv
.tv_sec
;
3780 newsav
->pid
= mhp
->msg
->sadb_msg_pid
;
3785 newsav
->state
= SADB_SASTATE_LARVAL
;
3786 LIST_INSERT_TAIL(&sah
->savtree
[SADB_SASTATE_LARVAL
], newsav
,
3794 * allocating a new SA with LARVAL state. key_add() and key_getspi() call,
3795 * and copy the values passed into new buffer.
3796 * When SAD message type is GETSPI:
3797 * to set sequence number from acq_seq++,
3798 * to set zero to SPI.
3799 * not to call key_setsava().
3801 * others : pointer to new secasvar.
3804 key_newsav2(struct secashead
*sah
,
3810 struct sadb_key
*key_auth
,
3811 u_int16_t key_auth_len
,
3812 struct sadb_key
*key_enc
,
3813 u_int16_t key_enc_len
,
3814 u_int16_t natt_port
,
3818 struct sadb_lifetime
*lifetime_hard
,
3819 struct sadb_lifetime
*lifetime_soft
)
3821 struct secasvar
*newsav
;
3823 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
3827 panic("key_newsa: NULL pointer is passed.\n");
3829 KMALLOC_NOWAIT(newsav
, struct secasvar
*, sizeof(struct secasvar
));
3830 if (newsav
== NULL
) {
3831 lck_mtx_unlock(sadb_mutex
);
3832 KMALLOC_WAIT(newsav
, struct secasvar
*, sizeof(struct secasvar
));
3833 lck_mtx_lock(sadb_mutex
);
3834 if (newsav
== NULL
) {
3835 ipseclog((LOG_DEBUG
, "key_newsa: No more memory.\n"));
3839 bzero((caddr_t
)newsav
, sizeof(struct secasvar
));
3841 #if IPSEC_DOSEQCHECK
3842 /* sync sequence number */
3844 newsav
->seq
= (acq_seq
= (acq_seq
== ~0 ? 1 : ++acq_seq
));
3848 key_setspi(newsav
, spi
);
3850 if (key_setsaval2(newsav
,
3874 newsav
->created
= tv
.tv_sec
;
3882 if (spi
&& key_auth
&& key_auth_len
&& key_enc
&& key_enc_len
) {
3883 newsav
->state
= SADB_SASTATE_MATURE
;
3884 LIST_INSERT_TAIL(&sah
->savtree
[SADB_SASTATE_MATURE
], newsav
,
3887 newsav
->state
= SADB_SASTATE_LARVAL
;
3888 LIST_INSERT_TAIL(&sah
->savtree
[SADB_SASTATE_LARVAL
], newsav
,
3897 key_migratesav(struct secasvar
*sav
,
3898 struct secashead
*newsah
)
3900 if (sav
== NULL
|| newsah
== NULL
|| sav
->state
!= SADB_SASTATE_MATURE
) {
3904 /* remove from SA header */
3905 if (__LIST_CHAINED(sav
))
3906 LIST_REMOVE(sav
, chain
);
3909 LIST_INSERT_TAIL(&newsah
->savtree
[SADB_SASTATE_MATURE
], sav
, secasvar
, chain
);
3914 * free() SA variable entry.
3918 struct secasvar
*sav
)
3921 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
3925 panic("key_delsav: NULL pointer is passed.\n");
3927 if (sav
->refcnt
> 0)
3928 return; /* can't free */
3930 /* remove from SA header */
3931 if (__LIST_CHAINED(sav
))
3932 LIST_REMOVE(sav
, chain
);
3935 if (sav
->spihash
.le_prev
|| sav
->spihash
.le_next
)
3936 LIST_REMOVE(sav
, spihash
);
3938 if (sav
->key_auth
!= NULL
) {
3939 bzero(_KEYBUF(sav
->key_auth
), _KEYLEN(sav
->key_auth
));
3940 KFREE(sav
->key_auth
);
3941 sav
->key_auth
= NULL
;
3943 if (sav
->key_enc
!= NULL
) {
3944 bzero(_KEYBUF(sav
->key_enc
), _KEYLEN(sav
->key_enc
));
3945 KFREE(sav
->key_enc
);
3946 sav
->key_enc
= NULL
;
3949 bzero(sav
->sched
, sav
->schedlen
);
3953 if (sav
->replay
!= NULL
) {
3954 keydb_delsecreplay(sav
->replay
);
3957 if (sav
->lft_c
!= NULL
) {
3961 if (sav
->lft_h
!= NULL
) {
3965 if (sav
->lft_s
!= NULL
) {
3969 if (sav
->iv
!= NULL
) {
3983 * others : found, pointer to a SA.
3985 static struct secashead
*
3986 key_getsah(struct secasindex
*saidx
)
3988 struct secashead
*sah
;
3990 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
3992 LIST_FOREACH(sah
, &sahtree
, chain
) {
3993 if (sah
->state
== SADB_SASTATE_DEAD
)
3995 if (key_cmpsaidx(&sah
->saidx
, saidx
, CMP_REQID
))
4003 key_newsah2 (struct secasindex
*saidx
,
4006 struct secashead
*sah
;
4008 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4010 sah
= key_getsah(saidx
);
4012 return(key_newsah(saidx
, NULL
, 0, dir
));
4018 * check not to be duplicated SPI.
4019 * NOTE: this function is too slow due to searching all SAD.
4022 * others : found, pointer to a SA.
4024 static struct secasvar
*
4026 struct secasindex
*saidx
,
4029 struct secasvar
*sav
;
4030 u_int stateidx
, state
;
4032 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4034 /* check address family */
4035 if (saidx
->src
.ss_family
!= saidx
->dst
.ss_family
) {
4036 ipseclog((LOG_DEBUG
, "key_checkspidup: address family mismatched.\n"));
4041 LIST_FOREACH(sav
, &spihash
[SPIHASH(spi
)], spihash
) {
4042 if (sav
->spi
!= spi
)
4045 stateidx
< _ARRAYLEN(saorder_state_alive
);
4047 state
= saorder_state_alive
[stateidx
];
4048 if (sav
->state
== state
&&
4049 key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
))
4059 struct secasvar
*sav
,
4062 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4064 if (sav
->spihash
.le_prev
|| sav
->spihash
.le_next
)
4065 LIST_REMOVE(sav
, spihash
);
4066 LIST_INSERT_HEAD(&spihash
[SPIHASH(spi
)], sav
, spihash
);
4071 * search SAD litmited alive SA, protocol, SPI.
4074 * others : found, pointer to a SA.
4076 static struct secasvar
*
4078 struct secashead
*sah
,
4081 struct secasvar
*sav
, *match
;
4082 u_int stateidx
, state
, matchidx
;
4084 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4086 matchidx
= _ARRAYLEN(saorder_state_alive
);
4087 LIST_FOREACH(sav
, &spihash
[SPIHASH(spi
)], spihash
) {
4088 if (sav
->spi
!= spi
)
4090 if (sav
->sah
!= sah
)
4092 for (stateidx
= 0; stateidx
< matchidx
; stateidx
++) {
4093 state
= saorder_state_alive
[stateidx
];
4094 if (sav
->state
== state
) {
4096 matchidx
= stateidx
;
4106 * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*.
4107 * You must update these if need.
4111 * does not modify mbuf. does not free mbuf on error.
4115 struct secasvar
*sav
,
4117 const struct sadb_msghdr
*mhp
)
4120 const struct esp_algorithm
*algo
;
4125 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4128 if (m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
4129 panic("key_setsaval: NULL pointer is passed.\n");
4131 /* initialization */
4133 sav
->key_auth
= NULL
;
4134 sav
->key_enc
= NULL
;
4141 sav
->remote_ike_port
= 0;
4142 sav
->natt_last_activity
= natt_now
;
4143 sav
->natt_encapsulated_src_port
= 0;
4146 if (mhp
->ext
[SADB_EXT_SA
] != NULL
) {
4147 const struct sadb_sa
*sa0
;
4149 sa0
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
4150 if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(*sa0
)) {
4151 ipseclog((LOG_DEBUG
, "key_setsaval: invalid message size.\n"));
4156 sav
->alg_auth
= sa0
->sadb_sa_auth
;
4157 sav
->alg_enc
= sa0
->sadb_sa_encrypt
;
4158 sav
->flags
= sa0
->sadb_sa_flags
;
4161 * Verify that a nat-traversal port was specified if
4162 * the nat-traversal flag is set.
4164 if ((sav
->flags
& SADB_X_EXT_NATT
) != 0) {
4165 if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(struct sadb_sa_2
) ||
4166 ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_port
== 0) {
4167 ipseclog((LOG_DEBUG
, "key_setsaval: natt port not set.\n"));
4171 sav
->remote_ike_port
= ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_port
;
4172 sav
->natt_interval
= ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_interval
;
4173 sav
->natt_offload_interval
= ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_offload_interval
;
4177 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
4178 * SADB_X_EXT_NATT is set and SADB_X_EXT_NATT_KEEPALIVE is not
4179 * set (we're not behind nat) - otherwise clear it.
4181 if ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0)
4182 if ((sav
->flags
& SADB_X_EXT_NATT
) == 0 ||
4183 (sav
->flags
& SADB_X_EXT_NATT_KEEPALIVE
) != 0)
4184 sav
->flags
&= ~SADB_X_EXT_NATT_MULTIPLEUSERS
;
4187 if ((sa0
->sadb_sa_flags
& SADB_X_EXT_OLD
) == 0) {
4188 sav
->replay
= keydb_newsecreplay(sa0
->sadb_sa_replay
);
4189 if (sav
->replay
== NULL
) {
4190 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4197 /* Authentication keys */
4198 if (mhp
->ext
[SADB_EXT_KEY_AUTH
] != NULL
) {
4199 const struct sadb_key
*key0
;
4202 key0
= (const struct sadb_key
*)mhp
->ext
[SADB_EXT_KEY_AUTH
];
4203 len
= mhp
->extlen
[SADB_EXT_KEY_AUTH
];
4206 if (len
< sizeof(*key0
)) {
4207 ipseclog((LOG_DEBUG
, "key_setsaval: invalid auth key ext len. len = %d\n", len
));
4211 switch (mhp
->msg
->sadb_msg_satype
) {
4212 case SADB_SATYPE_AH
:
4213 case SADB_SATYPE_ESP
:
4214 if (len
== PFKEY_ALIGN8(sizeof(struct sadb_key
)) &&
4215 sav
->alg_auth
!= SADB_X_AALG_NULL
)
4218 case SADB_X_SATYPE_IPCOMP
:
4224 ipseclog((LOG_DEBUG
, "key_setsaval: invalid key_auth values.\n"));
4228 sav
->key_auth
= (struct sadb_key
*)key_newbuf(key0
, len
);
4229 if (sav
->key_auth
== NULL
) {
4230 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4236 /* Encryption key */
4237 if (mhp
->ext
[SADB_EXT_KEY_ENCRYPT
] != NULL
) {
4238 const struct sadb_key
*key0
;
4241 key0
= (const struct sadb_key
*)mhp
->ext
[SADB_EXT_KEY_ENCRYPT
];
4242 len
= mhp
->extlen
[SADB_EXT_KEY_ENCRYPT
];
4245 if (len
< sizeof(*key0
)) {
4246 ipseclog((LOG_DEBUG
, "key_setsaval: invalid encryption key ext len. len = %d\n", len
));
4250 switch (mhp
->msg
->sadb_msg_satype
) {
4251 case SADB_SATYPE_ESP
:
4252 if (len
== PFKEY_ALIGN8(sizeof(struct sadb_key
)) &&
4253 sav
->alg_enc
!= SADB_EALG_NULL
) {
4254 ipseclog((LOG_DEBUG
, "key_setsaval: invalid ESP algorithm.\n"));
4258 sav
->key_enc
= (struct sadb_key
*)key_newbuf(key0
, len
);
4259 if (sav
->key_enc
== NULL
) {
4260 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4265 case SADB_X_SATYPE_IPCOMP
:
4266 if (len
!= PFKEY_ALIGN8(sizeof(struct sadb_key
)))
4268 sav
->key_enc
= NULL
; /*just in case*/
4270 case SADB_SATYPE_AH
:
4276 ipseclog((LOG_DEBUG
, "key_setsaval: invalid key_enc value.\n"));
4284 switch (mhp
->msg
->sadb_msg_satype
) {
4285 case SADB_SATYPE_ESP
:
4287 algo
= esp_algorithm_lookup(sav
->alg_enc
);
4288 if (algo
&& algo
->ivlen
)
4289 sav
->ivlen
= (*algo
->ivlen
)(algo
, sav
);
4290 if (sav
->ivlen
== 0)
4292 KMALLOC_NOWAIT(sav
->iv
, caddr_t
, sav
->ivlen
);
4294 lck_mtx_unlock(sadb_mutex
);
4295 KMALLOC_WAIT(sav
->iv
, caddr_t
, sav
->ivlen
);
4296 lck_mtx_lock(sadb_mutex
);
4298 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4305 if (sav
->alg_enc
== SADB_X_EALG_AES_GCM
) {
4306 bzero(sav
->iv
, sav
->ivlen
);
4308 key_randomfill(sav
->iv
, sav
->ivlen
);
4312 case SADB_SATYPE_AH
:
4313 case SADB_X_SATYPE_IPCOMP
:
4316 ipseclog((LOG_DEBUG
, "key_setsaval: invalid SA type.\n"));
4323 sav
->created
= tv
.tv_sec
;
4325 /* make lifetime for CURRENT */
4326 KMALLOC_NOWAIT(sav
->lft_c
, struct sadb_lifetime
*,
4327 sizeof(struct sadb_lifetime
));
4328 if (sav
->lft_c
== NULL
) {
4329 lck_mtx_unlock(sadb_mutex
);
4330 KMALLOC_WAIT(sav
->lft_c
, struct sadb_lifetime
*,
4331 sizeof(struct sadb_lifetime
));
4332 lck_mtx_lock(sadb_mutex
);
4333 if (sav
->lft_c
== NULL
) {
4334 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4342 sav
->lft_c
->sadb_lifetime_len
=
4343 PFKEY_UNIT64(sizeof(struct sadb_lifetime
));
4344 sav
->lft_c
->sadb_lifetime_exttype
= SADB_EXT_LIFETIME_CURRENT
;
4345 sav
->lft_c
->sadb_lifetime_allocations
= 0;
4346 sav
->lft_c
->sadb_lifetime_bytes
= 0;
4347 sav
->lft_c
->sadb_lifetime_addtime
= tv
.tv_sec
;
4348 sav
->lft_c
->sadb_lifetime_usetime
= 0;
4350 /* lifetimes for HARD and SOFT */
4352 const struct sadb_lifetime
*lft0
;
4354 lft0
= (struct sadb_lifetime
*)
4355 (void *)mhp
->ext
[SADB_EXT_LIFETIME_HARD
];
4357 if (mhp
->extlen
[SADB_EXT_LIFETIME_HARD
] < sizeof(*lft0
)) {
4358 ipseclog((LOG_DEBUG
, "key_setsaval: invalid hard lifetime ext len.\n"));
4362 sav
->lft_h
= (struct sadb_lifetime
*)key_newbuf(lft0
,
4364 if (sav
->lft_h
== NULL
) {
4365 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4369 /* to be initialize ? */
4372 lft0
= (struct sadb_lifetime
*)
4373 (void *)mhp
->ext
[SADB_EXT_LIFETIME_SOFT
];
4375 if (mhp
->extlen
[SADB_EXT_LIFETIME_SOFT
] < sizeof(*lft0
)) {
4376 ipseclog((LOG_DEBUG
, "key_setsaval: invalid soft lifetime ext len.\n"));
4380 sav
->lft_s
= (struct sadb_lifetime
*)key_newbuf(lft0
,
4382 if (sav
->lft_s
== NULL
) {
4383 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4387 /* to be initialize ? */
4394 /* initialization */
4395 if (sav
->replay
!= NULL
) {
4396 keydb_delsecreplay(sav
->replay
);
4399 if (sav
->key_auth
!= NULL
) {
4400 bzero(_KEYBUF(sav
->key_auth
), _KEYLEN(sav
->key_auth
));
4401 KFREE(sav
->key_auth
);
4402 sav
->key_auth
= NULL
;
4404 if (sav
->key_enc
!= NULL
) {
4405 bzero(_KEYBUF(sav
->key_enc
), _KEYLEN(sav
->key_enc
));
4406 KFREE(sav
->key_enc
);
4407 sav
->key_enc
= NULL
;
4410 bzero(sav
->sched
, sav
->schedlen
);
4414 if (sav
->iv
!= NULL
) {
4418 if (sav
->lft_c
!= NULL
) {
4422 if (sav
->lft_h
!= NULL
) {
4426 if (sav
->lft_s
!= NULL
) {
4435 * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*.
4436 * You must update these if need.
4440 * does not modify mbuf. does not free mbuf on error.
4443 key_setsaval2(struct secasvar
*sav
,
4449 struct sadb_key
*key_auth
,
4450 u_int16_t key_auth_len
,
4451 struct sadb_key
*key_enc
,
4452 u_int16_t key_enc_len
,
4453 u_int16_t natt_port
,
4457 struct sadb_lifetime
*lifetime_hard
,
4458 struct sadb_lifetime
*lifetime_soft
)
4461 const struct esp_algorithm
*algo
;
4466 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4468 /* initialization */
4470 sav
->key_auth
= NULL
;
4471 sav
->key_enc
= NULL
;
4478 sav
->remote_ike_port
= 0;
4479 sav
->natt_last_activity
= natt_now
;
4480 sav
->natt_encapsulated_src_port
= 0;
4482 sav
->alg_auth
= alg_auth
;
4483 sav
->alg_enc
= alg_enc
;
4487 key_setspi(sav
, htonl(spi
));
4490 * Verify that a nat-traversal port was specified if
4491 * the nat-traversal flag is set.
4493 if ((sav
->flags
& SADB_X_EXT_NATT
) != 0) {
4494 if (natt_port
== 0) {
4495 ipseclog((LOG_DEBUG
, "key_setsaval2: natt port not set.\n"));
4499 sav
->remote_ike_port
= natt_port
;
4503 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
4504 * SADB_X_EXT_NATT is set and SADB_X_EXT_NATT_KEEPALIVE is not
4505 * set (we're not behind nat) - otherwise clear it.
4507 if ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0)
4508 if ((sav
->flags
& SADB_X_EXT_NATT
) == 0 ||
4509 (sav
->flags
& SADB_X_EXT_NATT_KEEPALIVE
) != 0)
4510 sav
->flags
&= ~SADB_X_EXT_NATT_MULTIPLEUSERS
;
4513 if ((flags
& SADB_X_EXT_OLD
) == 0) {
4514 sav
->replay
= keydb_newsecreplay(replay
);
4515 if (sav
->replay
== NULL
) {
4516 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4522 /* Authentication keys */
4523 sav
->key_auth
= (__typeof__(sav
->key_auth
))key_newbuf(key_auth
, key_auth_len
);
4524 if (sav
->key_auth
== NULL
) {
4525 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4530 /* Encryption key */
4531 sav
->key_enc
= (__typeof__(sav
->key_enc
))key_newbuf(key_enc
, key_enc_len
);
4532 if (sav
->key_enc
== NULL
) {
4533 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4541 if (satype
== SADB_SATYPE_ESP
) {
4543 algo
= esp_algorithm_lookup(sav
->alg_enc
);
4544 if (algo
&& algo
->ivlen
)
4545 sav
->ivlen
= (*algo
->ivlen
)(algo
, sav
);
4546 if (sav
->ivlen
!= 0) {
4547 KMALLOC_NOWAIT(sav
->iv
, caddr_t
, sav
->ivlen
);
4549 lck_mtx_unlock(sadb_mutex
);
4550 KMALLOC_WAIT(sav
->iv
, caddr_t
, sav
->ivlen
);
4551 lck_mtx_lock(sadb_mutex
);
4553 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4559 if (sav
->alg_enc
== SADB_X_EALG_AES_GCM
) {
4560 bzero(sav
->iv
, sav
->ivlen
);
4562 key_randomfill(sav
->iv
, sav
->ivlen
);
4570 sav
->created
= tv
.tv_sec
;
4572 /* make lifetime for CURRENT */
4573 KMALLOC_NOWAIT(sav
->lft_c
, struct sadb_lifetime
*,
4574 sizeof(struct sadb_lifetime
));
4575 if (sav
->lft_c
== NULL
) {
4576 lck_mtx_unlock(sadb_mutex
);
4577 KMALLOC_WAIT(sav
->lft_c
, struct sadb_lifetime
*,
4578 sizeof(struct sadb_lifetime
));
4579 lck_mtx_lock(sadb_mutex
);
4580 if (sav
->lft_c
== NULL
) {
4581 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4589 sav
->lft_c
->sadb_lifetime_len
=
4590 PFKEY_UNIT64(sizeof(struct sadb_lifetime
));
4591 sav
->lft_c
->sadb_lifetime_exttype
= SADB_EXT_LIFETIME_CURRENT
;
4592 sav
->lft_c
->sadb_lifetime_allocations
= 0;
4593 sav
->lft_c
->sadb_lifetime_bytes
= 0;
4594 sav
->lft_c
->sadb_lifetime_addtime
= tv
.tv_sec
;
4595 sav
->lft_c
->sadb_lifetime_usetime
= 0;
4597 /* lifetimes for HARD and SOFT */
4598 sav
->lft_h
= (__typeof__(sav
->lft_h
))key_newbuf(lifetime_hard
,
4599 sizeof(*lifetime_hard
));
4600 if (sav
->lft_h
== NULL
) {
4601 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4605 sav
->lft_s
= (__typeof__(sav
->lft_s
))key_newbuf(lifetime_soft
,
4606 sizeof(*lifetime_soft
));
4607 if (sav
->lft_s
== NULL
) {
4608 ipseclog((LOG_DEBUG
, "key_setsaval: No more memory.\n"));
4616 /* initialization */
4617 if (sav
->replay
!= NULL
) {
4618 keydb_delsecreplay(sav
->replay
);
4621 if (sav
->key_auth
!= NULL
) {
4622 bzero(_KEYBUF(sav
->key_auth
), _KEYLEN(sav
->key_auth
));
4623 KFREE(sav
->key_auth
);
4624 sav
->key_auth
= NULL
;
4626 if (sav
->key_enc
!= NULL
) {
4627 bzero(_KEYBUF(sav
->key_enc
), _KEYLEN(sav
->key_enc
));
4628 KFREE(sav
->key_enc
);
4629 sav
->key_enc
= NULL
;
4632 bzero(sav
->sched
, sav
->schedlen
);
4636 if (sav
->iv
!= NULL
) {
4640 if (sav
->lft_c
!= NULL
) {
4644 if (sav
->lft_h
!= NULL
) {
4648 if (sav
->lft_s
!= NULL
) {
4657 * validation with a secasvar entry, and set SADB_SATYPE_MATURE.
4663 struct secasvar
*sav
)
4666 int checkmask
= 0; /* 2^0: ealg 2^1: aalg 2^2: calg */
4667 int mustmask
= 0; /* 2^0: ealg 2^1: aalg 2^2: calg */
4671 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
4673 /* check SPI value */
4674 switch (sav
->sah
->saidx
.proto
) {
4678 /* No reason to test if this is >= 0, because ntohl(sav->spi) is unsigned. */
4679 if (ntohl(sav
->spi
) <= 255) {
4680 ipseclog((LOG_DEBUG
,
4681 "key_mature: illegal range of SPI %u.\n",
4682 (u_int32_t
)ntohl(sav
->spi
)));
4689 switch (sav
->sah
->saidx
.proto
) {
4692 if ((sav
->flags
& SADB_X_EXT_OLD
)
4693 && (sav
->flags
& SADB_X_EXT_DERIV
)) {
4694 ipseclog((LOG_DEBUG
, "key_mature: "
4695 "invalid flag (derived) given to old-esp.\n"));
4698 if (sav
->alg_auth
== SADB_AALG_NONE
)
4706 if (sav
->flags
& SADB_X_EXT_DERIV
) {
4707 ipseclog((LOG_DEBUG
, "key_mature: "
4708 "invalid flag (derived) given to AH SA.\n"));
4711 if (sav
->alg_enc
!= SADB_EALG_NONE
) {
4712 ipseclog((LOG_DEBUG
, "key_mature: "
4713 "protocol and algorithm mismated.\n"));
4719 case IPPROTO_IPCOMP
:
4720 if (sav
->alg_auth
!= SADB_AALG_NONE
) {
4721 ipseclog((LOG_DEBUG
, "key_mature: "
4722 "protocol and algorithm mismated.\n"));
4725 if ((sav
->flags
& SADB_X_EXT_RAWCPI
) == 0
4726 && ntohl(sav
->spi
) >= 0x10000) {
4727 ipseclog((LOG_DEBUG
, "key_mature: invalid cpi for IPComp.\n"));
4734 ipseclog((LOG_DEBUG
, "key_mature: Invalid satype.\n"));
4735 return EPROTONOSUPPORT
;
4738 /* check authentication algorithm */
4739 if ((checkmask
& 2) != 0) {
4740 const struct ah_algorithm
*algo
;
4743 algo
= ah_algorithm_lookup(sav
->alg_auth
);
4745 ipseclog((LOG_DEBUG
,"key_mature: "
4746 "unknown authentication algorithm.\n"));
4750 /* algorithm-dependent check */
4752 keylen
= sav
->key_auth
->sadb_key_bits
;
4755 if (keylen
< algo
->keymin
|| algo
->keymax
< keylen
) {
4756 ipseclog((LOG_DEBUG
,
4757 "key_mature: invalid AH key length %d "
4758 "(%d-%d allowed)\n",
4759 keylen
, algo
->keymin
, algo
->keymax
));
4764 if ((*algo
->mature
)(sav
)) {
4765 /* message generated in per-algorithm function*/
4768 mature
= SADB_SATYPE_AH
;
4771 if ((mustmask
& 2) != 0 && mature
!= SADB_SATYPE_AH
) {
4772 ipseclog((LOG_DEBUG
, "key_mature: no satisfy algorithm for AH\n"));
4777 /* check encryption algorithm */
4778 if ((checkmask
& 1) != 0) {
4780 const struct esp_algorithm
*algo
;
4783 algo
= esp_algorithm_lookup(sav
->alg_enc
);
4785 ipseclog((LOG_DEBUG
, "key_mature: unknown encryption algorithm.\n"));
4789 /* algorithm-dependent check */
4791 keylen
= sav
->key_enc
->sadb_key_bits
;
4794 if (keylen
< algo
->keymin
|| algo
->keymax
< keylen
) {
4795 ipseclog((LOG_DEBUG
,
4796 "key_mature: invalid ESP key length %d "
4797 "(%d-%d allowed)\n",
4798 keylen
, algo
->keymin
, algo
->keymax
));
4803 if ((*algo
->mature
)(sav
)) {
4804 /* message generated in per-algorithm function*/
4807 mature
= SADB_SATYPE_ESP
;
4810 if ((mustmask
& 1) != 0 && mature
!= SADB_SATYPE_ESP
) {
4811 ipseclog((LOG_DEBUG
, "key_mature: no satisfy algorithm for ESP\n"));
4815 ipseclog((LOG_DEBUG
, "key_mature: ESP not supported in this configuration\n"));
4820 /* check compression algorithm */
4821 if ((checkmask
& 4) != 0) {
4822 const struct ipcomp_algorithm
*algo
;
4824 /* algorithm-dependent check */
4825 algo
= ipcomp_algorithm_lookup(sav
->alg_enc
);
4827 ipseclog((LOG_DEBUG
, "key_mature: unknown compression algorithm.\n"));
4832 key_sa_chgstate(sav
, SADB_SASTATE_MATURE
);
4838 * subroutine for SADB_GET and SADB_DUMP.
4840 static struct mbuf
*
4842 struct secasvar
*sav
,
4848 struct mbuf
*result
= NULL
, *tres
= NULL
, *m
;
4853 SADB_EXT_SA
, SADB_X_EXT_SA2
,
4854 SADB_EXT_LIFETIME_HARD
, SADB_EXT_LIFETIME_SOFT
,
4855 SADB_EXT_LIFETIME_CURRENT
, SADB_EXT_ADDRESS_SRC
,
4856 SADB_EXT_ADDRESS_DST
, SADB_EXT_ADDRESS_PROXY
, SADB_EXT_KEY_AUTH
,
4857 SADB_EXT_KEY_ENCRYPT
, SADB_EXT_IDENTITY_SRC
,
4858 SADB_EXT_IDENTITY_DST
, SADB_EXT_SENSITIVITY
,
4861 m
= key_setsadbmsg(type
, 0, satype
, seq
, pid
, sav
->refcnt
);
4866 for (i
= sizeof(dumporder
)/sizeof(dumporder
[0]) - 1; i
>= 0; i
--) {
4869 switch (dumporder
[i
]) {
4871 m
= key_setsadbsa(sav
);
4876 case SADB_X_EXT_SA2
:
4877 m
= key_setsadbxsa2(sav
->sah
->saidx
.mode
,
4878 sav
->replay
? sav
->replay
->count
: 0,
4879 sav
->sah
->saidx
.reqid
,
4885 case SADB_EXT_ADDRESS_SRC
:
4886 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
4887 (struct sockaddr
*)&sav
->sah
->saidx
.src
,
4888 FULLMASK
, IPSEC_ULPROTO_ANY
);
4893 case SADB_EXT_ADDRESS_DST
:
4894 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
4895 (struct sockaddr
*)&sav
->sah
->saidx
.dst
,
4896 FULLMASK
, IPSEC_ULPROTO_ANY
);
4901 case SADB_EXT_KEY_AUTH
:
4904 l
= PFKEY_UNUNIT64(sav
->key_auth
->sadb_key_len
);
4908 case SADB_EXT_KEY_ENCRYPT
:
4911 l
= PFKEY_UNUNIT64(sav
->key_enc
->sadb_key_len
);
4915 case SADB_EXT_LIFETIME_CURRENT
:
4918 l
= PFKEY_UNUNIT64(((struct sadb_ext
*)sav
->lft_c
)->sadb_ext_len
);
4922 case SADB_EXT_LIFETIME_HARD
:
4925 l
= PFKEY_UNUNIT64(((struct sadb_ext
*)sav
->lft_h
)->sadb_ext_len
);
4929 case SADB_EXT_LIFETIME_SOFT
:
4932 l
= PFKEY_UNUNIT64(((struct sadb_ext
*)sav
->lft_s
)->sadb_ext_len
);
4936 case SADB_EXT_ADDRESS_PROXY
:
4937 case SADB_EXT_IDENTITY_SRC
:
4938 case SADB_EXT_IDENTITY_DST
:
4939 /* XXX: should we brought from SPD ? */
4940 case SADB_EXT_SENSITIVITY
:
4945 if ((!m
&& !p
) || (m
&& p
))
4948 M_PREPEND(tres
, l
, M_WAITOK
, 1);
4951 bcopy(p
, mtod(tres
, caddr_t
), l
);
4955 m
= key_alloc_mbuf(l
);
4958 m_copyback(m
, 0, l
, p
);
4966 m_cat(result
, tres
);
4968 if (sav
->sah
&& (sav
->sah
->outgoing_if
|| sav
->sah
->ipsec_if
)) {
4969 m
= key_setsadbipsecif(NULL
, ifindex2ifnet
[sav
->sah
->outgoing_if
], sav
->sah
->ipsec_if
, 0);
4975 if (result
->m_len
< sizeof(struct sadb_msg
)) {
4976 result
= m_pullup(result
, sizeof(struct sadb_msg
));
4981 result
->m_pkthdr
.len
= 0;
4982 for (m
= result
; m
; m
= m
->m_next
)
4983 result
->m_pkthdr
.len
+= m
->m_len
;
4985 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
4986 PFKEY_UNIT64(result
->m_pkthdr
.len
);
4997 * set data into sadb_msg.
4999 static struct mbuf
*
5012 len
= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
5015 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
5016 if (m
&& len
> MHLEN
) {
5017 MCLGET(m
, M_DONTWAIT
);
5018 if ((m
->m_flags
& M_EXT
) == 0) {
5025 m
->m_pkthdr
.len
= m
->m_len
= len
;
5028 p
= mtod(m
, struct sadb_msg
*);
5031 p
->sadb_msg_version
= PF_KEY_V2
;
5032 p
->sadb_msg_type
= type
;
5033 p
->sadb_msg_errno
= 0;
5034 p
->sadb_msg_satype
= satype
;
5035 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
5036 p
->sadb_msg_reserved
= reserved
;
5037 p
->sadb_msg_seq
= seq
;
5038 p
->sadb_msg_pid
= (u_int32_t
)pid
;
5044 * copy secasvar data into sadb_address.
5046 static struct mbuf
*
5048 struct secasvar
*sav
)
5054 len
= PFKEY_ALIGN8(sizeof(struct sadb_sa
));
5055 m
= key_alloc_mbuf(len
);
5056 if (!m
|| m
->m_next
) { /*XXX*/
5062 p
= mtod(m
, struct sadb_sa
*);
5065 p
->sadb_sa_len
= PFKEY_UNIT64(len
);
5066 p
->sadb_sa_exttype
= SADB_EXT_SA
;
5067 p
->sadb_sa_spi
= sav
->spi
;
5068 p
->sadb_sa_replay
= (sav
->replay
!= NULL
? sav
->replay
->wsize
: 0);
5069 p
->sadb_sa_state
= sav
->state
;
5070 p
->sadb_sa_auth
= sav
->alg_auth
;
5071 p
->sadb_sa_encrypt
= sav
->alg_enc
;
5072 p
->sadb_sa_flags
= sav
->flags
;
5078 * set data into sadb_address.
5080 static struct mbuf
*
5083 struct sockaddr
*saddr
,
5088 struct sadb_address
*p
;
5091 len
= PFKEY_ALIGN8(sizeof(struct sadb_address
)) +
5092 PFKEY_ALIGN8(saddr
->sa_len
);
5093 m
= key_alloc_mbuf(len
);
5094 if (!m
|| m
->m_next
) { /*XXX*/
5100 p
= mtod(m
, struct sadb_address
*);
5103 p
->sadb_address_len
= PFKEY_UNIT64(len
);
5104 p
->sadb_address_exttype
= exttype
;
5105 p
->sadb_address_proto
= ul_proto
;
5106 if (prefixlen
== FULLMASK
) {
5107 switch (saddr
->sa_family
) {
5109 prefixlen
= sizeof(struct in_addr
) << 3;
5112 prefixlen
= sizeof(struct in6_addr
) << 3;
5118 p
->sadb_address_prefixlen
= prefixlen
;
5119 p
->sadb_address_reserved
= 0;
5122 mtod(m
, caddr_t
) + PFKEY_ALIGN8(sizeof(struct sadb_address
)),
5128 static struct mbuf
*
5129 key_setsadbipsecif(ifnet_t internal_if
,
5130 ifnet_t outgoing_if
,
5135 struct sadb_x_ipsecif
*p
;
5138 len
= PFKEY_ALIGN8(sizeof(struct sadb_x_ipsecif
));
5139 m
= key_alloc_mbuf(len
);
5140 if (!m
|| m
->m_next
) { /*XXX*/
5146 p
= mtod(m
, struct sadb_x_ipsecif
*);
5149 p
->sadb_x_ipsecif_len
= PFKEY_UNIT64(len
);
5150 p
->sadb_x_ipsecif_exttype
= SADB_X_EXT_IPSECIF
;
5152 if (internal_if
&& internal_if
->if_xname
)
5153 strlcpy(p
->sadb_x_ipsecif_internal_if
, internal_if
->if_xname
, IFXNAMSIZ
);
5154 if (outgoing_if
&& outgoing_if
->if_xname
)
5155 strlcpy(p
->sadb_x_ipsecif_outgoing_if
, outgoing_if
->if_xname
, IFXNAMSIZ
);
5156 if (ipsec_if
&& ipsec_if
->if_xname
)
5157 strlcpy(p
->sadb_x_ipsecif_ipsec_if
, ipsec_if
->if_xname
, IFXNAMSIZ
);
5159 p
->sadb_x_ipsecif_init_disabled
= init_disabled
;
5165 * set data into sadb_session_id
5167 static struct mbuf
*
5168 key_setsadbsession_id (u_int64_t session_ids
[])
5171 struct sadb_session_id
*p
;
5174 len
= PFKEY_ALIGN8(sizeof(*p
));
5175 m
= key_alloc_mbuf(len
);
5176 if (!m
|| m
->m_next
) { /*XXX*/
5182 p
= mtod(m
, __typeof__(p
));
5185 p
->sadb_session_id_len
= PFKEY_UNIT64(len
);
5186 p
->sadb_session_id_exttype
= SADB_EXT_SESSION_ID
;
5187 p
->sadb_session_id_v
[0] = session_ids
[0];
5188 p
->sadb_session_id_v
[1] = session_ids
[1];
5194 * copy stats data into sadb_sastat type.
5196 static struct mbuf
*
5197 key_setsadbsastat (u_int32_t dir
,
5198 struct sastat
*stats
,
5199 u_int32_t max_stats
)
5202 struct sadb_sastat
*p
;
5209 list_len
= sizeof(*stats
) * max_stats
;
5210 len
= PFKEY_ALIGN8(sizeof(*p
)) + PFKEY_ALIGN8(list_len
);
5211 m
= key_alloc_mbuf(len
);
5212 if (!m
|| m
->m_next
) { /*XXX*/
5218 p
= mtod(m
, __typeof__(p
));
5221 p
->sadb_sastat_len
= PFKEY_UNIT64(len
);
5222 p
->sadb_sastat_exttype
= SADB_EXT_SASTAT
;
5223 p
->sadb_sastat_dir
= dir
;
5224 p
->sadb_sastat_list_len
= max_stats
;
5227 mtod(m
, caddr_t
) + PFKEY_ALIGN8(sizeof(*p
)),
5236 * set data into sadb_ident.
5238 static struct mbuf
*
5247 struct sadb_ident
*p
;
5250 len
= PFKEY_ALIGN8(sizeof(struct sadb_ident
)) + PFKEY_ALIGN8(stringlen
);
5251 m
= key_alloc_mbuf(len
);
5252 if (!m
|| m
->m_next
) { /*XXX*/
5258 p
= mtod(m
, struct sadb_ident
*);
5261 p
->sadb_ident_len
= PFKEY_UNIT64(len
);
5262 p
->sadb_ident_exttype
= exttype
;
5263 p
->sadb_ident_type
= idtype
;
5264 p
->sadb_ident_reserved
= 0;
5265 p
->sadb_ident_id
= id
;
5268 mtod(m
, caddr_t
) + PFKEY_ALIGN8(sizeof(struct sadb_ident
)),
5276 * set data into sadb_x_sa2.
5278 static struct mbuf
*
5286 struct sadb_x_sa2
*p
;
5289 len
= PFKEY_ALIGN8(sizeof(struct sadb_x_sa2
));
5290 m
= key_alloc_mbuf(len
);
5291 if (!m
|| m
->m_next
) { /*XXX*/
5297 p
= mtod(m
, struct sadb_x_sa2
*);
5300 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
5301 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
5302 p
->sadb_x_sa2_mode
= mode
;
5303 p
->sadb_x_sa2_reserved1
= 0;
5304 p
->sadb_x_sa2_reserved2
= 0;
5305 p
->sadb_x_sa2_sequence
= seq
;
5306 p
->sadb_x_sa2_reqid
= reqid
;
5307 p
->sadb_x_sa2_flags
= flags
;
5313 * set data into sadb_x_policy
5315 static struct mbuf
*
5322 struct sadb_x_policy
*p
;
5325 len
= PFKEY_ALIGN8(sizeof(struct sadb_x_policy
));
5326 m
= key_alloc_mbuf(len
);
5327 if (!m
|| m
->m_next
) { /*XXX*/
5333 p
= mtod(m
, struct sadb_x_policy
*);
5336 p
->sadb_x_policy_len
= PFKEY_UNIT64(len
);
5337 p
->sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
5338 p
->sadb_x_policy_type
= type
;
5339 p
->sadb_x_policy_dir
= dir
;
5340 p
->sadb_x_policy_id
= id
;
5347 * copy a buffer into the new buffer allocated.
5356 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
5357 KMALLOC_NOWAIT(new, caddr_t
, len
);
5359 lck_mtx_unlock(sadb_mutex
);
5360 KMALLOC_WAIT(new, caddr_t
, len
);
5361 lck_mtx_lock(sadb_mutex
);
5363 ipseclog((LOG_DEBUG
, "key_newbuf: No more memory.\n"));
5367 bcopy(src
, new, len
);
5372 /* compare my own address
5373 * OUT: 1: true, i.e. my address.
5378 struct sockaddr
*sa
)
5381 struct sockaddr_in
*sin
;
5382 struct in_ifaddr
*ia
;
5387 panic("key_ismyaddr: NULL pointer is passed.\n");
5389 switch (sa
->sa_family
) {
5392 lck_rw_lock_shared(in_ifaddr_rwlock
);
5393 sin
= (struct sockaddr_in
*)(void *)sa
;
5394 for (ia
= in_ifaddrhead
.tqh_first
; ia
;
5395 ia
= ia
->ia_link
.tqe_next
) {
5396 IFA_LOCK_SPIN(&ia
->ia_ifa
);
5397 if (sin
->sin_family
== ia
->ia_addr
.sin_family
&&
5398 sin
->sin_len
== ia
->ia_addr
.sin_len
&&
5399 sin
->sin_addr
.s_addr
== ia
->ia_addr
.sin_addr
.s_addr
)
5401 IFA_UNLOCK(&ia
->ia_ifa
);
5402 lck_rw_done(in_ifaddr_rwlock
);
5405 IFA_UNLOCK(&ia
->ia_ifa
);
5407 lck_rw_done(in_ifaddr_rwlock
);
5412 return key_ismyaddr6((struct sockaddr_in6
*)(void *)sa
);
5421 * compare my own address for IPv6.
5424 * NOTE: derived ip6_input() in KAME. This is necessary to modify more.
5426 #include <netinet6/in6_var.h>
5430 struct sockaddr_in6
*sin6
)
5432 struct in6_ifaddr
*ia
;
5433 struct in6_multi
*in6m
;
5435 lck_rw_lock_shared(&in6_ifaddr_rwlock
);
5436 for (ia
= in6_ifaddrs
; ia
; ia
= ia
->ia_next
) {
5437 IFA_LOCK(&ia
->ia_ifa
);
5438 if (key_sockaddrcmp((struct sockaddr
*)&sin6
,
5439 (struct sockaddr
*)&ia
->ia_addr
, 0) == 0) {
5440 IFA_UNLOCK(&ia
->ia_ifa
);
5441 lck_rw_done(&in6_ifaddr_rwlock
);
5444 IFA_UNLOCK(&ia
->ia_ifa
);
5448 * XXX why do we care about multlicast here while we don't care
5449 * about IPv4 multicast??
5453 in6_multihead_lock_shared();
5454 IN6_LOOKUP_MULTI(&sin6
->sin6_addr
, ia
->ia_ifp
, in6m
);
5455 in6_multihead_lock_done();
5457 lck_rw_done(&in6_ifaddr_rwlock
);
5462 lck_rw_done(&in6_ifaddr_rwlock
);
5464 /* loopback, just for safety */
5465 if (IN6_IS_ADDR_LOOPBACK(&sin6
->sin6_addr
))
5473 * compare two secasindex structure.
5474 * flag can specify to compare 2 saidxes.
5475 * compare two secasindex structure without both mode and reqid.
5476 * don't compare port.
5478 * saidx0: source, it can be in SAD.
5486 struct secasindex
*saidx0
,
5487 struct secasindex
*saidx1
,
5491 if (saidx0
== NULL
&& saidx1
== NULL
)
5494 if (saidx0
== NULL
|| saidx1
== NULL
)
5497 if (saidx0
->ipsec_ifindex
!= 0 && saidx0
->ipsec_ifindex
!= saidx1
->ipsec_ifindex
)
5500 if (saidx0
->proto
!= saidx1
->proto
)
5503 if (flag
== CMP_EXACTLY
) {
5504 if (saidx0
->mode
!= saidx1
->mode
)
5506 if (saidx0
->reqid
!= saidx1
->reqid
)
5508 if (bcmp(&saidx0
->src
, &saidx1
->src
, saidx0
->src
.ss_len
) != 0 ||
5509 bcmp(&saidx0
->dst
, &saidx1
->dst
, saidx0
->dst
.ss_len
) != 0)
5513 /* CMP_MODE_REQID, CMP_REQID, CMP_HEAD */
5514 if (flag
& CMP_REQID
) {
5516 * If reqid of SPD is non-zero, unique SA is required.
5517 * The result must be of same reqid in this case.
5519 if (saidx1
->reqid
!= 0 && saidx0
->reqid
!= saidx1
->reqid
)
5523 if (flag
& CMP_MODE
) {
5524 if (saidx0
->mode
!= IPSEC_MODE_ANY
5525 && saidx0
->mode
!= saidx1
->mode
)
5529 if (key_sockaddrcmp((struct sockaddr
*)&saidx0
->src
,
5530 (struct sockaddr
*)&saidx1
->src
, flag
& CMP_PORT
? 1 : 0) != 0) {
5533 if (key_sockaddrcmp((struct sockaddr
*)&saidx0
->dst
,
5534 (struct sockaddr
*)&saidx1
->dst
, flag
& CMP_PORT
? 1 : 0) != 0) {
5543 * compare two secindex structure exactly.
5545 * spidx0: source, it is often in SPD.
5546 * spidx1: object, it is often from PFKEY message.
5552 key_cmpspidx_exactly(
5553 struct secpolicyindex
*spidx0
,
5554 struct secpolicyindex
*spidx1
)
5557 if (spidx0
== NULL
&& spidx1
== NULL
)
5560 if (spidx0
== NULL
|| spidx1
== NULL
)
5563 if (spidx0
->prefs
!= spidx1
->prefs
5564 || spidx0
->prefd
!= spidx1
->prefd
5565 || spidx0
->ul_proto
!= spidx1
->ul_proto
5566 || spidx0
->internal_if
!= spidx1
->internal_if
)
5569 if (key_sockaddrcmp((struct sockaddr
*)&spidx0
->src
,
5570 (struct sockaddr
*)&spidx1
->src
, 1) != 0) {
5573 if (key_sockaddrcmp((struct sockaddr
*)&spidx0
->dst
,
5574 (struct sockaddr
*)&spidx1
->dst
, 1) != 0) {
5578 if (key_sockaddrcmp((struct sockaddr
*)&spidx0
->src_range
.start
,
5579 (struct sockaddr
*)&spidx1
->src_range
.start
, 1) != 0) {
5582 if (key_sockaddrcmp((struct sockaddr
*)&spidx0
->src_range
.end
,
5583 (struct sockaddr
*)&spidx1
->src_range
.end
, 1) != 0) {
5586 if (key_sockaddrcmp((struct sockaddr
*)&spidx0
->dst_range
.start
,
5587 (struct sockaddr
*)&spidx1
->dst_range
.start
, 1) != 0) {
5590 if (key_sockaddrcmp((struct sockaddr
*)&spidx0
->dst_range
.end
,
5591 (struct sockaddr
*)&spidx1
->dst_range
.end
, 1) != 0) {
5599 * compare two secindex structure with mask.
5601 * spidx0: source, it is often in SPD.
5602 * spidx1: object, it is often from IP header.
5608 key_cmpspidx_withmask(
5609 struct secpolicyindex
*spidx0
,
5610 struct secpolicyindex
*spidx1
)
5612 int spidx0_src_is_range
= 0;
5613 int spidx0_dst_is_range
= 0;
5616 if (spidx0
== NULL
&& spidx1
== NULL
)
5619 if (spidx0
== NULL
|| spidx1
== NULL
)
5622 if (spidx0
->src_range
.start
.ss_len
> 0)
5623 spidx0_src_is_range
= 1;
5625 if (spidx0
->dst_range
.start
.ss_len
> 0)
5626 spidx0_dst_is_range
= 1;
5628 if ((spidx0_src_is_range
? spidx0
->src_range
.start
.ss_family
: spidx0
->src
.ss_family
) != spidx1
->src
.ss_family
||
5629 (spidx0_dst_is_range
? spidx0
->dst_range
.start
.ss_family
: spidx0
->dst
.ss_family
) != spidx1
->dst
.ss_family
||
5630 (spidx0_src_is_range
? spidx0
->src_range
.start
.ss_len
: spidx0
->src
.ss_len
) != spidx1
->src
.ss_len
||
5631 (spidx0_dst_is_range
? spidx0
->dst_range
.start
.ss_len
: spidx0
->dst
.ss_len
) != spidx1
->dst
.ss_len
)
5634 /* if spidx.ul_proto == IPSEC_ULPROTO_ANY, ignore. */
5635 if (spidx0
->ul_proto
!= (u_int16_t
)IPSEC_ULPROTO_ANY
5636 && spidx0
->ul_proto
!= spidx1
->ul_proto
)
5639 /* If spidx1 specifies interface, ignore src addr */
5640 if (spidx1
->internal_if
!= NULL
) {
5641 if (spidx0
->internal_if
== NULL
5642 || spidx0
->internal_if
!= spidx1
->internal_if
)
5645 /* Still check ports */
5646 switch (spidx0
->src
.ss_family
) {
5648 if (spidx0_src_is_range
&&
5649 (satosin(&spidx1
->src
)->sin_port
< satosin(&spidx0
->src_range
.start
)->sin_port
5650 || satosin(&spidx1
->src
)->sin_port
> satosin(&spidx0
->src_range
.end
)->sin_port
))
5652 else if (satosin(&spidx0
->src
)->sin_port
!= IPSEC_PORT_ANY
5653 && satosin(&spidx0
->src
)->sin_port
!=
5654 satosin(&spidx1
->src
)->sin_port
)
5658 if (spidx0_src_is_range
&&
5659 (satosin6(&spidx1
->src
)->sin6_port
< satosin6(&spidx0
->src_range
.start
)->sin6_port
5660 || satosin6(&spidx1
->src
)->sin6_port
> satosin6(&spidx0
->src_range
.end
)->sin6_port
))
5662 else if (satosin6(&spidx0
->src
)->sin6_port
!= IPSEC_PORT_ANY
5663 && satosin6(&spidx0
->src
)->sin6_port
!=
5664 satosin6(&spidx1
->src
)->sin6_port
)
5670 } else if (spidx0_src_is_range
) {
5671 if (!key_is_addr_in_range(&spidx1
->src
, &spidx0
->src_range
))
5674 switch (spidx0
->src
.ss_family
) {
5676 if (satosin(&spidx0
->src
)->sin_port
!= IPSEC_PORT_ANY
5677 && satosin(&spidx0
->src
)->sin_port
!=
5678 satosin(&spidx1
->src
)->sin_port
)
5680 if (!key_bbcmp((caddr_t
)&satosin(&spidx0
->src
)->sin_addr
,
5681 (caddr_t
)&satosin(&spidx1
->src
)->sin_addr
, spidx0
->prefs
))
5685 if (satosin6(&spidx0
->src
)->sin6_port
!= IPSEC_PORT_ANY
5686 && satosin6(&spidx0
->src
)->sin6_port
!=
5687 satosin6(&spidx1
->src
)->sin6_port
)
5690 * scope_id check. if sin6_scope_id is 0, we regard it
5691 * as a wildcard scope, which matches any scope zone ID.
5693 if (satosin6(&spidx0
->src
)->sin6_scope_id
&&
5694 satosin6(&spidx1
->src
)->sin6_scope_id
&&
5695 satosin6(&spidx0
->src
)->sin6_scope_id
!=
5696 satosin6(&spidx1
->src
)->sin6_scope_id
)
5698 if (!key_bbcmp((caddr_t
)&satosin6(&spidx0
->src
)->sin6_addr
,
5699 (caddr_t
)&satosin6(&spidx1
->src
)->sin6_addr
, spidx0
->prefs
))
5704 if (bcmp(&spidx0
->src
, &spidx1
->src
, spidx0
->src
.ss_len
) != 0)
5710 if (spidx0_dst_is_range
) {
5711 if (!key_is_addr_in_range(&spidx1
->dst
, &spidx0
->dst_range
))
5714 switch (spidx0
->dst
.ss_family
) {
5716 if (satosin(&spidx0
->dst
)->sin_port
!= IPSEC_PORT_ANY
5717 && satosin(&spidx0
->dst
)->sin_port
!=
5718 satosin(&spidx1
->dst
)->sin_port
)
5720 if (!key_bbcmp((caddr_t
)&satosin(&spidx0
->dst
)->sin_addr
,
5721 (caddr_t
)&satosin(&spidx1
->dst
)->sin_addr
, spidx0
->prefd
))
5725 if (satosin6(&spidx0
->dst
)->sin6_port
!= IPSEC_PORT_ANY
5726 && satosin6(&spidx0
->dst
)->sin6_port
!=
5727 satosin6(&spidx1
->dst
)->sin6_port
)
5730 * scope_id check. if sin6_scope_id is 0, we regard it
5731 * as a wildcard scope, which matches any scope zone ID.
5733 if (satosin6(&spidx0
->src
)->sin6_scope_id
&&
5734 satosin6(&spidx1
->src
)->sin6_scope_id
&&
5735 satosin6(&spidx0
->dst
)->sin6_scope_id
!=
5736 satosin6(&spidx1
->dst
)->sin6_scope_id
)
5738 if (!key_bbcmp((caddr_t
)&satosin6(&spidx0
->dst
)->sin6_addr
,
5739 (caddr_t
)&satosin6(&spidx1
->dst
)->sin6_addr
, spidx0
->prefd
))
5744 if (bcmp(&spidx0
->dst
, &spidx1
->dst
, spidx0
->dst
.ss_len
) != 0)
5750 /* XXX Do we check other field ? e.g. flowinfo */
5756 key_is_addr_in_range(struct sockaddr_storage
*addr
, struct secpolicyaddrrange
*addr_range
)
5760 if (addr
== NULL
|| addr_range
== NULL
)
5763 /* Must be greater than or equal to start */
5764 cmp
= key_sockaddrcmp((struct sockaddr
*)addr
, (struct sockaddr
*)&addr_range
->start
, 1);
5765 if (cmp
!= 0 && cmp
!= 1)
5768 /* Must be less than or equal to end */
5769 cmp
= key_sockaddrcmp((struct sockaddr
*)addr
, (struct sockaddr
*)&addr_range
->end
, 1);
5770 if (cmp
!= 0 && cmp
!= -1)
5781 2: Not comparable or error
5785 struct sockaddr
*sa1
,
5786 struct sockaddr
*sa2
,
5790 int port_result
= 0;
5792 if (sa1
->sa_family
!= sa2
->sa_family
|| sa1
->sa_len
!= sa2
->sa_len
)
5795 if (sa1
->sa_len
== 0)
5798 switch (sa1
->sa_family
) {
5800 if (sa1
->sa_len
!= sizeof(struct sockaddr_in
))
5803 result
= memcmp(&satosin(sa1
)->sin_addr
.s_addr
, &satosin(sa2
)->sin_addr
.s_addr
, sizeof(satosin(sa1
)->sin_addr
.s_addr
));
5806 if (satosin(sa1
)->sin_port
< satosin(sa2
)->sin_port
) {
5808 } else if (satosin(sa1
)->sin_port
> satosin(sa2
)->sin_port
) {
5813 result
= port_result
;
5814 else if ((result
> 0 && port_result
< 0) || (result
< 0 && port_result
> 0))
5820 if (sa1
->sa_len
!= sizeof(struct sockaddr_in6
))
5821 return 2; /*EINVAL*/
5823 if (satosin6(sa1
)->sin6_scope_id
!=
5824 satosin6(sa2
)->sin6_scope_id
) {
5828 result
= memcmp(&satosin6(sa1
)->sin6_addr
.s6_addr
[0], &satosin6(sa2
)->sin6_addr
.s6_addr
[0], sizeof(struct in6_addr
));
5831 if (satosin6(sa1
)->sin6_port
< satosin6(sa2
)->sin6_port
) {
5833 } else if (satosin6(sa1
)->sin6_port
> satosin6(sa2
)->sin6_port
) {
5838 result
= port_result
;
5839 else if ((result
> 0 && port_result
< 0) || (result
< 0 && port_result
> 0))
5845 result
= memcmp(sa1
, sa2
, sa1
->sa_len
);
5849 if (result
< 0) result
= -1;
5850 else if (result
> 0) result
= 1;
5856 * compare two buffers with mask.
5860 * bits: Number of bits to compare
5873 /* XXX: This could be considerably faster if we compare a word
5874 * at a time, but it is complicated on LSB Endian machines */
5876 /* Handle null pointers */
5877 if (p1
== NULL
|| p2
== NULL
)
5887 mask
= ~((1<<(8-bits
))-1);
5888 if ((*p1
& mask
) != (*p2
& mask
))
5891 return 1; /* Match! */
5896 * scanning SPD and SAD to check status for each entries,
5897 * and do to remove or to expire.
5898 * XXX: year 2038 problem may remain.
5900 int key_timehandler_debug
= 0;
5901 u_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;
5902 u_int64_t total_sav_count
= 0;
5904 key_timehandler(void)
5908 struct secpolicy
**spbuf
= NULL
, **spptr
= NULL
;
5909 struct secasvar
**savexbuf
= NULL
, **savexptr
= NULL
;
5910 struct secasvar
**savkabuf
= NULL
, **savkaptr
= NULL
;
5911 int spbufcount
= 0, savbufcount
= 0, spcount
= 0, savexcount
= 0, savkacount
= 0, cnt
;
5912 int stop_handler
= 1; /* stop the timehandler */
5916 /* pre-allocate buffers before taking the lock */
5917 /* if allocation failures occur - portions of the processing will be skipped */
5918 if ((spbufcount
= ipsec_policy_count
) != 0) {
5920 KMALLOC_WAIT(spbuf
, struct secpolicy
**, spbufcount
* sizeof(struct secpolicy
*));
5924 if ((savbufcount
= ipsec_sav_count
) != 0) {
5926 KMALLOC_WAIT(savexbuf
, struct secasvar
**, savbufcount
* sizeof(struct secasvar
*));
5928 savexptr
= savexbuf
;
5929 KMALLOC_WAIT(savkabuf
, struct secasvar
**, savbufcount
* sizeof(struct secasvar
*));
5931 savkaptr
= savkabuf
;
5933 lck_mtx_lock(sadb_mutex
);
5937 struct secpolicy
*sp
, *nextsp
;
5939 for (dir
= 0; dir
< IPSEC_DIR_MAX
; dir
++) {
5940 for (sp
= LIST_FIRST(&sptree
[dir
]);
5944 /* don't prevent timehandler from stopping for generate policy */
5945 if (sp
->policy
!= IPSEC_POLICY_GENERATE
)
5948 nextsp
= LIST_NEXT(sp
, chain
);
5950 if (sp
->state
== IPSEC_SPSTATE_DEAD
) {
5951 key_freesp(sp
, KEY_SADB_LOCKED
);
5955 if (sp
->lifetime
== 0 && sp
->validtime
== 0)
5957 if (spbuf
&& spcount
< spbufcount
) {
5958 /* the deletion will occur next time */
5960 && tv
.tv_sec
- sp
->created
> sp
->lifetime
)
5962 && tv
.tv_sec
- sp
->lastused
> sp
->validtime
)) {
5963 //key_spdexpire(sp);
5964 sp
->state
= IPSEC_SPSTATE_DEAD
;
5976 struct secashead
*sah
, *nextsah
;
5977 struct secasvar
*sav
, *nextsav
;
5979 for (sah
= LIST_FIRST(&sahtree
);
5984 nextsah
= LIST_NEXT(sah
, chain
);
5986 /* if sah has been dead, then delete it and process next sah. */
5987 if (sah
->state
== SADB_SASTATE_DEAD
) {
5993 if (LIST_FIRST(&sah
->savtree
[SADB_SASTATE_LARVAL
]) == NULL
&&
5994 LIST_FIRST(&sah
->savtree
[SADB_SASTATE_MATURE
]) == NULL
&&
5995 LIST_FIRST(&sah
->savtree
[SADB_SASTATE_DYING
]) == NULL
&&
5996 LIST_FIRST(&sah
->savtree
[SADB_SASTATE_DEAD
]) == NULL
) {
6002 if (savbufcount
== 0) {
6008 /* if LARVAL entry doesn't become MATURE, delete it. */
6009 for (sav
= LIST_FIRST(&sah
->savtree
[SADB_SASTATE_LARVAL
]);
6015 nextsav
= LIST_NEXT(sav
, chain
);
6017 if (sav
->lft_h
!= NULL
) {
6018 /* If a hard lifetime is defined for the LARVAL SA, use it */
6019 if (sav
->lft_h
->sadb_lifetime_addtime
!= 0
6020 && tv
.tv_sec
- sav
->created
> sav
->lft_h
->sadb_lifetime_addtime
) {
6021 if (sav
->always_expire
) {
6022 key_send_delete(sav
);
6025 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
6026 key_freesav(sav
, KEY_SADB_LOCKED
);
6031 if (tv
.tv_sec
- sav
->created
> key_larval_lifetime
) {
6032 key_freesav(sav
, KEY_SADB_LOCKED
);
6038 * If this is a NAT traversal SA with no activity,
6039 * we need to send a keep alive.
6041 * Performed outside of the loop before so we will
6042 * only ever send one keepalive. The first SA on
6043 * the list is the one that will be used for sending
6044 * traffic, so this is the one we use for determining
6045 * when to send the keepalive.
6047 if (savkabuf
&& savkacount
< savbufcount
) {
6048 sav
= LIST_FIRST(&sah
->savtree
[SADB_SASTATE_MATURE
]); //%%% should we check dying list if this is empty???
6049 if (sav
&& (natt_keepalive_interval
|| sav
->natt_interval
) &&
6050 (sav
->flags
& (SADB_X_EXT_NATT_KEEPALIVE
| SADB_X_EXT_ESP_KEEPALIVE
)) != 0) {
6058 * check MATURE entry to start to send expire message
6061 for (sav
= LIST_FIRST(&sah
->savtree
[SADB_SASTATE_MATURE
]);
6067 nextsav
= LIST_NEXT(sav
, chain
);
6069 /* we don't need to check. */
6070 if (sav
->lft_s
== NULL
)
6074 if (sav
->lft_c
== NULL
) {
6075 ipseclog((LOG_DEBUG
,"key_timehandler: "
6076 "There is no CURRENT time, why?\n"));
6080 /* check SOFT lifetime */
6081 if (sav
->lft_s
->sadb_lifetime_addtime
!= 0
6082 && tv
.tv_sec
- sav
->created
> sav
->lft_s
->sadb_lifetime_addtime
) {
6084 * If always_expire is set, expire. Otherwise,
6085 * if the SA has not been used, delete immediately.
6087 if (sav
->lft_c
->sadb_lifetime_usetime
== 0
6088 && sav
->always_expire
== 0) {
6089 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
6090 key_freesav(sav
, KEY_SADB_LOCKED
);
6092 } else if (savexbuf
&& savexcount
< savbufcount
) {
6093 key_sa_chgstate(sav
, SADB_SASTATE_DYING
);
6100 /* check SOFT lifetime by bytes */
6102 * XXX I don't know the way to delete this SA
6103 * when new SA is installed. Caution when it's
6104 * installed too big lifetime by time.
6106 else if (savexbuf
&& savexcount
< savbufcount
6107 && sav
->lft_s
->sadb_lifetime_bytes
!= 0
6108 && sav
->lft_s
->sadb_lifetime_bytes
< sav
->lft_c
->sadb_lifetime_bytes
) {
6111 * XXX If we keep to send expire
6112 * message in the status of
6113 * DYING. Do remove below code.
6116 key_sa_chgstate(sav
, SADB_SASTATE_DYING
);
6123 /* check DYING entry to change status to DEAD. */
6124 for (sav
= LIST_FIRST(&sah
->savtree
[SADB_SASTATE_DYING
]);
6130 nextsav
= LIST_NEXT(sav
, chain
);
6132 /* we don't need to check. */
6133 if (sav
->lft_h
== NULL
)
6137 if (sav
->lft_c
== NULL
) {
6138 ipseclog((LOG_DEBUG
, "key_timehandler: "
6139 "There is no CURRENT time, why?\n"));
6143 if (sav
->lft_h
->sadb_lifetime_addtime
!= 0
6144 && tv
.tv_sec
- sav
->created
> sav
->lft_h
->sadb_lifetime_addtime
) {
6145 if (sav
->always_expire
) {
6146 key_send_delete(sav
);
6149 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
6150 key_freesav(sav
, KEY_SADB_LOCKED
);
6154 #if 0 /* XXX Should we keep to send expire message until HARD lifetime ? */
6155 else if (savbuf
&& savexcount
< savbufcount
6156 && sav
->lft_s
!= NULL
6157 && sav
->lft_s
->sadb_lifetime_addtime
!= 0
6158 && tv
.tv_sec
- sav
->created
> sav
->lft_s
->sadb_lifetime_addtime
) {
6160 * XXX: should be checked to be
6161 * installed the valid SA.
6165 * If there is no SA then sending
6174 /* check HARD lifetime by bytes */
6175 else if (sav
->lft_h
->sadb_lifetime_bytes
!= 0
6176 && sav
->lft_h
->sadb_lifetime_bytes
< sav
->lft_c
->sadb_lifetime_bytes
) {
6177 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
6178 key_freesav(sav
, KEY_SADB_LOCKED
);
6183 /* delete entry in DEAD */
6184 for (sav
= LIST_FIRST(&sah
->savtree
[SADB_SASTATE_DEAD
]);
6190 nextsav
= LIST_NEXT(sav
, chain
);
6193 if (sav
->state
!= SADB_SASTATE_DEAD
) {
6194 ipseclog((LOG_DEBUG
, "key_timehandler: "
6195 "invalid sav->state "
6196 "(queue: %d SA: %d): "
6198 SADB_SASTATE_DEAD
, sav
->state
));
6202 * do not call key_freesav() here.
6203 * sav should already be freed, and sav->refcnt
6204 * shows other references to sav
6205 * (such as from SPD).
6211 if (++key_timehandler_debug
>= 300) {
6212 if (key_debug_level
) {
6213 printf("%s: total stats for %u calls\n", __FUNCTION__
, key_timehandler_debug
);
6214 printf("%s: walked %u SPDs\n", __FUNCTION__
, spd_count
);
6215 printf("%s: walked %llu SAs: LARVAL SAs %u, MATURE SAs %u, DYING SAs %u, DEAD SAs %u\n", __FUNCTION__
,
6216 total_sav_count
, larval_sav_count
, mature_sav_count
, dying_sav_count
, dead_sav_count
);
6217 printf("%s: walked %u SAHs: DEAD SAHs %u, EMPTY SAHs %u\n", __FUNCTION__
,
6218 sah_count
, dead_sah_count
, empty_sah_count
);
6219 if (sah_search_calls
) {
6220 printf("%s: SAH search cost %d iters per call\n", __FUNCTION__
,
6221 (sah_search_count
/sah_search_calls
));
6227 empty_sah_count
= 0;
6228 larval_sav_count
= 0;
6229 mature_sav_count
= 0;
6230 dying_sav_count
= 0;
6232 total_sav_count
= 0;
6233 sah_search_count
= 0;
6234 sah_search_calls
= 0;
6235 key_timehandler_debug
= 0;
6237 #ifndef IPSEC_NONBLOCK_ACQUIRE
6240 struct secacq
*acq
, *nextacq
;
6242 for (acq
= LIST_FIRST(&acqtree
);
6247 nextacq
= LIST_NEXT(acq
, chain
);
6249 if (tv
.tv_sec
- acq
->created
> key_blockacq_lifetime
6250 && __LIST_CHAINED(acq
)) {
6251 LIST_REMOVE(acq
, chain
);
6260 struct secspacq
*acq
, *nextacq
;
6262 for (acq
= LIST_FIRST(&spacqtree
);
6267 nextacq
= LIST_NEXT(acq
, chain
);
6269 if (tv
.tv_sec
- acq
->created
> key_blockacq_lifetime
6270 && __LIST_CHAINED(acq
)) {
6271 LIST_REMOVE(acq
, chain
);
6277 /* initialize random seed */
6278 if (key_tick_init_random
++ > key_int_random
) {
6279 key_tick_init_random
= 0;
6283 uint64_t acc_sleep_time
= 0;
6284 absolutetime_to_nanoseconds(mach_absolutetime_asleep
, &acc_sleep_time
);
6285 natt_now
= ++up_time
+ (acc_sleep_time
/ NSEC_PER_SEC
);
6287 lck_mtx_unlock(sadb_mutex
);
6289 /* send messages outside of sadb_mutex */
6290 if (spbuf
&& spcount
> 0) {
6293 key_spdexpire(*(--spptr
));
6295 if (savkabuf
&& savkacount
> 0) {
6296 struct secasvar
**savkaptr_sav
= savkaptr
;
6297 int cnt_send
= savkacount
;
6299 while (cnt_send
--) {
6300 if (ipsec_send_natt_keepalive(*(--savkaptr
))) {
6301 // <rdar://6768487> iterate (all over again) and update timestamps
6302 struct secasvar
**savkaptr_update
= savkaptr_sav
;
6303 int cnt_update
= savkacount
;
6304 while (cnt_update
--) {
6305 key_update_natt_keepalive_timestamp(*savkaptr
,
6306 *(--savkaptr_update
));
6311 if (savexbuf
&& savexcount
> 0) {
6314 key_expire(*(--savexptr
));
6317 /* decrement ref counts and free buffers */
6318 lck_mtx_lock(sadb_mutex
);
6321 key_freesp(*spptr
++, KEY_SADB_LOCKED
);
6325 while (savkacount
--)
6326 key_freesav(*savkaptr
++, KEY_SADB_LOCKED
);
6330 while (savexcount
--)
6331 key_freesav(*savexptr
++, KEY_SADB_LOCKED
);
6336 key_timehandler_running
= 0;
6337 /* Turn on the ipsec bypass */
6340 /* do exchange to tick time !! */
6341 (void)timeout((void *)key_timehandler
, (void *)0, hz
);
6344 lck_mtx_unlock(sadb_mutex
);
6349 * to initialize a seed for random()
6355 /* Our PRNG is based on Yarrow and doesn't need to be seeded */
6362 srandom(tv
.tv_usec
);
6373 key_randomfill(&value
, sizeof(value
));
6383 cc_rand_generate(p
, l
);
6387 static int warn
= 1;
6390 n
= (size_t)read_random(p
, (u_int
)l
);
6394 bcopy(&v
, (u_int8_t
*)p
+ n
,
6395 l
- n
< sizeof(v
) ? l
- n
: sizeof(v
));
6399 printf("WARNING: pseudo-random number generator "
6400 "used for IPsec processing\n");
6408 * map SADB_SATYPE_* to IPPROTO_*.
6409 * if satype == SADB_SATYPE then satype is mapped to ~0.
6411 * 0: invalid satype.
6418 case SADB_SATYPE_UNSPEC
:
6419 return IPSEC_PROTO_ANY
;
6420 case SADB_SATYPE_AH
:
6422 case SADB_SATYPE_ESP
:
6424 case SADB_X_SATYPE_IPCOMP
:
6425 return IPPROTO_IPCOMP
;
6433 * map IPPROTO_* to SADB_SATYPE_*
6435 * 0: invalid protocol type.
6443 return SADB_SATYPE_AH
;
6445 return SADB_SATYPE_ESP
;
6446 case IPPROTO_IPCOMP
:
6447 return SADB_X_SATYPE_IPCOMP
;
6455 key_get_ipsec_if_from_message (const struct sadb_msghdr
*mhp
, int message_type
)
6457 struct sadb_x_ipsecif
*ipsecifopts
= NULL
;
6458 ifnet_t ipsec_if
= NULL
;
6460 ipsecifopts
= (struct sadb_x_ipsecif
*)(void *)mhp
->ext
[message_type
];
6461 if (ipsecifopts
!= NULL
) {
6462 if (ipsecifopts
->sadb_x_ipsecif_ipsec_if
[0]) {
6463 ifnet_find_by_name(ipsecifopts
->sadb_x_ipsecif_ipsec_if
, &ipsec_if
);
6471 key_get_outgoing_ifindex_from_message (const struct sadb_msghdr
*mhp
, int message_type
)
6473 struct sadb_x_ipsecif
*ipsecifopts
= NULL
;
6474 ifnet_t outgoing_if
= NULL
;
6476 ipsecifopts
= (struct sadb_x_ipsecif
*)(void *)mhp
->ext
[message_type
];
6477 if (ipsecifopts
!= NULL
) {
6478 if (ipsecifopts
->sadb_x_ipsecif_outgoing_if
[0]) {
6479 ifnet_find_by_name(ipsecifopts
->sadb_x_ipsecif_outgoing_if
, &outgoing_if
);
6483 return outgoing_if
? outgoing_if
->if_index
: 0;
6488 * SADB_GETSPI processing is to receive
6489 * <base, (SA2), src address, dst address, (SPI range)>
6490 * from the IKMPd, to assign a unique spi value, to hang on the INBOUND
6491 * tree with the status of LARVAL, and send
6492 * <base, SA(*), address(SD)>
6495 * IN: mhp: pointer to the pointer to each header.
6496 * OUT: NULL if fail.
6497 * other if success, return pointer to the message to send.
6503 const struct sadb_msghdr
*mhp
)
6505 struct sadb_address
*src0
, *dst0
;
6506 struct secasindex saidx
;
6507 struct secashead
*newsah
;
6508 struct secasvar
*newsav
;
6509 ifnet_t ipsec_if
= NULL
;
6516 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
6519 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
6520 panic("key_getspi: NULL pointer is passed.\n");
6522 if (mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
6523 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
) {
6524 ipseclog((LOG_DEBUG
, "key_getspi: invalid message is passed.\n"));
6525 return key_senderror(so
, m
, EINVAL
);
6527 if (mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
6528 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) {
6529 ipseclog((LOG_DEBUG
, "key_getspi: invalid message is passed.\n"));
6530 return key_senderror(so
, m
, EINVAL
);
6532 if (mhp
->ext
[SADB_X_EXT_SA2
] != NULL
) {
6533 mode
= ((struct sadb_x_sa2
*)
6534 (void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
6535 reqid
= ((struct sadb_x_sa2
*)
6536 (void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_reqid
;
6538 mode
= IPSEC_MODE_ANY
;
6542 src0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_SRC
]);
6543 dst0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_DST
]);
6545 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
6547 /* map satype to proto */
6548 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
6549 ipseclog((LOG_DEBUG
, "key_getspi: invalid satype is passed.\n"));
6550 return key_senderror(so
, m
, EINVAL
);
6553 /* make sure if port number is zero. */
6554 switch (((struct sockaddr
*)(src0
+ 1))->sa_family
) {
6556 if (((struct sockaddr
*)(src0
+ 1))->sa_len
!=
6557 sizeof(struct sockaddr_in
))
6558 return key_senderror(so
, m
, EINVAL
);
6559 ((struct sockaddr_in
*)(void *)(src0
+ 1))->sin_port
= 0;
6562 if (((struct sockaddr
*)(src0
+ 1))->sa_len
!=
6563 sizeof(struct sockaddr_in6
))
6564 return key_senderror(so
, m
, EINVAL
);
6565 ((struct sockaddr_in6
*)(void *)(src0
+ 1))->sin6_port
= 0;
6570 switch (((struct sockaddr
*)(dst0
+ 1))->sa_family
) {
6572 if (((struct sockaddr
*)(dst0
+ 1))->sa_len
!=
6573 sizeof(struct sockaddr_in
))
6574 return key_senderror(so
, m
, EINVAL
);
6575 ((struct sockaddr_in
*)(void *)(dst0
+ 1))->sin_port
= 0;
6578 if (((struct sockaddr
*)(dst0
+ 1))->sa_len
!=
6579 sizeof(struct sockaddr_in6
))
6580 return key_senderror(so
, m
, EINVAL
);
6581 ((struct sockaddr_in6
*)(void *)(dst0
+ 1))->sin6_port
= 0;
6587 /* XXX boundary check against sa_len */
6588 KEY_SETSECASIDX(proto
, mode
, reqid
, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
6590 lck_mtx_lock(sadb_mutex
);
6592 /* SPI allocation */
6593 spi
= key_do_getnewspi((struct sadb_spirange
*)
6594 (void *)mhp
->ext
[SADB_EXT_SPIRANGE
], &saidx
);
6596 lck_mtx_unlock(sadb_mutex
);
6597 return key_senderror(so
, m
, EINVAL
);
6600 /* get a SA index */
6601 if ((newsah
= key_getsah(&saidx
)) == NULL
) {
6602 /* create a new SA index: key_addspi is always used for inbound spi */
6603 if ((newsah
= key_newsah(&saidx
, ipsec_if
, key_get_outgoing_ifindex_from_message(mhp
, SADB_X_EXT_IPSECIF
), IPSEC_DIR_INBOUND
)) == NULL
) {
6604 lck_mtx_unlock(sadb_mutex
);
6605 ipseclog((LOG_DEBUG
, "key_getspi: No more memory.\n"));
6606 return key_senderror(so
, m
, ENOBUFS
);
6612 newsav
= key_newsav(m
, mhp
, newsah
, &error
, so
);
6613 if (newsav
== NULL
) {
6614 /* XXX don't free new SA index allocated in above. */
6615 lck_mtx_unlock(sadb_mutex
);
6616 return key_senderror(so
, m
, error
);
6620 key_setspi(newsav
, htonl(spi
));
6622 #ifndef IPSEC_NONBLOCK_ACQUIRE
6623 /* delete the entry in acqtree */
6624 if (mhp
->msg
->sadb_msg_seq
!= 0) {
6626 if ((acq
= key_getacqbyseq(mhp
->msg
->sadb_msg_seq
)) != NULL
) {
6627 /* reset counter in order to deletion by timehandler. */
6630 acq
->created
= tv
.tv_sec
;
6636 lck_mtx_unlock(sadb_mutex
);
6639 struct mbuf
*n
, *nn
;
6640 struct sadb_sa
*m_sa
;
6641 struct sadb_msg
*newmsg
;
6644 /* create new sadb_msg to reply. */
6645 len
= PFKEY_ALIGN8(sizeof(struct sadb_msg
)) +
6646 PFKEY_ALIGN8(sizeof(struct sadb_sa
));
6648 return key_senderror(so
, m
, ENOBUFS
);
6650 MGETHDR(n
, M_WAITOK
, MT_DATA
);
6651 if (n
&& len
> MHLEN
) {
6652 MCLGET(n
, M_WAITOK
);
6653 if ((n
->m_flags
& M_EXT
) == 0) {
6659 return key_senderror(so
, m
, ENOBUFS
);
6665 m_copydata(m
, 0, sizeof(struct sadb_msg
), mtod(n
, caddr_t
) + off
);
6666 off
+= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
6668 m_sa
= (struct sadb_sa
*)(void *)(mtod(n
, caddr_t
) + off
);
6669 m_sa
->sadb_sa_len
= PFKEY_UNIT64(sizeof(struct sadb_sa
));
6670 m_sa
->sadb_sa_exttype
= SADB_EXT_SA
;
6671 m_sa
->sadb_sa_spi
= htonl(spi
);
6672 off
+= PFKEY_ALIGN8(sizeof(struct sadb_sa
));
6676 panic("length inconsistency in key_getspi");
6679 int mbufItems
[] = {SADB_EXT_ADDRESS_SRC
, SADB_EXT_ADDRESS_DST
};
6680 n
->m_next
= key_gather_mbuf(m
, mhp
, 0, sizeof(mbufItems
)/sizeof(int), mbufItems
);
6683 return key_senderror(so
, m
, ENOBUFS
);
6687 if (n
->m_len
< sizeof(struct sadb_msg
)) {
6688 n
= m_pullup(n
, sizeof(struct sadb_msg
));
6690 return key_sendup_mbuf(so
, m
, KEY_SENDUP_ONE
);
6693 n
->m_pkthdr
.len
= 0;
6694 for (nn
= n
; nn
; nn
= nn
->m_next
)
6695 n
->m_pkthdr
.len
+= nn
->m_len
;
6697 newmsg
= mtod(n
, struct sadb_msg
*);
6698 newmsg
->sadb_msg_seq
= newsav
->seq
;
6699 newmsg
->sadb_msg_errno
= 0;
6700 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
6703 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ONE
);
6708 key_getspi2(struct sockaddr
*src
,
6709 struct sockaddr
*dst
,
6713 struct sadb_spirange
*spirange
)
6716 struct secasindex saidx
;
6718 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
6720 /* XXX boundary check against sa_len */
6721 KEY_SETSECASIDX(proto
, mode
, reqid
, src
, dst
, 0, &saidx
);
6723 /* make sure if port number is zero. */
6724 switch (((struct sockaddr
*)&saidx
.src
)->sa_family
) {
6726 if (((struct sockaddr
*)&saidx
.src
)->sa_len
!= sizeof(struct sockaddr_in
))
6728 ((struct sockaddr_in
*)&saidx
.src
)->sin_port
= 0;
6731 if (((struct sockaddr
*)&saidx
.src
)->sa_len
!= sizeof(struct sockaddr_in6
))
6733 ((struct sockaddr_in6
*)&saidx
.src
)->sin6_port
= 0;
6738 switch (((struct sockaddr
*)&saidx
.dst
)->sa_family
) {
6740 if (((struct sockaddr
*)&saidx
.dst
)->sa_len
!= sizeof(struct sockaddr_in
))
6742 ((struct sockaddr_in
*)&saidx
.dst
)->sin_port
= 0;
6745 if (((struct sockaddr
*)&saidx
.dst
)->sa_len
!= sizeof(struct sockaddr_in6
))
6747 ((struct sockaddr_in6
*)&saidx
.dst
)->sin6_port
= 0;
6753 lck_mtx_lock(sadb_mutex
);
6755 /* SPI allocation */
6756 spi
= key_do_getnewspi(spirange
, &saidx
);
6758 lck_mtx_unlock(sadb_mutex
);
6764 * allocating new SPI
6765 * called by key_getspi() and key_getspi2().
6772 struct sadb_spirange
*spirange
,
6773 struct secasindex
*saidx
)
6776 u_int32_t keymin
, keymax
;
6777 int count
= key_spi_trycnt
;
6779 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
6781 /* set spi range to allocate */
6782 if (spirange
!= NULL
) {
6783 keymin
= spirange
->sadb_spirange_min
;
6784 keymax
= spirange
->sadb_spirange_max
;
6786 keymin
= key_spi_minval
;
6787 keymax
= key_spi_maxval
;
6789 /* IPCOMP needs 2-byte SPI */
6790 if (saidx
->proto
== IPPROTO_IPCOMP
) {
6792 if (keymin
>= 0x10000)
6794 if (keymax
>= 0x10000)
6796 if (keymin
> keymax
) {
6797 t
= keymin
; keymin
= keymax
; keymax
= t
;
6801 if (keymin
== keymax
) {
6802 if (key_checkspidup(saidx
, keymin
) != NULL
) {
6803 ipseclog((LOG_DEBUG
, "key_do_getnewspi: SPI %u exists already.\n", keymin
));
6807 count
--; /* taking one cost. */
6812 u_int32_t range
= keymax
- keymin
+ 1; /* overflow value of zero means full range */
6817 /* when requesting to allocate spi ranged */
6819 u_int32_t rand_val
= key_random();
6821 /* generate pseudo-random SPI value ranged. */
6822 newspi
= (range
== 0 ? rand_val
: keymin
+ (rand_val
% range
));
6824 if (key_checkspidup(saidx
, newspi
) == NULL
)
6828 if (count
== 0 || newspi
== 0) {
6829 ipseclog((LOG_DEBUG
, "key_do_getnewspi: to allocate spi is failed.\n"));
6835 keystat
.getspi_count
=
6836 (keystat
.getspi_count
+ key_spi_trycnt
- count
) / 2;
6842 * SADB_UPDATE processing
6844 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
6845 * key(AE), (identity(SD),) (sensitivity)>
6846 * from the ikmpd, and update a secasvar entry whose status is SADB_SASTATE_LARVAL.
6848 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
6849 * (identity(SD),) (sensitivity)>
6852 * m will always be freed.
6858 const struct sadb_msghdr
*mhp
)
6860 struct sadb_sa
*sa0
;
6861 struct sadb_address
*src0
, *dst0
;
6862 ifnet_t ipsec_if
= NULL
;
6863 struct secasindex saidx
;
6864 struct secashead
*sah
;
6865 struct secasvar
*sav
;
6872 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
6875 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
6876 panic("key_update: NULL pointer is passed.\n");
6878 /* map satype to proto */
6879 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
6880 ipseclog((LOG_DEBUG
, "key_update: invalid satype is passed.\n"));
6881 return key_senderror(so
, m
, EINVAL
);
6884 if (mhp
->ext
[SADB_EXT_SA
] == NULL
||
6885 mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
6886 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
||
6887 (mhp
->msg
->sadb_msg_satype
== SADB_SATYPE_ESP
&&
6888 mhp
->ext
[SADB_EXT_KEY_ENCRYPT
] == NULL
) ||
6889 (mhp
->msg
->sadb_msg_satype
== SADB_SATYPE_AH
&&
6890 mhp
->ext
[SADB_EXT_KEY_AUTH
] == NULL
) ||
6891 (mhp
->ext
[SADB_EXT_LIFETIME_HARD
] != NULL
&&
6892 mhp
->ext
[SADB_EXT_LIFETIME_SOFT
] == NULL
) ||
6893 (mhp
->ext
[SADB_EXT_LIFETIME_HARD
] == NULL
&&
6894 mhp
->ext
[SADB_EXT_LIFETIME_SOFT
] != NULL
)) {
6895 ipseclog((LOG_DEBUG
, "key_update: invalid message is passed.\n"));
6896 return key_senderror(so
, m
, EINVAL
);
6898 if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(struct sadb_sa
) ||
6899 mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
6900 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) {
6901 ipseclog((LOG_DEBUG
, "key_update: invalid message is passed.\n"));
6902 return key_senderror(so
, m
, EINVAL
);
6904 if (mhp
->ext
[SADB_X_EXT_SA2
] != NULL
) {
6905 mode
= ((struct sadb_x_sa2
*)
6906 (void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
6907 reqid
= ((struct sadb_x_sa2
*)
6908 (void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_reqid
;
6909 flags2
= ((struct sadb_x_sa2
*)(void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_flags
;
6911 mode
= IPSEC_MODE_ANY
;
6915 /* XXX boundary checking for other extensions */
6917 sa0
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
6918 src0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_SRC
]);
6919 dst0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_DST
]);
6920 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
6922 /* XXX boundary check against sa_len */
6923 KEY_SETSECASIDX(proto
, mode
, reqid
, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
6925 lck_mtx_lock(sadb_mutex
);
6927 /* get a SA header */
6928 if ((sah
= key_getsah(&saidx
)) == NULL
) {
6929 lck_mtx_unlock(sadb_mutex
);
6930 ipseclog((LOG_DEBUG
, "key_update: no SA index found.\n"));
6931 return key_senderror(so
, m
, ENOENT
);
6934 /* set spidx if there */
6936 error
= key_setident(sah
, m
, mhp
);
6938 lck_mtx_unlock(sadb_mutex
);
6939 return key_senderror(so
, m
, error
);
6942 /* find a SA with sequence number. */
6943 #if IPSEC_DOSEQCHECK
6944 if (mhp
->msg
->sadb_msg_seq
!= 0
6945 && (sav
= key_getsavbyseq(sah
, mhp
->msg
->sadb_msg_seq
)) == NULL
) {
6946 lck_mtx_unlock(sadb_mutex
);
6947 ipseclog((LOG_DEBUG
,
6948 "key_update: no larval SA with sequence %u exists.\n",
6949 mhp
->msg
->sadb_msg_seq
));
6950 return key_senderror(so
, m
, ENOENT
);
6953 if ((sav
= key_getsavbyspi(sah
, sa0
->sadb_sa_spi
)) == NULL
) {
6954 lck_mtx_unlock(sadb_mutex
);
6955 ipseclog((LOG_DEBUG
,
6956 "key_update: no such a SA found (spi:%u)\n",
6957 (u_int32_t
)ntohl(sa0
->sadb_sa_spi
)));
6958 return key_senderror(so
, m
, EINVAL
);
6962 /* validity check */
6963 if (sav
->sah
->saidx
.proto
!= proto
) {
6964 lck_mtx_unlock(sadb_mutex
);
6965 ipseclog((LOG_DEBUG
,
6966 "key_update: protocol mismatched (DB=%u param=%u)\n",
6967 sav
->sah
->saidx
.proto
, proto
));
6968 return key_senderror(so
, m
, EINVAL
);
6970 #if IPSEC_DOSEQCHECK
6971 if (sav
->spi
!= sa0
->sadb_sa_spi
) {
6972 lck_mtx_unlock(sadb_mutex
);
6973 ipseclog((LOG_DEBUG
,
6974 "key_update: SPI mismatched (DB:%u param:%u)\n",
6975 (u_int32_t
)ntohl(sav
->spi
),
6976 (u_int32_t
)ntohl(sa0
->sadb_sa_spi
)));
6977 return key_senderror(so
, m
, EINVAL
);
6980 if (sav
->pid
!= mhp
->msg
->sadb_msg_pid
) {
6981 lck_mtx_unlock(sadb_mutex
);
6982 ipseclog((LOG_DEBUG
,
6983 "key_update: pid mismatched (DB:%u param:%u)\n",
6984 sav
->pid
, mhp
->msg
->sadb_msg_pid
));
6985 return key_senderror(so
, m
, EINVAL
);
6988 /* copy sav values */
6989 error
= key_setsaval(sav
, m
, mhp
);
6991 key_freesav(sav
, KEY_SADB_LOCKED
);
6992 lck_mtx_unlock(sadb_mutex
);
6993 return key_senderror(so
, m
, error
);
6996 sav
->flags2
= flags2
;
6997 if (flags2
& SADB_X_EXT_SA2_DELETE_ON_DETACH
) {
7002 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
7003 * this SA is for transport mode - otherwise clear it.
7005 if ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0 &&
7006 (sav
->sah
->saidx
.mode
!= IPSEC_MODE_TRANSPORT
||
7007 sav
->sah
->saidx
.src
.ss_family
!= AF_INET
))
7008 sav
->flags
&= ~SADB_X_EXT_NATT_MULTIPLEUSERS
;
7010 /* check SA values to be mature. */
7011 if ((error
= key_mature(sav
)) != 0) {
7012 key_freesav(sav
, KEY_SADB_LOCKED
);
7013 lck_mtx_unlock(sadb_mutex
);
7014 return key_senderror(so
, m
, error
);
7017 lck_mtx_unlock(sadb_mutex
);
7022 /* set msg buf from mhp */
7023 n
= key_getmsgbuf_x1(m
, mhp
);
7025 ipseclog((LOG_DEBUG
, "key_update: No more memory.\n"));
7026 return key_senderror(so
, m
, ENOBUFS
);
7030 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
7035 key_migrate(struct socket
*so
,
7037 const struct sadb_msghdr
*mhp
)
7039 struct sadb_sa
*sa0
= NULL
;
7040 struct sadb_address
*src0
= NULL
;
7041 struct sadb_address
*dst0
= NULL
;
7042 struct sadb_address
*src1
= NULL
;
7043 struct sadb_address
*dst1
= NULL
;
7044 ifnet_t ipsec_if0
= NULL
;
7045 ifnet_t ipsec_if1
= NULL
;
7046 struct secasindex saidx0
;
7047 struct secasindex saidx1
;
7048 struct secashead
*sah
= NULL
;
7049 struct secashead
*newsah
= NULL
;
7050 struct secasvar
*sav
= NULL
;
7053 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
7056 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
7057 panic("key_migrate: NULL pointer is passed.\n");
7059 /* map satype to proto */
7060 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
7061 ipseclog((LOG_DEBUG
, "key_migrate: invalid satype is passed.\n"));
7062 return key_senderror(so
, m
, EINVAL
);
7065 if (mhp
->ext
[SADB_EXT_SA
] == NULL
||
7066 mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
7067 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
||
7068 mhp
->ext
[SADB_EXT_MIGRATE_ADDRESS_SRC
] == NULL
||
7069 mhp
->ext
[SADB_EXT_MIGRATE_ADDRESS_DST
] == NULL
) {
7070 ipseclog((LOG_DEBUG
, "key_migrate: invalid message is passed.\n"));
7071 return key_senderror(so
, m
, EINVAL
);
7074 if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(struct sadb_sa
) ||
7075 mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
7076 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
) ||
7077 mhp
->extlen
[SADB_EXT_MIGRATE_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
7078 mhp
->extlen
[SADB_EXT_MIGRATE_ADDRESS_DST
] < sizeof(struct sadb_address
)) {
7079 ipseclog((LOG_DEBUG
, "key_migrate: invalid message is passed.\n"));
7080 return key_senderror(so
, m
, EINVAL
);
7083 lck_mtx_lock(sadb_mutex
);
7085 sa0
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
7086 src0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_SRC
]);
7087 dst0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_DST
]);
7088 src1
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_MIGRATE_ADDRESS_SRC
]);
7089 dst1
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_MIGRATE_ADDRESS_DST
]);
7090 ipsec_if0
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
7091 ipsec_if1
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_MIGRATE_IPSECIF
);
7093 /* Find existing SAH and SAV */
7094 KEY_SETSECASIDX(proto
, IPSEC_MODE_ANY
, 0, src0
+ 1, dst0
+ 1, ipsec_if0
? ipsec_if0
->if_index
: 0, &saidx0
);
7096 LIST_FOREACH(sah
, &sahtree
, chain
) {
7097 if (sah
->state
!= SADB_SASTATE_MATURE
)
7099 if (key_cmpsaidx(&sah
->saidx
, &saidx0
, CMP_HEAD
) == 0)
7102 sav
= key_getsavbyspi(sah
, sa0
->sadb_sa_spi
);
7103 if (sav
&& sav
->state
== SADB_SASTATE_MATURE
)
7107 lck_mtx_unlock(sadb_mutex
);
7108 ipseclog((LOG_DEBUG
, "key_migrate: no mature SAH found.\n"));
7109 return key_senderror(so
, m
, ENOENT
);
7113 lck_mtx_unlock(sadb_mutex
);
7114 ipseclog((LOG_DEBUG
, "key_migrate: no SA found.\n"));
7115 return key_senderror(so
, m
, ENOENT
);
7118 /* Find or create new SAH */
7119 KEY_SETSECASIDX(proto
, sah
->saidx
.mode
, sah
->saidx
.reqid
, src1
+ 1, dst1
+ 1, ipsec_if1
? ipsec_if1
->if_index
: 0, &saidx1
);
7121 if ((newsah
= key_getsah(&saidx1
)) == NULL
) {
7122 if ((newsah
= key_newsah(&saidx1
, ipsec_if1
, key_get_outgoing_ifindex_from_message(mhp
, SADB_X_EXT_MIGRATE_IPSECIF
), sah
->dir
)) == NULL
) {
7123 lck_mtx_unlock(sadb_mutex
);
7124 ipseclog((LOG_DEBUG
, "key_migrate: No more memory.\n"));
7125 return key_senderror(so
, m
, ENOBUFS
);
7129 /* Migrate SAV in to new SAH */
7130 if (key_migratesav(sav
, newsah
) != 0) {
7131 lck_mtx_unlock(sadb_mutex
);
7132 ipseclog((LOG_DEBUG
, "key_migrate: Failed to migrate SA to new SAH.\n"));
7133 return key_senderror(so
, m
, EINVAL
);
7136 /* Reset NAT values */
7137 sav
->flags
= sa0
->sadb_sa_flags
;
7138 sav
->remote_ike_port
= ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_port
;
7139 sav
->natt_interval
= ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_interval
;
7140 sav
->natt_offload_interval
= ((const struct sadb_sa_2
*)(sa0
))->sadb_sa_natt_offload_interval
;
7141 sav
->natt_last_activity
= natt_now
;
7144 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
7145 * SADB_X_EXT_NATT is set and SADB_X_EXT_NATT_KEEPALIVE is not
7146 * set (we're not behind nat) - otherwise clear it.
7148 if ((sav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0)
7149 if ((sav
->flags
& SADB_X_EXT_NATT
) == 0 ||
7150 (sav
->flags
& SADB_X_EXT_NATT_KEEPALIVE
) != 0)
7151 sav
->flags
&= ~SADB_X_EXT_NATT_MULTIPLEUSERS
;
7153 lck_mtx_unlock(sadb_mutex
);
7156 struct sadb_msg
*newmsg
;
7157 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_EXT_SA
,
7158 SADB_EXT_ADDRESS_SRC
, SADB_EXT_ADDRESS_DST
, SADB_X_EXT_IPSECIF
,
7159 SADB_EXT_MIGRATE_ADDRESS_SRC
, SADB_EXT_MIGRATE_ADDRESS_DST
, SADB_X_EXT_MIGRATE_IPSECIF
};
7161 /* create new sadb_msg to reply. */
7162 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
7164 return key_senderror(so
, m
, ENOBUFS
);
7166 if (n
->m_len
< sizeof(struct sadb_msg
)) {
7167 n
= m_pullup(n
, sizeof(struct sadb_msg
));
7169 return key_senderror(so
, m
, ENOBUFS
);
7171 newmsg
= mtod(n
, struct sadb_msg
*);
7172 newmsg
->sadb_msg_errno
= 0;
7173 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
7176 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
7181 * search SAD with sequence for a SA which state is SADB_SASTATE_LARVAL.
7182 * only called by key_update().
7185 * others : found, pointer to a SA.
7187 #if IPSEC_DOSEQCHECK
7188 static struct secasvar
*
7190 struct secashead
*sah
,
7193 struct secasvar
*sav
;
7196 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
7198 state
= SADB_SASTATE_LARVAL
;
7200 /* search SAD with sequence number ? */
7201 LIST_FOREACH(sav
, &sah
->savtree
[state
], chain
) {
7203 KEY_CHKSASTATE(state
, sav
->state
, "key_getsabyseq");
7205 if (sav
->seq
== seq
) {
7207 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
7208 printf("DP key_getsavbyseq cause "
7209 "refcnt++:%d SA:0x%llx\n", sav
->refcnt
,
7210 (uint64_t)VM_KERNEL_ADDRPERM(sav
)));
7220 * SADB_ADD processing
7221 * add a entry to SA database, when received
7222 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
7223 * key(AE), (identity(SD),) (sensitivity)>
7226 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
7227 * (identity(SD),) (sensitivity)>
7230 * IGNORE identity and sensitivity messages.
7232 * m will always be freed.
7238 const struct sadb_msghdr
*mhp
)
7240 struct sadb_sa
*sa0
;
7241 struct sadb_address
*src0
, *dst0
;
7242 ifnet_t ipsec_if
= NULL
;
7243 struct secasindex saidx
;
7244 struct secashead
*newsah
;
7245 struct secasvar
*newsav
;
7251 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
7254 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
7255 panic("key_add: NULL pointer is passed.\n");
7257 /* map satype to proto */
7258 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
7259 ipseclog((LOG_DEBUG
, "key_add: invalid satype is passed.\n"));
7261 return key_senderror(so
, m
, EINVAL
);
7264 if (mhp
->ext
[SADB_EXT_SA
] == NULL
||
7265 mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
7266 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
||
7267 (mhp
->msg
->sadb_msg_satype
== SADB_SATYPE_ESP
&&
7268 mhp
->ext
[SADB_EXT_KEY_ENCRYPT
] == NULL
) ||
7269 (mhp
->msg
->sadb_msg_satype
== SADB_SATYPE_AH
&&
7270 mhp
->ext
[SADB_EXT_KEY_AUTH
] == NULL
) ||
7271 (mhp
->ext
[SADB_EXT_LIFETIME_HARD
] != NULL
&&
7272 mhp
->ext
[SADB_EXT_LIFETIME_SOFT
] == NULL
) ||
7273 (mhp
->ext
[SADB_EXT_LIFETIME_HARD
] == NULL
&&
7274 mhp
->ext
[SADB_EXT_LIFETIME_SOFT
] != NULL
)) {
7275 ipseclog((LOG_DEBUG
, "key_add: invalid message is passed.\n"));
7277 return key_senderror(so
, m
, EINVAL
);
7279 if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(struct sadb_sa
) ||
7280 mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
7281 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) {
7283 ipseclog((LOG_DEBUG
, "key_add: invalid message is passed.\n"));
7285 return key_senderror(so
, m
, EINVAL
);
7287 if (mhp
->ext
[SADB_X_EXT_SA2
] != NULL
) {
7288 mode
= ((struct sadb_x_sa2
*)
7289 (void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
7290 reqid
= ((struct sadb_x_sa2
*)
7291 (void *)mhp
->ext
[SADB_X_EXT_SA2
])->sadb_x_sa2_reqid
;
7293 mode
= IPSEC_MODE_ANY
;
7297 sa0
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
7298 src0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_SRC
];
7299 dst0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_DST
];
7300 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
7302 /* XXX boundary check against sa_len */
7303 KEY_SETSECASIDX(proto
, mode
, reqid
, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
7305 lck_mtx_lock(sadb_mutex
);
7307 /* get a SA header */
7308 if ((newsah
= key_getsah(&saidx
)) == NULL
) {
7309 /* create a new SA header: key_addspi is always used for outbound spi */
7310 if ((newsah
= key_newsah(&saidx
, ipsec_if
, key_get_outgoing_ifindex_from_message(mhp
, SADB_X_EXT_IPSECIF
), IPSEC_DIR_OUTBOUND
)) == NULL
) {
7311 lck_mtx_unlock(sadb_mutex
);
7312 ipseclog((LOG_DEBUG
, "key_add: No more memory.\n"));
7314 return key_senderror(so
, m
, ENOBUFS
);
7318 /* set spidx if there */
7320 error
= key_setident(newsah
, m
, mhp
);
7322 lck_mtx_unlock(sadb_mutex
);
7324 return key_senderror(so
, m
, error
);
7327 /* create new SA entry. */
7328 /* We can create new SA only if SPI is different. */
7329 if (key_getsavbyspi(newsah
, sa0
->sadb_sa_spi
)) {
7330 lck_mtx_unlock(sadb_mutex
);
7331 ipseclog((LOG_DEBUG
, "key_add: SA already exists.\n"));
7333 return key_senderror(so
, m
, EEXIST
);
7335 newsav
= key_newsav(m
, mhp
, newsah
, &error
, so
);
7336 if (newsav
== NULL
) {
7337 lck_mtx_unlock(sadb_mutex
);
7339 return key_senderror(so
, m
, error
);
7343 * Verify if SADB_X_EXT_NATT_MULTIPLEUSERS flag is set that
7344 * this SA is for transport mode - otherwise clear it.
7346 if ((newsav
->flags
& SADB_X_EXT_NATT_MULTIPLEUSERS
) != 0 &&
7347 (newsah
->saidx
.mode
!= IPSEC_MODE_TRANSPORT
||
7348 newsah
->saidx
.dst
.ss_family
!= AF_INET
))
7349 newsav
->flags
&= ~SADB_X_EXT_NATT_MULTIPLEUSERS
;
7351 /* check SA values to be mature. */
7352 if ((error
= key_mature(newsav
)) != 0) {
7353 key_freesav(newsav
, KEY_SADB_LOCKED
);
7354 lck_mtx_unlock(sadb_mutex
);
7356 return key_senderror(so
, m
, error
);
7359 lck_mtx_unlock(sadb_mutex
);
7362 * don't call key_freesav() here, as we would like to keep the SA
7363 * in the database on success.
7369 /* set msg buf from mhp */
7370 n
= key_getmsgbuf_x1(m
, mhp
);
7372 ipseclog((LOG_DEBUG
, "key_update: No more memory.\n"));
7374 return key_senderror(so
, m
, ENOBUFS
);
7377 // mh.ext points to the mbuf content.
7378 // Zero out Encryption and Integrity keys if present.
7381 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
7388 struct secashead
*sah
,
7390 const struct sadb_msghdr
*mhp
)
7392 const struct sadb_ident
*idsrc
, *iddst
;
7393 int idsrclen
, iddstlen
;
7395 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
7398 if (sah
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
7399 panic("key_setident: NULL pointer is passed.\n");
7401 /* don't make buffer if not there */
7402 if (mhp
->ext
[SADB_EXT_IDENTITY_SRC
] == NULL
&&
7403 mhp
->ext
[SADB_EXT_IDENTITY_DST
] == NULL
) {
7409 if (mhp
->ext
[SADB_EXT_IDENTITY_SRC
] == NULL
||
7410 mhp
->ext
[SADB_EXT_IDENTITY_DST
] == NULL
) {
7411 ipseclog((LOG_DEBUG
, "key_setident: invalid identity.\n"));
7415 idsrc
= (const struct sadb_ident
*)
7416 (void *)mhp
->ext
[SADB_EXT_IDENTITY_SRC
];
7417 iddst
= (const struct sadb_ident
*)
7418 (void *)mhp
->ext
[SADB_EXT_IDENTITY_DST
];
7419 idsrclen
= mhp
->extlen
[SADB_EXT_IDENTITY_SRC
];
7420 iddstlen
= mhp
->extlen
[SADB_EXT_IDENTITY_DST
];
7422 /* validity check */
7423 if (idsrc
->sadb_ident_type
!= iddst
->sadb_ident_type
) {
7424 ipseclog((LOG_DEBUG
, "key_setident: ident type mismatch.\n"));
7428 switch (idsrc
->sadb_ident_type
) {
7429 case SADB_IDENTTYPE_PREFIX
:
7430 case SADB_IDENTTYPE_FQDN
:
7431 case SADB_IDENTTYPE_USERFQDN
:
7433 /* XXX do nothing */
7439 /* make structure */
7440 KMALLOC_NOWAIT(sah
->idents
, struct sadb_ident
*, idsrclen
);
7441 if (sah
->idents
== NULL
) {
7442 lck_mtx_unlock(sadb_mutex
);
7443 KMALLOC_WAIT(sah
->idents
, struct sadb_ident
*, idsrclen
);
7444 lck_mtx_lock(sadb_mutex
);
7445 if (sah
->idents
== NULL
) {
7446 ipseclog((LOG_DEBUG
, "key_setident: No more memory.\n"));
7450 KMALLOC_NOWAIT(sah
->identd
, struct sadb_ident
*, iddstlen
);
7451 if (sah
->identd
== NULL
) {
7452 lck_mtx_unlock(sadb_mutex
);
7453 KMALLOC_WAIT(sah
->identd
, struct sadb_ident
*, iddstlen
);
7454 lck_mtx_lock(sadb_mutex
);
7455 if (sah
->identd
== NULL
) {
7458 ipseclog((LOG_DEBUG
, "key_setident: No more memory.\n"));
7462 bcopy(idsrc
, sah
->idents
, idsrclen
);
7463 bcopy(iddst
, sah
->identd
, iddstlen
);
7469 * m will not be freed on return.
7470 * it is caller's responsibility to free the result.
7472 static struct mbuf
*
7475 const struct sadb_msghdr
*mhp
)
7478 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_EXT_SA
,
7479 SADB_X_EXT_SA2
, SADB_EXT_ADDRESS_SRC
,
7480 SADB_EXT_ADDRESS_DST
, SADB_EXT_LIFETIME_HARD
,
7481 SADB_EXT_LIFETIME_SOFT
, SADB_EXT_IDENTITY_SRC
,
7482 SADB_EXT_IDENTITY_DST
};
7485 if (m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
7486 panic("key_getmsgbuf_x1: NULL pointer is passed.\n");
7488 /* create new sadb_msg to reply. */
7489 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
7493 if (n
->m_len
< sizeof(struct sadb_msg
)) {
7494 n
= m_pullup(n
, sizeof(struct sadb_msg
));
7498 mtod(n
, struct sadb_msg
*)->sadb_msg_errno
= 0;
7499 mtod(n
, struct sadb_msg
*)->sadb_msg_len
=
7500 PFKEY_UNIT64(n
->m_pkthdr
.len
);
7505 static int key_delete_all(struct socket
*, struct mbuf
*,
7506 const struct sadb_msghdr
*, u_int16_t
);
7509 * SADB_DELETE processing
7511 * <base, SA(*), address(SD)>
7512 * from the ikmpd, and set SADB_SASTATE_DEAD,
7514 * <base, SA(*), address(SD)>
7517 * m will always be freed.
7523 const struct sadb_msghdr
*mhp
)
7525 struct sadb_sa
*sa0
;
7526 struct sadb_address
*src0
, *dst0
;
7527 ifnet_t ipsec_if
= NULL
;
7528 struct secasindex saidx
;
7529 struct secashead
*sah
;
7530 struct secasvar
*sav
= NULL
;
7533 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
7536 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
7537 panic("key_delete: NULL pointer is passed.\n");
7539 /* map satype to proto */
7540 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
7541 ipseclog((LOG_DEBUG
, "key_delete: invalid satype is passed.\n"));
7542 return key_senderror(so
, m
, EINVAL
);
7545 if (mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
7546 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
) {
7547 ipseclog((LOG_DEBUG
, "key_delete: invalid message is passed.\n"));
7548 return key_senderror(so
, m
, EINVAL
);
7551 if (mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
7552 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) {
7553 ipseclog((LOG_DEBUG
, "key_delete: invalid message is passed.\n"));
7554 return key_senderror(so
, m
, EINVAL
);
7557 lck_mtx_lock(sadb_mutex
);
7559 if (mhp
->ext
[SADB_EXT_SA
] == NULL
) {
7561 * Caller wants us to delete all non-LARVAL SAs
7562 * that match the src/dst. This is used during
7563 * IKE INITIAL-CONTACT.
7565 ipseclog((LOG_DEBUG
, "key_delete: doing delete all.\n"));
7566 /* key_delete_all will unlock sadb_mutex */
7567 return key_delete_all(so
, m
, mhp
, proto
);
7568 } else if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(struct sadb_sa
)) {
7569 lck_mtx_unlock(sadb_mutex
);
7570 ipseclog((LOG_DEBUG
, "key_delete: invalid message is passed.\n"));
7571 return key_senderror(so
, m
, EINVAL
);
7574 sa0
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
7575 src0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_SRC
]);
7576 dst0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_DST
]);
7577 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
7579 /* XXX boundary check against sa_len */
7580 KEY_SETSECASIDX(proto
, IPSEC_MODE_ANY
, 0, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
7582 /* get a SA header */
7583 LIST_FOREACH(sah
, &sahtree
, chain
) {
7584 if (sah
->state
== SADB_SASTATE_DEAD
)
7586 if (key_cmpsaidx(&sah
->saidx
, &saidx
, CMP_HEAD
) == 0)
7589 /* get a SA with SPI. */
7590 sav
= key_getsavbyspi(sah
, sa0
->sadb_sa_spi
);
7595 lck_mtx_unlock(sadb_mutex
);
7596 ipseclog((LOG_DEBUG
, "key_delete: no SA found.\n"));
7597 return key_senderror(so
, m
, ENOENT
);
7600 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
7601 key_freesav(sav
, KEY_SADB_LOCKED
);
7603 lck_mtx_unlock(sadb_mutex
);
7608 struct sadb_msg
*newmsg
;
7609 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_EXT_SA
,
7610 SADB_EXT_ADDRESS_SRC
, SADB_EXT_ADDRESS_DST
};
7612 /* create new sadb_msg to reply. */
7613 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
7615 return key_senderror(so
, m
, ENOBUFS
);
7617 if (n
->m_len
< sizeof(struct sadb_msg
)) {
7618 n
= m_pullup(n
, sizeof(struct sadb_msg
));
7620 return key_senderror(so
, m
, ENOBUFS
);
7622 newmsg
= mtod(n
, struct sadb_msg
*);
7623 newmsg
->sadb_msg_errno
= 0;
7624 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
7627 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
7632 * delete all SAs for src/dst. Called from key_delete().
7638 const struct sadb_msghdr
*mhp
,
7641 struct sadb_address
*src0
, *dst0
;
7642 ifnet_t ipsec_if
= NULL
;
7643 struct secasindex saidx
;
7644 struct secashead
*sah
;
7645 struct secasvar
*sav
, *nextsav
;
7646 u_int stateidx
, state
;
7648 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
7650 src0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_SRC
]);
7651 dst0
= (struct sadb_address
*)(mhp
->ext
[SADB_EXT_ADDRESS_DST
]);
7652 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
7654 /* XXX boundary check against sa_len */
7655 KEY_SETSECASIDX(proto
, IPSEC_MODE_ANY
, 0, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
7657 LIST_FOREACH(sah
, &sahtree
, chain
) {
7658 if (sah
->state
== SADB_SASTATE_DEAD
)
7660 if (key_cmpsaidx(&sah
->saidx
, &saidx
, CMP_HEAD
) == 0)
7663 /* Delete all non-LARVAL SAs. */
7665 stateidx
< _ARRAYLEN(saorder_state_alive
);
7667 state
= saorder_state_alive
[stateidx
];
7668 if (state
== SADB_SASTATE_LARVAL
)
7670 for (sav
= LIST_FIRST(&sah
->savtree
[state
]);
7671 sav
!= NULL
; sav
= nextsav
) {
7672 nextsav
= LIST_NEXT(sav
, chain
);
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
));
7682 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
7683 key_freesav(sav
, KEY_SADB_LOCKED
);
7687 lck_mtx_unlock(sadb_mutex
);
7691 struct sadb_msg
*newmsg
;
7692 int mbufItems
[] = {SADB_EXT_RESERVED
, SADB_EXT_ADDRESS_SRC
,
7693 SADB_EXT_ADDRESS_DST
};
7695 /* create new sadb_msg to reply. */
7696 n
= key_gather_mbuf(m
, mhp
, 1, sizeof(mbufItems
)/sizeof(int), mbufItems
);
7698 return key_senderror(so
, m
, ENOBUFS
);
7700 if (n
->m_len
< sizeof(struct sadb_msg
)) {
7701 n
= m_pullup(n
, sizeof(struct sadb_msg
));
7703 return key_senderror(so
, m
, ENOBUFS
);
7705 newmsg
= mtod(n
, struct sadb_msg
*);
7706 newmsg
->sadb_msg_errno
= 0;
7707 newmsg
->sadb_msg_len
= PFKEY_UNIT64(n
->m_pkthdr
.len
);
7710 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
7715 * SADB_GET processing
7717 * <base, SA(*), address(SD)>
7718 * from the ikmpd, and get a SP and a SA to respond,
7720 * <base, SA, (lifetime(HSC),) address(SD), (address(P),) key(AE),
7721 * (identity(SD),) (sensitivity)>
7724 * m will always be freed.
7730 const struct sadb_msghdr
*mhp
)
7732 struct sadb_sa
*sa0
;
7733 struct sadb_address
*src0
, *dst0
;
7734 ifnet_t ipsec_if
= NULL
;
7735 struct secasindex saidx
;
7736 struct secashead
*sah
;
7737 struct secasvar
*sav
= NULL
;
7740 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
7743 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
7744 panic("key_get: NULL pointer is passed.\n");
7746 /* map satype to proto */
7747 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
7748 ipseclog((LOG_DEBUG
, "key_get: invalid satype is passed.\n"));
7749 return key_senderror(so
, m
, EINVAL
);
7752 if (mhp
->ext
[SADB_EXT_SA
] == NULL
||
7753 mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
7754 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
) {
7755 ipseclog((LOG_DEBUG
, "key_get: invalid message is passed.\n"));
7756 return key_senderror(so
, m
, EINVAL
);
7758 if (mhp
->extlen
[SADB_EXT_SA
] < sizeof(struct sadb_sa
) ||
7759 mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
7760 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
)) {
7761 ipseclog((LOG_DEBUG
, "key_get: invalid message is passed.\n"));
7762 return key_senderror(so
, m
, EINVAL
);
7765 sa0
= (struct sadb_sa
*)(void *)mhp
->ext
[SADB_EXT_SA
];
7766 src0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_SRC
];
7767 dst0
= (struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_DST
];
7768 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
7770 /* XXX boundary check against sa_len */
7771 KEY_SETSECASIDX(proto
, IPSEC_MODE_ANY
, 0, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
7773 lck_mtx_lock(sadb_mutex
);
7775 /* get a SA header */
7776 LIST_FOREACH(sah
, &sahtree
, chain
) {
7777 if (sah
->state
== SADB_SASTATE_DEAD
)
7779 if (key_cmpsaidx(&sah
->saidx
, &saidx
, CMP_HEAD
) == 0)
7782 /* get a SA with SPI. */
7783 sav
= key_getsavbyspi(sah
, sa0
->sadb_sa_spi
);
7788 lck_mtx_unlock(sadb_mutex
);
7789 ipseclog((LOG_DEBUG
, "key_get: no SA found.\n"));
7790 return key_senderror(so
, m
, ENOENT
);
7797 /* map proto to satype */
7798 if ((satype
= key_proto2satype(sah
->saidx
.proto
)) == 0) {
7799 lck_mtx_unlock(sadb_mutex
);
7800 ipseclog((LOG_DEBUG
, "key_get: there was invalid proto in SAD.\n"));
7801 return key_senderror(so
, m
, EINVAL
);
7803 lck_mtx_unlock(sadb_mutex
);
7805 /* create new sadb_msg to reply. */
7806 n
= key_setdumpsa(sav
, SADB_GET
, satype
, mhp
->msg
->sadb_msg_seq
,
7807 mhp
->msg
->sadb_msg_pid
);
7812 return key_senderror(so
, m
, ENOBUFS
);
7815 return key_sendup_mbuf(so
, n
, KEY_SENDUP_ONE
);
7820 * get SA stats by spi.
7821 * OUT: -1 : not found
7822 * 0 : found, arg pointer to a SA stats is updated.
7825 key_getsastatbyspi_one (u_int32_t spi
,
7826 struct sastat
*stat
)
7828 struct secashead
*sah
;
7829 struct secasvar
*sav
= NULL
;
7831 if ((void *)stat
== NULL
) {
7835 lck_mtx_lock(sadb_mutex
);
7837 /* get a SA header */
7838 LIST_FOREACH(sah
, &sahtree
, chain
) {
7839 if (sah
->state
== SADB_SASTATE_DEAD
)
7842 /* get a SA with SPI. */
7843 sav
= key_getsavbyspi(sah
, spi
);
7845 stat
->spi
= sav
->spi
;
7846 stat
->created
= sav
->created
;
7848 bcopy(sav
->lft_c
,&stat
->lft_c
, sizeof(stat
->lft_c
));
7850 bzero(&stat
->lft_c
, sizeof(stat
->lft_c
));
7852 lck_mtx_unlock(sadb_mutex
);
7857 lck_mtx_unlock(sadb_mutex
);
7863 * get SA stats collection by indices.
7864 * OUT: -1 : not found
7865 * 0 : found, arg pointers to a SA stats and 'maximum stats' are updated.
7868 key_getsastatbyspi (struct sastat
*stat_arg
,
7869 u_int32_t max_stat_arg
,
7870 struct sastat
*stat_res
,
7871 u_int32_t
*max_stat_res
)
7875 if (stat_arg
== NULL
||
7877 max_stat_res
== NULL
) {
7881 for (cur
= 0; cur
< max_stat_arg
; cur
++) {
7882 if (key_getsastatbyspi_one(stat_arg
[cur
].spi
,
7883 &stat_res
[found
]) == 0) {
7887 *max_stat_res
= found
;
7895 /* XXX make it sysctl-configurable? */
7897 key_getcomb_setlifetime(
7898 struct sadb_comb
*comb
)
7901 comb
->sadb_comb_soft_allocations
= 1;
7902 comb
->sadb_comb_hard_allocations
= 1;
7903 comb
->sadb_comb_soft_bytes
= 0;
7904 comb
->sadb_comb_hard_bytes
= 0;
7905 comb
->sadb_comb_hard_addtime
= 86400; /* 1 day */
7906 comb
->sadb_comb_soft_addtime
= comb
->sadb_comb_soft_addtime
* 80 / 100;
7907 comb
->sadb_comb_soft_usetime
= 28800; /* 8 hours */
7908 comb
->sadb_comb_hard_usetime
= comb
->sadb_comb_hard_usetime
* 80 / 100;
7913 * XXX reorder combinations by preference
7914 * XXX no idea if the user wants ESP authentication or not
7916 static struct mbuf
*
7917 key_getcomb_esp(void)
7919 struct sadb_comb
*comb
;
7920 const struct esp_algorithm
*algo
;
7921 struct mbuf
*result
= NULL
, *m
, *n
;
7925 const int l
= PFKEY_ALIGN8(sizeof(struct sadb_comb
));
7928 for (i
= 1; i
<= SADB_EALG_MAX
; i
++) {
7929 algo
= esp_algorithm_lookup(i
);
7933 if (algo
->keymax
< ipsec_esp_keymin
)
7935 if (algo
->keymin
< ipsec_esp_keymin
)
7936 encmin
= ipsec_esp_keymin
;
7938 encmin
= algo
->keymin
;
7941 m
= key_getcomb_ah();
7945 panic("assumption failed in key_getcomb_esp");
7947 MGET(m
, M_WAITOK
, MT_DATA
);
7952 bzero(mtod(m
, caddr_t
), m
->m_len
);
7959 for (n
= m
; n
; n
= n
->m_next
)
7963 panic("assumption failed in key_getcomb_esp");
7966 for (off
= 0; off
< totlen
; off
+= l
) {
7967 n
= m_pulldown(m
, off
, l
, &o
);
7969 /* m is already freed */
7972 comb
= (struct sadb_comb
*)
7973 (void *)(mtod(n
, caddr_t
) + o
);
7974 bzero(comb
, sizeof(*comb
));
7975 key_getcomb_setlifetime(comb
);
7976 comb
->sadb_comb_encrypt
= i
;
7977 comb
->sadb_comb_encrypt_minbits
= encmin
;
7978 comb
->sadb_comb_encrypt_maxbits
= algo
->keymax
;
7997 * XXX reorder combinations by preference
7999 static struct mbuf
*
8000 key_getcomb_ah(void)
8002 struct sadb_comb
*comb
;
8003 const struct ah_algorithm
*algo
;
8007 const int l
= PFKEY_ALIGN8(sizeof(struct sadb_comb
));
8010 for (i
= 1; i
<= SADB_AALG_MAX
; i
++) {
8012 /* we prefer HMAC algorithms, not old algorithms */
8013 if (i
!= SADB_AALG_SHA1HMAC
&& i
!= SADB_AALG_MD5HMAC
)
8016 algo
= ah_algorithm_lookup(i
);
8020 if (algo
->keymax
< ipsec_ah_keymin
)
8022 if (algo
->keymin
< ipsec_ah_keymin
)
8023 keymin
= ipsec_ah_keymin
;
8025 keymin
= algo
->keymin
;
8030 panic("assumption failed in key_getcomb_ah");
8032 MGET(m
, M_WAITOK
, MT_DATA
);
8039 M_PREPEND(m
, l
, M_WAITOK
, 1);
8043 comb
= mtod(m
, struct sadb_comb
*);
8044 bzero(comb
, sizeof(*comb
));
8045 key_getcomb_setlifetime(comb
);
8046 comb
->sadb_comb_auth
= i
;
8047 comb
->sadb_comb_auth_minbits
= keymin
;
8048 comb
->sadb_comb_auth_maxbits
= algo
->keymax
;
8055 * not really an official behavior. discussed in pf_key@inner.net in Sep2000.
8056 * XXX reorder combinations by preference
8058 static struct mbuf
*
8059 key_getcomb_ipcomp(void)
8061 struct sadb_comb
*comb
;
8062 const struct ipcomp_algorithm
*algo
;
8065 const int l
= PFKEY_ALIGN8(sizeof(struct sadb_comb
));
8068 for (i
= 1; i
<= SADB_X_CALG_MAX
; i
++) {
8069 algo
= ipcomp_algorithm_lookup(i
);
8076 panic("assumption failed in key_getcomb_ipcomp");
8078 MGET(m
, M_WAITOK
, MT_DATA
);
8085 M_PREPEND(m
, l
, M_WAITOK
, 1);
8089 comb
= mtod(m
, struct sadb_comb
*);
8090 bzero(comb
, sizeof(*comb
));
8091 key_getcomb_setlifetime(comb
);
8092 comb
->sadb_comb_encrypt
= i
;
8093 /* what should we set into sadb_comb_*_{min,max}bits? */
8100 * XXX no way to pass mode (transport/tunnel) to userland
8101 * XXX replay checking?
8102 * XXX sysctl interface to ipsec_{ah,esp}_keymin
8104 static struct mbuf
*
8106 const struct secasindex
*saidx
)
8108 struct sadb_prop
*prop
;
8110 const int l
= PFKEY_ALIGN8(sizeof(struct sadb_prop
));
8113 switch (saidx
->proto
) {
8116 m
= key_getcomb_esp();
8120 m
= key_getcomb_ah();
8122 case IPPROTO_IPCOMP
:
8123 m
= key_getcomb_ipcomp();
8131 M_PREPEND(m
, l
, M_WAITOK
, 1);
8136 for (n
= m
; n
; n
= n
->m_next
)
8139 prop
= mtod(m
, struct sadb_prop
*);
8140 bzero(prop
, sizeof(*prop
));
8141 prop
->sadb_prop_len
= PFKEY_UNIT64(totlen
);
8142 prop
->sadb_prop_exttype
= SADB_EXT_PROPOSAL
;
8143 prop
->sadb_prop_replay
= 32; /* XXX */
8149 * SADB_ACQUIRE processing called by key_checkrequest() and key_acquire2().
8151 * <base, SA, address(SD), (address(P)), x_policy,
8152 * (identity(SD),) (sensitivity,) proposal>
8153 * to KMD, and expect to receive
8154 * <base> with SADB_ACQUIRE if error occurred,
8156 * <base, src address, dst address, (SPI range)> with SADB_GETSPI
8157 * from KMD by PF_KEY.
8159 * XXX x_policy is outside of RFC2367 (KAME extension).
8160 * XXX sensitivity is not supported.
8161 * XXX for ipcomp, RFC2367 does not define how to fill in proposal.
8162 * see comment for key_getcomb_ipcomp().
8166 * others: error number
8170 struct secasindex
*saidx
,
8171 struct secpolicy
*sp
)
8173 struct mbuf
*result
= NULL
, *m
;
8174 #ifndef IPSEC_NONBLOCK_ACQUIRE
8175 struct secacq
*newacq
;
8181 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
8185 panic("key_acquire: NULL pointer is passed.\n");
8186 if ((satype
= key_proto2satype(saidx
->proto
)) == 0)
8187 panic("key_acquire: invalid proto is passed.\n");
8189 #ifndef IPSEC_NONBLOCK_ACQUIRE
8191 * We never do anything about acquirng SA. There is anather
8192 * solution that kernel blocks to send SADB_ACQUIRE message until
8193 * getting something message from IKEd. In later case, to be
8194 * managed with ACQUIRING list.
8196 /* get a entry to check whether sending message or not. */
8197 lck_mtx_lock(sadb_mutex
);
8198 if ((newacq
= key_getacq(saidx
)) != NULL
) {
8199 if (key_blockacq_count
< newacq
->count
) {
8200 /* reset counter and do send message. */
8203 /* increment counter and do nothing. */
8205 lck_mtx_unlock(sadb_mutex
);
8209 /* make new entry for blocking to send SADB_ACQUIRE. */
8210 if ((newacq
= key_newacq(saidx
)) == NULL
) {
8211 lck_mtx_unlock(sadb_mutex
);
8215 /* add to acqtree */
8216 LIST_INSERT_HEAD(&acqtree
, newacq
, chain
);
8217 key_start_timehandler();
8220 lck_mtx_unlock(sadb_mutex
);
8223 seq
= (acq_seq
= (acq_seq
== ~0 ? 1 : ++acq_seq
));
8225 m
= key_setsadbmsg(SADB_ACQUIRE
, 0, satype
, seq
, 0, 0);
8232 /* set sadb_address for saidx's. */
8233 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
8234 (struct sockaddr
*)&saidx
->src
, FULLMASK
, IPSEC_ULPROTO_ANY
);
8241 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
8242 (struct sockaddr
*)&saidx
->dst
, FULLMASK
, IPSEC_ULPROTO_ANY
);
8249 /* XXX proxy address (optional) */
8251 /* set sadb_x_policy */
8253 m
= key_setsadbxpolicy(sp
->policy
, sp
->spidx
.dir
, sp
->id
);
8261 /* XXX identity (optional) */
8263 if (idexttype
&& fqdn
) {
8264 /* create identity extension (FQDN) */
8265 struct sadb_ident
*id
;
8268 fqdnlen
= strlen(fqdn
) + 1; /* +1 for terminating-NUL */
8269 id
= (struct sadb_ident
*)p
;
8270 bzero(id
, sizeof(*id
) + PFKEY_ALIGN8(fqdnlen
));
8271 id
->sadb_ident_len
= PFKEY_UNIT64(sizeof(*id
) + PFKEY_ALIGN8(fqdnlen
));
8272 id
->sadb_ident_exttype
= idexttype
;
8273 id
->sadb_ident_type
= SADB_IDENTTYPE_FQDN
;
8274 bcopy(fqdn
, id
+ 1, fqdnlen
);
8275 p
+= sizeof(struct sadb_ident
) + PFKEY_ALIGN8(fqdnlen
);
8279 /* create identity extension (USERFQDN) */
8280 struct sadb_ident
*id
;
8284 /* +1 for terminating-NUL */
8285 userfqdnlen
= strlen(userfqdn
) + 1;
8288 id
= (struct sadb_ident
*)p
;
8289 bzero(id
, sizeof(*id
) + PFKEY_ALIGN8(userfqdnlen
));
8290 id
->sadb_ident_len
= PFKEY_UNIT64(sizeof(*id
) + PFKEY_ALIGN8(userfqdnlen
));
8291 id
->sadb_ident_exttype
= idexttype
;
8292 id
->sadb_ident_type
= SADB_IDENTTYPE_USERFQDN
;
8293 /* XXX is it correct? */
8294 if (curproc
&& curproc
->p_cred
)
8295 id
->sadb_ident_id
= curproc
->p_cred
->p_ruid
;
8296 if (userfqdn
&& userfqdnlen
)
8297 bcopy(userfqdn
, id
+ 1, userfqdnlen
);
8298 p
+= sizeof(struct sadb_ident
) + PFKEY_ALIGN8(userfqdnlen
);
8302 /* XXX sensitivity (optional) */
8304 /* create proposal/combination extension */
8305 m
= key_getprop(saidx
);
8308 * spec conformant: always attach proposal/combination extension,
8309 * the problem is that we have no way to attach it for ipcomp,
8310 * due to the way sadb_comb is declared in RFC2367.
8319 * outside of spec; make proposal/combination extension optional.
8325 if ((result
->m_flags
& M_PKTHDR
) == 0) {
8330 if (result
->m_len
< sizeof(struct sadb_msg
)) {
8331 result
= m_pullup(result
, sizeof(struct sadb_msg
));
8332 if (result
== NULL
) {
8338 result
->m_pkthdr
.len
= 0;
8339 for (m
= result
; m
; m
= m
->m_next
)
8340 result
->m_pkthdr
.len
+= m
->m_len
;
8342 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
8343 PFKEY_UNIT64(result
->m_pkthdr
.len
);
8345 return key_sendup_mbuf(NULL
, result
, KEY_SENDUP_REGISTERED
);
8353 #ifndef IPSEC_NONBLOCK_ACQUIRE
8354 static struct secacq
*
8356 struct secasindex
*saidx
)
8358 struct secacq
*newacq
;
8362 KMALLOC_NOWAIT(newacq
, struct secacq
*, sizeof(struct secacq
));
8363 if (newacq
== NULL
) {
8364 lck_mtx_unlock(sadb_mutex
);
8365 KMALLOC_WAIT(newacq
, struct secacq
*, sizeof(struct secacq
));
8366 lck_mtx_lock(sadb_mutex
);
8367 if (newacq
== NULL
) {
8368 ipseclog((LOG_DEBUG
, "key_newacq: No more memory.\n"));
8372 bzero(newacq
, sizeof(*newacq
));
8375 bcopy(saidx
, &newacq
->saidx
, sizeof(newacq
->saidx
));
8376 newacq
->seq
= (acq_seq
== ~0 ? 1 : ++acq_seq
);
8378 newacq
->created
= tv
.tv_sec
;
8384 static struct secacq
*
8386 struct secasindex
*saidx
)
8390 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
8392 LIST_FOREACH(acq
, &acqtree
, chain
) {
8393 if (key_cmpsaidx(saidx
, &acq
->saidx
, CMP_EXACTLY
))
8400 static struct secacq
*
8406 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
8408 LIST_FOREACH(acq
, &acqtree
, chain
) {
8409 if (acq
->seq
== seq
)
8417 static struct secspacq
*
8419 struct secpolicyindex
*spidx
)
8421 struct secspacq
*acq
;
8425 KMALLOC_NOWAIT(acq
, struct secspacq
*, sizeof(struct secspacq
));
8427 lck_mtx_unlock(sadb_mutex
);
8428 KMALLOC_WAIT(acq
, struct secspacq
*, sizeof(struct secspacq
));
8429 lck_mtx_lock(sadb_mutex
);
8431 ipseclog((LOG_DEBUG
, "key_newspacq: No more memory.\n"));
8435 bzero(acq
, sizeof(*acq
));
8438 bcopy(spidx
, &acq
->spidx
, sizeof(acq
->spidx
));
8440 acq
->created
= tv
.tv_sec
;
8446 static struct secspacq
*
8448 struct secpolicyindex
*spidx
)
8450 struct secspacq
*acq
;
8452 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
8454 LIST_FOREACH(acq
, &spacqtree
, chain
) {
8455 if (key_cmpspidx_exactly(spidx
, &acq
->spidx
))
8463 * SADB_ACQUIRE processing,
8464 * in first situation, is receiving
8466 * from the ikmpd, and clear sequence of its secasvar entry.
8468 * In second situation, is receiving
8469 * <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal>
8470 * from a user land process, and return
8471 * <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal>
8474 * m will always be freed.
8480 const struct sadb_msghdr
*mhp
)
8482 const struct sadb_address
*src0
, *dst0
;
8483 ifnet_t ipsec_if
= NULL
;
8484 struct secasindex saidx
;
8485 struct secashead
*sah
;
8491 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
8492 panic("key_acquire2: NULL pointer is passed.\n");
8495 * Error message from KMd.
8496 * We assume that if error was occurred in IKEd, the length of PFKEY
8497 * message is equal to the size of sadb_msg structure.
8498 * We do not raise error even if error occurred in this function.
8500 lck_mtx_lock(sadb_mutex
);
8502 if (mhp
->msg
->sadb_msg_len
== PFKEY_UNIT64(sizeof(struct sadb_msg
))) {
8503 #ifndef IPSEC_NONBLOCK_ACQUIRE
8507 /* check sequence number */
8508 if (mhp
->msg
->sadb_msg_seq
== 0) {
8509 lck_mtx_unlock(sadb_mutex
);
8510 ipseclog((LOG_DEBUG
, "key_acquire2: must specify sequence number.\n"));
8515 if ((acq
= key_getacqbyseq(mhp
->msg
->sadb_msg_seq
)) == NULL
) {
8517 * the specified larval SA is already gone, or we got
8518 * a bogus sequence number. we can silently ignore it.
8520 lck_mtx_unlock(sadb_mutex
);
8525 /* reset acq counter in order to deletion by timehander. */
8527 acq
->created
= tv
.tv_sec
;
8530 lck_mtx_unlock(sadb_mutex
);
8536 * This message is from user land.
8539 /* map satype to proto */
8540 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
8541 lck_mtx_unlock(sadb_mutex
);
8542 ipseclog((LOG_DEBUG
, "key_acquire2: invalid satype is passed.\n"));
8543 return key_senderror(so
, m
, EINVAL
);
8546 if (mhp
->ext
[SADB_EXT_ADDRESS_SRC
] == NULL
||
8547 mhp
->ext
[SADB_EXT_ADDRESS_DST
] == NULL
||
8548 mhp
->ext
[SADB_EXT_PROPOSAL
] == NULL
) {
8550 lck_mtx_unlock(sadb_mutex
);
8551 ipseclog((LOG_DEBUG
, "key_acquire2: invalid message is passed.\n"));
8552 return key_senderror(so
, m
, EINVAL
);
8554 if (mhp
->extlen
[SADB_EXT_ADDRESS_SRC
] < sizeof(struct sadb_address
) ||
8555 mhp
->extlen
[SADB_EXT_ADDRESS_DST
] < sizeof(struct sadb_address
) ||
8556 mhp
->extlen
[SADB_EXT_PROPOSAL
] < sizeof(struct sadb_prop
)) {
8558 lck_mtx_unlock(sadb_mutex
);
8559 ipseclog((LOG_DEBUG
, "key_acquire2: invalid message is passed.\n"));
8560 return key_senderror(so
, m
, EINVAL
);
8563 src0
= (const struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_SRC
];
8564 dst0
= (const struct sadb_address
*)mhp
->ext
[SADB_EXT_ADDRESS_DST
];
8565 ipsec_if
= key_get_ipsec_if_from_message(mhp
, SADB_X_EXT_IPSECIF
);
8567 /* XXX boundary check against sa_len */
8569 KEY_SETSECASIDX(proto
, IPSEC_MODE_ANY
, 0, src0
+ 1, dst0
+ 1, ipsec_if
? ipsec_if
->if_index
: 0, &saidx
);
8571 /* get a SA index */
8572 LIST_FOREACH(sah
, &sahtree
, chain
) {
8573 if (sah
->state
== SADB_SASTATE_DEAD
)
8575 if (key_cmpsaidx(&sah
->saidx
, &saidx
, CMP_MODE
| CMP_REQID
))
8579 lck_mtx_unlock(sadb_mutex
);
8580 ipseclog((LOG_DEBUG
, "key_acquire2: a SA exists already.\n"));
8581 return key_senderror(so
, m
, EEXIST
);
8583 lck_mtx_unlock(sadb_mutex
);
8584 error
= key_acquire(&saidx
, NULL
);
8586 ipseclog((LOG_DEBUG
, "key_acquire2: error %d returned "
8587 "from key_acquire.\n", mhp
->msg
->sadb_msg_errno
));
8588 return key_senderror(so
, m
, error
);
8591 return key_sendup_mbuf(so
, m
, KEY_SENDUP_REGISTERED
);
8595 * SADB_REGISTER processing.
8596 * If SATYPE_UNSPEC has been passed as satype, only return sadb_supported.
8599 * from the ikmpd, and register a socket to send PF_KEY messages,
8603 * If socket is detached, must free from regnode.
8605 * m will always be freed.
8611 const struct sadb_msghdr
*mhp
)
8613 struct secreg
*reg
, *newreg
= 0;
8616 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
8617 panic("key_register: NULL pointer is passed.\n");
8619 /* check for invalid register message */
8620 if (mhp
->msg
->sadb_msg_satype
>= sizeof(regtree
)/sizeof(regtree
[0]))
8621 return key_senderror(so
, m
, EINVAL
);
8623 /* When SATYPE_UNSPEC is specified, only return sadb_supported. */
8624 if (mhp
->msg
->sadb_msg_satype
== SADB_SATYPE_UNSPEC
)
8627 /* create regnode */
8628 KMALLOC_WAIT(newreg
, struct secreg
*, sizeof(*newreg
));
8629 if (newreg
== NULL
) {
8630 ipseclog((LOG_DEBUG
, "key_register: No more memory.\n"));
8631 return key_senderror(so
, m
, ENOBUFS
);
8633 bzero((caddr_t
)newreg
, sizeof(*newreg
));
8635 lck_mtx_lock(sadb_mutex
);
8636 /* check whether existing or not */
8637 LIST_FOREACH(reg
, ®tree
[mhp
->msg
->sadb_msg_satype
], chain
) {
8638 if (reg
->so
== so
) {
8639 lck_mtx_unlock(sadb_mutex
);
8640 ipseclog((LOG_DEBUG
, "key_register: socket exists already.\n"));
8642 return key_senderror(so
, m
, EEXIST
);
8648 ((struct keycb
*)sotorawcb(so
))->kp_registered
++;
8649 socket_unlock(so
, 1);
8651 /* add regnode to regtree. */
8652 LIST_INSERT_HEAD(®tree
[mhp
->msg
->sadb_msg_satype
], newreg
, chain
);
8653 lck_mtx_unlock(sadb_mutex
);
8657 struct sadb_msg
*newmsg
;
8658 struct sadb_supported
*sup
;
8659 u_int len
, alen
, elen
;
8662 struct sadb_alg
*alg
;
8664 /* create new sadb_msg to reply. */
8666 for (i
= 1; i
<= SADB_AALG_MAX
; i
++) {
8667 if (ah_algorithm_lookup(i
))
8668 alen
+= sizeof(struct sadb_alg
);
8671 alen
+= sizeof(struct sadb_supported
);
8674 for (i
= 1; i
<= SADB_EALG_MAX
; i
++) {
8675 if (esp_algorithm_lookup(i
))
8676 elen
+= sizeof(struct sadb_alg
);
8679 elen
+= sizeof(struct sadb_supported
);
8682 len
= sizeof(struct sadb_msg
) + alen
+ elen
;
8685 return key_senderror(so
, m
, ENOBUFS
);
8687 MGETHDR(n
, M_WAITOK
, MT_DATA
);
8688 if (n
&& len
> MHLEN
) {
8689 MCLGET(n
, M_WAITOK
);
8690 if ((n
->m_flags
& M_EXT
) == 0) {
8696 return key_senderror(so
, m
, ENOBUFS
);
8698 n
->m_pkthdr
.len
= n
->m_len
= len
;
8702 m_copydata(m
, 0, sizeof(struct sadb_msg
), mtod(n
, caddr_t
) + off
);
8703 newmsg
= mtod(n
, struct sadb_msg
*);
8704 newmsg
->sadb_msg_errno
= 0;
8705 newmsg
->sadb_msg_len
= PFKEY_UNIT64(len
);
8706 off
+= PFKEY_ALIGN8(sizeof(struct sadb_msg
));
8708 /* for authentication algorithm */
8710 sup
= (struct sadb_supported
*)(void *)(mtod(n
, caddr_t
) + off
);
8711 sup
->sadb_supported_len
= PFKEY_UNIT64(alen
);
8712 sup
->sadb_supported_exttype
= SADB_EXT_SUPPORTED_AUTH
;
8713 off
+= PFKEY_ALIGN8(sizeof(*sup
));
8715 for (i
= 1; i
<= SADB_AALG_MAX
; i
++) {
8716 const struct ah_algorithm
*aalgo
;
8718 aalgo
= ah_algorithm_lookup(i
);
8721 alg
= (struct sadb_alg
*)
8722 (void *)(mtod(n
, caddr_t
) + off
);
8723 alg
->sadb_alg_id
= i
;
8724 alg
->sadb_alg_ivlen
= 0;
8725 alg
->sadb_alg_minbits
= aalgo
->keymin
;
8726 alg
->sadb_alg_maxbits
= aalgo
->keymax
;
8727 off
+= PFKEY_ALIGN8(sizeof(*alg
));
8732 /* for encryption algorithm */
8734 sup
= (struct sadb_supported
*)(void *)(mtod(n
, caddr_t
) + off
);
8735 sup
->sadb_supported_len
= PFKEY_UNIT64(elen
);
8736 sup
->sadb_supported_exttype
= SADB_EXT_SUPPORTED_ENCRYPT
;
8737 off
+= PFKEY_ALIGN8(sizeof(*sup
));
8739 for (i
= 1; i
<= SADB_EALG_MAX
; i
++) {
8740 const struct esp_algorithm
*ealgo
;
8742 ealgo
= esp_algorithm_lookup(i
);
8745 alg
= (struct sadb_alg
*)
8746 (void *)(mtod(n
, caddr_t
) + off
);
8747 alg
->sadb_alg_id
= i
;
8748 if (ealgo
&& ealgo
->ivlen
) {
8750 * give NULL to get the value preferred by
8751 * algorithm XXX SADB_X_EXT_DERIV ?
8753 alg
->sadb_alg_ivlen
=
8754 (*ealgo
->ivlen
)(ealgo
, NULL
);
8756 alg
->sadb_alg_ivlen
= 0;
8757 alg
->sadb_alg_minbits
= ealgo
->keymin
;
8758 alg
->sadb_alg_maxbits
= ealgo
->keymax
;
8759 off
+= PFKEY_ALIGN8(sizeof(struct sadb_alg
));
8766 panic("length assumption failed in key_register");
8770 return key_sendup_mbuf(so
, n
, KEY_SENDUP_REGISTERED
);
8775 key_delete_all_for_socket (struct socket
*so
)
8777 struct secashead
*sah
, *nextsah
;
8778 struct secasvar
*sav
, *nextsav
;
8782 for (sah
= LIST_FIRST(&sahtree
);
8785 nextsah
= LIST_NEXT(sah
, chain
);
8786 for (stateidx
= 0; stateidx
< _ARRAYLEN(saorder_state_alive
); stateidx
++) {
8787 state
= saorder_state_any
[stateidx
];
8788 for (sav
= LIST_FIRST(&sah
->savtree
[state
]); sav
!= NULL
; sav
= nextsav
) {
8789 nextsav
= LIST_NEXT(sav
, chain
);
8790 if (sav
->flags2
& SADB_X_EXT_SA2_DELETE_ON_DETACH
&&
8792 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
8793 key_freesav(sav
, KEY_SADB_LOCKED
);
8801 * free secreg entry registered.
8802 * XXX: I want to do free a socket marked done SADB_RESIGER to socket.
8813 panic("key_freereg: NULL pointer is passed.\n");
8816 * check whether existing or not.
8817 * check all type of SA, because there is a potential that
8818 * one socket is registered to multiple type of SA.
8820 lck_mtx_lock(sadb_mutex
);
8821 key_delete_all_for_socket(so
);
8822 for (i
= 0; i
<= SADB_SATYPE_MAX
; i
++) {
8823 LIST_FOREACH(reg
, ®tree
[i
], chain
) {
8825 && __LIST_CHAINED(reg
)) {
8826 LIST_REMOVE(reg
, chain
);
8832 lck_mtx_unlock(sadb_mutex
);
8837 * SADB_EXPIRE processing
8839 * <base, SA, SA2, lifetime(C and one of HS), address(SD)>
8841 * NOTE: We send only soft lifetime extension.
8844 * others : error number
8848 struct secasvar
*sav
)
8851 struct mbuf
*result
= NULL
, *m
;
8854 struct sadb_lifetime
*lt
;
8856 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
8860 panic("key_expire: NULL pointer is passed.\n");
8861 if (sav
->sah
== NULL
)
8862 panic("key_expire: Why was SA index in SA NULL.\n");
8863 if ((satype
= key_proto2satype(sav
->sah
->saidx
.proto
)) == 0)
8864 panic("key_expire: invalid proto is passed.\n");
8866 /* set msg header */
8867 m
= key_setsadbmsg(SADB_EXPIRE
, 0, satype
, sav
->seq
, 0, sav
->refcnt
);
8874 /* create SA extension */
8875 m
= key_setsadbsa(sav
);
8882 /* create SA extension */
8883 m
= key_setsadbxsa2(sav
->sah
->saidx
.mode
,
8884 sav
->replay
? sav
->replay
->count
: 0,
8885 sav
->sah
->saidx
.reqid
,
8893 /* create lifetime extension (current and soft) */
8894 len
= PFKEY_ALIGN8(sizeof(*lt
)) * 2;
8895 m
= key_alloc_mbuf(len
);
8896 if (!m
|| m
->m_next
) { /*XXX*/
8902 bzero(mtod(m
, caddr_t
), len
);
8903 lt
= mtod(m
, struct sadb_lifetime
*);
8904 lt
->sadb_lifetime_len
= PFKEY_UNIT64(sizeof(struct sadb_lifetime
));
8905 lt
->sadb_lifetime_exttype
= SADB_EXT_LIFETIME_CURRENT
;
8906 lt
->sadb_lifetime_allocations
= sav
->lft_c
->sadb_lifetime_allocations
;
8907 lt
->sadb_lifetime_bytes
= sav
->lft_c
->sadb_lifetime_bytes
;
8908 lt
->sadb_lifetime_addtime
= sav
->lft_c
->sadb_lifetime_addtime
;
8909 lt
->sadb_lifetime_usetime
= sav
->lft_c
->sadb_lifetime_usetime
;
8910 lt
= (struct sadb_lifetime
*)(void *)(mtod(m
, caddr_t
) + len
/ 2);
8911 bcopy(sav
->lft_s
, lt
, sizeof(*lt
));
8914 /* set sadb_address for source */
8915 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
8916 (struct sockaddr
*)&sav
->sah
->saidx
.src
,
8917 FULLMASK
, IPSEC_ULPROTO_ANY
);
8924 /* set sadb_address for destination */
8925 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
8926 (struct sockaddr
*)&sav
->sah
->saidx
.dst
,
8927 FULLMASK
, IPSEC_ULPROTO_ANY
);
8934 if ((result
->m_flags
& M_PKTHDR
) == 0) {
8939 if (result
->m_len
< sizeof(struct sadb_msg
)) {
8940 result
= m_pullup(result
, sizeof(struct sadb_msg
));
8941 if (result
== NULL
) {
8947 result
->m_pkthdr
.len
= 0;
8948 for (m
= result
; m
; m
= m
->m_next
)
8949 result
->m_pkthdr
.len
+= m
->m_len
;
8951 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
8952 PFKEY_UNIT64(result
->m_pkthdr
.len
);
8954 return key_sendup_mbuf(NULL
, result
, KEY_SENDUP_REGISTERED
);
8963 * SADB_FLUSH processing
8966 * from the ikmpd, and free all entries in secastree.
8970 * NOTE: to do is only marking SADB_SASTATE_DEAD.
8972 * m will always be freed.
8978 const struct sadb_msghdr
*mhp
)
8980 struct sadb_msg
*newmsg
;
8981 struct secashead
*sah
, *nextsah
;
8982 struct secasvar
*sav
, *nextsav
;
8988 if (so
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
8989 panic("key_flush: NULL pointer is passed.\n");
8991 /* map satype to proto */
8992 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
8993 ipseclog((LOG_DEBUG
, "key_flush: invalid satype is passed.\n"));
8994 return key_senderror(so
, m
, EINVAL
);
8997 lck_mtx_lock(sadb_mutex
);
8999 /* no SATYPE specified, i.e. flushing all SA. */
9000 for (sah
= LIST_FIRST(&sahtree
);
9003 nextsah
= LIST_NEXT(sah
, chain
);
9005 if (mhp
->msg
->sadb_msg_satype
!= SADB_SATYPE_UNSPEC
9006 && proto
!= sah
->saidx
.proto
)
9010 stateidx
< _ARRAYLEN(saorder_state_alive
);
9012 state
= saorder_state_any
[stateidx
];
9013 for (sav
= LIST_FIRST(&sah
->savtree
[state
]);
9017 nextsav
= LIST_NEXT(sav
, chain
);
9019 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
9020 key_freesav(sav
, KEY_SADB_LOCKED
);
9024 sah
->state
= SADB_SASTATE_DEAD
;
9026 lck_mtx_unlock(sadb_mutex
);
9028 if (m
->m_len
< sizeof(struct sadb_msg
) ||
9029 sizeof(struct sadb_msg
) > m
->m_len
+ M_TRAILINGSPACE(m
)) {
9030 ipseclog((LOG_DEBUG
, "key_flush: No more memory.\n"));
9031 return key_senderror(so
, m
, ENOBUFS
);
9037 m
->m_pkthdr
.len
= m
->m_len
= sizeof(struct sadb_msg
);
9038 newmsg
= mtod(m
, struct sadb_msg
*);
9039 newmsg
->sadb_msg_errno
= 0;
9040 newmsg
->sadb_msg_len
= PFKEY_UNIT64(m
->m_pkthdr
.len
);
9042 return key_sendup_mbuf(so
, m
, KEY_SENDUP_ALL
);
9046 * SADB_DUMP processing
9047 * dump all entries including status of DEAD in SAD.
9050 * from the ikmpd, and dump all secasvar leaves
9055 * m will always be freed.
9058 struct sav_dump_elem
{
9059 struct secasvar
*sav
;
9067 const struct sadb_msghdr
*mhp
)
9069 struct secashead
*sah
;
9070 struct secasvar
*sav
;
9071 struct sav_dump_elem
*savbuf
= NULL
, *elem_ptr
;
9076 int cnt
= 0, cnt2
, bufcount
;
9080 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
9083 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
9084 panic("key_dump: NULL pointer is passed.\n");
9086 /* map satype to proto */
9087 if ((proto
= key_satype2proto(mhp
->msg
->sadb_msg_satype
)) == 0) {
9088 ipseclog((LOG_DEBUG
, "key_dump: invalid satype is passed.\n"));
9089 return key_senderror(so
, m
, EINVAL
);
9092 if ((bufcount
= ipsec_sav_count
) <= 0) {
9096 bufcount
+= 512; /* extra */
9097 KMALLOC_WAIT(savbuf
, struct sav_dump_elem
*, bufcount
* sizeof(struct sav_dump_elem
));
9098 if (savbuf
== NULL
) {
9099 ipseclog((LOG_DEBUG
, "key_dump: No more memory.\n"));
9104 /* count sav entries to be sent to the userland. */
9105 lck_mtx_lock(sadb_mutex
);
9107 LIST_FOREACH(sah
, &sahtree
, chain
) {
9108 if (mhp
->msg
->sadb_msg_satype
!= SADB_SATYPE_UNSPEC
9109 && proto
!= sah
->saidx
.proto
)
9112 /* map proto to satype */
9113 if ((satype
= key_proto2satype(sah
->saidx
.proto
)) == 0) {
9114 lck_mtx_unlock(sadb_mutex
);
9115 ipseclog((LOG_DEBUG
, "key_dump: there was invalid proto in SAD.\n"));
9121 stateidx
< _ARRAYLEN(saorder_state_any
);
9123 state
= saorder_state_any
[stateidx
];
9124 LIST_FOREACH(sav
, &sah
->savtree
[state
], chain
) {
9125 if (cnt
== bufcount
)
9126 break; /* out of buffer space */
9127 elem_ptr
->sav
= sav
;
9128 elem_ptr
->satype
= satype
;
9135 lck_mtx_unlock(sadb_mutex
);
9142 /* send this to the userland, one at a time. */
9146 n
= key_setdumpsa(elem_ptr
->sav
, SADB_DUMP
, elem_ptr
->satype
,
9147 --cnt2
, mhp
->msg
->sadb_msg_pid
);
9154 key_sendup_mbuf(so
, n
, KEY_SENDUP_ONE
);
9162 lck_mtx_lock(sadb_mutex
);
9164 key_freesav((elem_ptr
++)->sav
, KEY_SADB_LOCKED
);
9165 lck_mtx_unlock(sadb_mutex
);
9171 return key_senderror(so
, m
, error
);
9178 * SADB_X_PROMISC processing
9180 * m will always be freed.
9186 const struct sadb_msghdr
*mhp
)
9191 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
9192 panic("key_promisc: NULL pointer is passed.\n");
9194 olen
= PFKEY_UNUNIT64(mhp
->msg
->sadb_msg_len
);
9196 if (olen
< sizeof(struct sadb_msg
)) {
9198 return key_senderror(so
, m
, EINVAL
);
9203 } else if (olen
== sizeof(struct sadb_msg
)) {
9204 /* enable/disable promisc mode */
9208 if ((kp
= (struct keycb
*)sotorawcb(so
)) == NULL
)
9209 return key_senderror(so
, m
, EINVAL
);
9210 mhp
->msg
->sadb_msg_errno
= 0;
9211 switch (mhp
->msg
->sadb_msg_satype
) {
9214 kp
->kp_promisc
= mhp
->msg
->sadb_msg_satype
;
9217 socket_unlock(so
, 1);
9218 return key_senderror(so
, m
, EINVAL
);
9220 socket_unlock(so
, 1);
9222 /* send the original message back to everyone */
9223 mhp
->msg
->sadb_msg_errno
= 0;
9224 return key_sendup_mbuf(so
, m
, KEY_SENDUP_ALL
);
9226 /* send packet as is */
9228 m_adj(m
, PFKEY_ALIGN8(sizeof(struct sadb_msg
)));
9230 /* TODO: if sadb_msg_seq is specified, send to specific pid */
9231 return key_sendup_mbuf(so
, m
, KEY_SENDUP_ALL
);
9235 static int (*key_typesw
[])(struct socket
*, struct mbuf
*,
9236 const struct sadb_msghdr
*) = {
9237 NULL
, /* SADB_RESERVED */
9238 key_getspi
, /* SADB_GETSPI */
9239 key_update
, /* SADB_UPDATE */
9240 key_add
, /* SADB_ADD */
9241 key_delete
, /* SADB_DELETE */
9242 key_get
, /* SADB_GET */
9243 key_acquire2
, /* SADB_ACQUIRE */
9244 key_register
, /* SADB_REGISTER */
9245 NULL
, /* SADB_EXPIRE */
9246 key_flush
, /* SADB_FLUSH */
9247 key_dump
, /* SADB_DUMP */
9248 key_promisc
, /* SADB_X_PROMISC */
9249 NULL
, /* SADB_X_PCHANGE */
9250 key_spdadd
, /* SADB_X_SPDUPDATE */
9251 key_spdadd
, /* SADB_X_SPDADD */
9252 key_spddelete
, /* SADB_X_SPDDELETE */
9253 key_spdget
, /* SADB_X_SPDGET */
9254 NULL
, /* SADB_X_SPDACQUIRE */
9255 key_spddump
, /* SADB_X_SPDDUMP */
9256 key_spdflush
, /* SADB_X_SPDFLUSH */
9257 key_spdadd
, /* SADB_X_SPDSETIDX */
9258 NULL
, /* SADB_X_SPDEXPIRE */
9259 key_spddelete2
, /* SADB_X_SPDDELETE2 */
9260 key_getsastat
, /* SADB_GETSASTAT */
9261 key_spdenable
, /* SADB_X_SPDENABLE */
9262 key_spddisable
, /* SADB_X_SPDDISABLE */
9263 key_migrate
, /* SADB_MIGRATE */
9267 bzero_mbuf(struct mbuf
*m
)
9269 struct mbuf
*mptr
= m
;
9270 struct sadb_msg
*msg
= NULL
;
9277 if (mptr
->m_len
>= sizeof(struct sadb_msg
)) {
9278 msg
= mtod(mptr
, struct sadb_msg
*);
9279 if (msg
->sadb_msg_type
!= SADB_ADD
&&
9280 msg
->sadb_msg_type
!= SADB_UPDATE
) {
9283 offset
= sizeof(struct sadb_msg
);
9285 bzero(mptr
->m_data
+offset
, mptr
->m_len
-offset
);
9286 mptr
= mptr
->m_next
;
9287 while (mptr
!= NULL
) {
9288 bzero(mptr
->m_data
, mptr
->m_len
);
9289 mptr
= mptr
->m_next
;
9294 bzero_keys(const struct sadb_msghdr
*mh
)
9302 offset
= sizeof(struct sadb_key
);
9304 if (mh
->ext
[SADB_EXT_KEY_ENCRYPT
]) {
9305 struct sadb_key
*key
= (struct sadb_key
*)mh
->ext
[SADB_EXT_KEY_ENCRYPT
];
9306 extlen
= key
->sadb_key_bits
>> 3;
9308 if (mh
->extlen
[SADB_EXT_KEY_ENCRYPT
] >= offset
+ extlen
) {
9309 bzero((uint8_t *)mh
->ext
[SADB_EXT_KEY_ENCRYPT
]+offset
, extlen
);
9311 bzero(mh
->ext
[SADB_EXT_KEY_ENCRYPT
], mh
->extlen
[SADB_EXT_KEY_ENCRYPT
]);
9314 if (mh
->ext
[SADB_EXT_KEY_AUTH
]) {
9315 struct sadb_key
*key
= (struct sadb_key
*)mh
->ext
[SADB_EXT_KEY_AUTH
];
9316 extlen
= key
->sadb_key_bits
>> 3;
9318 if (mh
->extlen
[SADB_EXT_KEY_AUTH
] >= offset
+ extlen
) {
9319 bzero((uint8_t *)mh
->ext
[SADB_EXT_KEY_AUTH
]+offset
, extlen
);
9321 bzero(mh
->ext
[SADB_EXT_KEY_AUTH
], mh
->extlen
[SADB_EXT_KEY_AUTH
]);
9327 key_validate_address_pair(struct sadb_address
*src0
,
9328 struct sadb_address
*dst0
)
9332 /* check upper layer protocol */
9333 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
9334 ipseclog((LOG_DEBUG
, "key_parse: upper layer protocol mismatched.\n"));
9335 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9340 if (PFKEY_ADDR_SADDR(src0
)->sa_family
!=
9341 PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
9342 ipseclog((LOG_DEBUG
, "key_parse: address family mismatched.\n"));
9343 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9346 if (PFKEY_ADDR_SADDR(src0
)->sa_len
!=
9347 PFKEY_ADDR_SADDR(dst0
)->sa_len
) {
9348 ipseclog((LOG_DEBUG
,
9349 "key_parse: address struct size mismatched.\n"));
9350 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9354 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
9356 if (PFKEY_ADDR_SADDR(src0
)->sa_len
!= sizeof(struct sockaddr_in
)) {
9357 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9362 if (PFKEY_ADDR_SADDR(src0
)->sa_len
!= sizeof(struct sockaddr_in6
)) {
9363 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9368 ipseclog((LOG_DEBUG
,
9369 "key_parse: unsupported address family.\n"));
9370 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9371 return (EAFNOSUPPORT
);
9374 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
9376 plen
= sizeof(struct in_addr
) << 3;
9379 plen
= sizeof(struct in6_addr
) << 3;
9382 plen
= 0; /*fool gcc*/
9386 /* check max prefix length */
9387 if (src0
->sadb_address_prefixlen
> plen
||
9388 dst0
->sadb_address_prefixlen
> plen
) {
9389 ipseclog((LOG_DEBUG
,
9390 "key_parse: illegal prefixlen.\n"));
9391 PFKEY_STAT_INCREMENT(pfkeystat
.out_invaddr
);
9396 * prefixlen == 0 is valid because there can be a case when
9397 * all addresses are matched.
9403 * parse sadb_msg buffer to process PFKEYv2,
9404 * and create a data to response if needed.
9405 * I think to be dealed with mbuf directly.
9407 * msgp : pointer to pointer to a received buffer pulluped.
9408 * This is rewrited to response.
9409 * so : pointer to socket.
9411 * length for buffer to send to user process.
9418 struct sadb_msg
*msg
;
9419 struct sadb_msghdr mh
;
9423 Boolean keyAligned
= FALSE
;
9425 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
9428 if (m
== NULL
|| so
== NULL
)
9429 panic("key_parse: NULL pointer is passed.\n");
9431 #if 0 /*kdebug_sadb assumes msg in linear buffer*/
9432 KEYDEBUG(KEYDEBUG_KEY_DUMP
,
9433 ipseclog((LOG_DEBUG
, "key_parse: passed sadb_msg\n"));
9437 if (m
->m_len
< sizeof(struct sadb_msg
)) {
9438 m
= m_pullup(m
, sizeof(struct sadb_msg
));
9442 msg
= mtod(m
, struct sadb_msg
*);
9443 orglen
= PFKEY_UNUNIT64(msg
->sadb_msg_len
);
9444 target
= KEY_SENDUP_ONE
;
9446 if ((m
->m_flags
& M_PKTHDR
) == 0 ||
9447 m
->m_pkthdr
.len
!= m
->m_pkthdr
.len
) {
9448 ipseclog((LOG_DEBUG
, "key_parse: invalid message length.\n"));
9449 PFKEY_STAT_INCREMENT(pfkeystat
.out_invlen
);
9454 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
9455 ipseclog((LOG_DEBUG
,
9456 "key_parse: PF_KEY version %u is mismatched.\n",
9457 msg
->sadb_msg_version
));
9458 PFKEY_STAT_INCREMENT(pfkeystat
.out_invver
);
9463 if (msg
->sadb_msg_type
> SADB_MAX
) {
9464 ipseclog((LOG_DEBUG
, "key_parse: invalid type %u is passed.\n",
9465 msg
->sadb_msg_type
));
9466 PFKEY_STAT_INCREMENT(pfkeystat
.out_invmsgtype
);
9471 /* for old-fashioned code - should be nuked */
9472 if (m
->m_pkthdr
.len
> MCLBYTES
) {
9479 MGETHDR(n
, M_WAITOK
, MT_DATA
);
9480 if (n
&& m
->m_pkthdr
.len
> MHLEN
) {
9481 MCLGET(n
, M_WAITOK
);
9482 if ((n
->m_flags
& M_EXT
) == 0) {
9492 m_copydata(m
, 0, m
->m_pkthdr
.len
, mtod(n
, caddr_t
));
9493 n
->m_pkthdr
.len
= n
->m_len
= m
->m_pkthdr
.len
;
9500 /* align the mbuf chain so that extensions are in contiguous region. */
9501 error
= key_align(m
, &mh
);
9505 if (m
->m_next
) { /*XXX*/
9515 switch (msg
->sadb_msg_satype
) {
9516 case SADB_SATYPE_UNSPEC
:
9517 switch (msg
->sadb_msg_type
) {
9525 ipseclog((LOG_DEBUG
, "key_parse: must specify satype "
9526 "when msg type=%u.\n", msg
->sadb_msg_type
));
9527 PFKEY_STAT_INCREMENT(pfkeystat
.out_invsatype
);
9532 case SADB_SATYPE_AH
:
9533 case SADB_SATYPE_ESP
:
9534 case SADB_X_SATYPE_IPCOMP
:
9535 switch (msg
->sadb_msg_type
) {
9537 case SADB_X_SPDDELETE
:
9539 case SADB_X_SPDDUMP
:
9540 case SADB_X_SPDFLUSH
:
9541 case SADB_X_SPDSETIDX
:
9542 case SADB_X_SPDUPDATE
:
9543 case SADB_X_SPDDELETE2
:
9544 case SADB_X_SPDENABLE
:
9545 case SADB_X_SPDDISABLE
:
9546 ipseclog((LOG_DEBUG
, "key_parse: illegal satype=%u\n",
9547 msg
->sadb_msg_type
));
9548 PFKEY_STAT_INCREMENT(pfkeystat
.out_invsatype
);
9553 case SADB_SATYPE_RSVP
:
9554 case SADB_SATYPE_OSPFV2
:
9555 case SADB_SATYPE_RIPV2
:
9556 case SADB_SATYPE_MIP
:
9557 ipseclog((LOG_DEBUG
, "key_parse: type %u isn't supported.\n",
9558 msg
->sadb_msg_satype
));
9559 PFKEY_STAT_INCREMENT(pfkeystat
.out_invsatype
);
9562 case 1: /* XXX: What does it do? */
9563 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
9567 ipseclog((LOG_DEBUG
, "key_parse: invalid type %u is passed.\n",
9568 msg
->sadb_msg_satype
));
9569 PFKEY_STAT_INCREMENT(pfkeystat
.out_invsatype
);
9574 /* Validate address fields for matching families, lengths, etc. */
9575 void *src0
= mh
.ext
[SADB_EXT_ADDRESS_SRC
];
9576 void *dst0
= mh
.ext
[SADB_EXT_ADDRESS_DST
];
9577 if (mh
.ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
] != NULL
&&
9578 mh
.ext
[SADB_X_EXT_ADDR_RANGE_SRC_END
] != NULL
) {
9580 error
= key_validate_address_pair((struct sadb_address
*)(mh
.ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
]),
9581 (struct sadb_address
*)(mh
.ext
[SADB_X_EXT_ADDR_RANGE_SRC_END
]));
9587 src0
= mh
.ext
[SADB_X_EXT_ADDR_RANGE_SRC_START
];
9590 if (mh
.ext
[SADB_X_EXT_ADDR_RANGE_DST_START
] != NULL
&&
9591 mh
.ext
[SADB_X_EXT_ADDR_RANGE_DST_END
] != NULL
) {
9593 error
= key_validate_address_pair((struct sadb_address
*)(mh
.ext
[SADB_X_EXT_ADDR_RANGE_DST_START
]),
9594 (struct sadb_address
*)(mh
.ext
[SADB_X_EXT_ADDR_RANGE_DST_END
]));
9600 dst0
= mh
.ext
[SADB_X_EXT_ADDR_RANGE_DST_START
];
9603 if (src0
!= NULL
&& dst0
!= NULL
) {
9604 error
= key_validate_address_pair((struct sadb_address
*)(src0
),
9605 (struct sadb_address
*)(dst0
));
9611 if (msg
->sadb_msg_type
>= sizeof(key_typesw
)/sizeof(key_typesw
[0]) ||
9612 key_typesw
[msg
->sadb_msg_type
] == NULL
) {
9613 PFKEY_STAT_INCREMENT(pfkeystat
.out_invmsgtype
);
9618 error
= (*key_typesw
[msg
->sadb_msg_type
])(so
, m
, &mh
);
9628 msg
->sadb_msg_errno
= error
;
9629 return key_sendup_mbuf(so
, m
, target
);
9638 struct sadb_msg
*msg
;
9640 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
9642 if (m
->m_len
< sizeof(struct sadb_msg
))
9643 panic("invalid mbuf passed to key_senderror");
9645 msg
= mtod(m
, struct sadb_msg
*);
9646 msg
->sadb_msg_errno
= code
;
9647 return key_sendup_mbuf(so
, m
, KEY_SENDUP_ONE
);
9651 * set the pointer to each header into message buffer.
9652 * m will be freed on error.
9653 * XXX larger-than-MCLBYTES extension?
9658 struct sadb_msghdr
*mhp
)
9661 struct sadb_ext
*ext
;
9667 if (m
== NULL
|| mhp
== NULL
)
9668 panic("key_align: NULL pointer is passed.\n");
9669 if (m
->m_len
< sizeof(struct sadb_msg
))
9670 panic("invalid mbuf passed to key_align");
9673 bzero(mhp
, sizeof(*mhp
));
9675 mhp
->msg
= mtod(m
, struct sadb_msg
*);
9676 mhp
->ext
[0] = (struct sadb_ext
*)mhp
->msg
; /*XXX backward compat */
9678 end
= PFKEY_UNUNIT64(mhp
->msg
->sadb_msg_len
);
9679 extlen
= end
; /*just in case extlen is not updated*/
9680 for (off
= sizeof(struct sadb_msg
); off
< end
; off
+= extlen
) {
9681 n
= m_pulldown(m
, off
, sizeof(struct sadb_ext
), &toff
);
9683 /* m is already freed */
9686 ext
= (struct sadb_ext
*)(void *)(mtod(n
, caddr_t
) + toff
);
9689 switch (ext
->sadb_ext_type
) {
9691 case SADB_EXT_ADDRESS_SRC
:
9692 case SADB_EXT_ADDRESS_DST
:
9693 case SADB_EXT_ADDRESS_PROXY
:
9694 case SADB_EXT_LIFETIME_CURRENT
:
9695 case SADB_EXT_LIFETIME_HARD
:
9696 case SADB_EXT_LIFETIME_SOFT
:
9697 case SADB_EXT_KEY_AUTH
:
9698 case SADB_EXT_KEY_ENCRYPT
:
9699 case SADB_EXT_IDENTITY_SRC
:
9700 case SADB_EXT_IDENTITY_DST
:
9701 case SADB_EXT_SENSITIVITY
:
9702 case SADB_EXT_PROPOSAL
:
9703 case SADB_EXT_SUPPORTED_AUTH
:
9704 case SADB_EXT_SUPPORTED_ENCRYPT
:
9705 case SADB_EXT_SPIRANGE
:
9706 case SADB_X_EXT_POLICY
:
9707 case SADB_X_EXT_SA2
:
9708 case SADB_EXT_SESSION_ID
:
9709 case SADB_EXT_SASTAT
:
9710 case SADB_X_EXT_IPSECIF
:
9711 case SADB_X_EXT_ADDR_RANGE_SRC_START
:
9712 case SADB_X_EXT_ADDR_RANGE_SRC_END
:
9713 case SADB_X_EXT_ADDR_RANGE_DST_START
:
9714 case SADB_X_EXT_ADDR_RANGE_DST_END
:
9715 case SADB_EXT_MIGRATE_ADDRESS_SRC
:
9716 case SADB_EXT_MIGRATE_ADDRESS_DST
:
9717 case SADB_X_EXT_MIGRATE_IPSECIF
:
9718 /* duplicate check */
9720 * XXX Are there duplication payloads of either
9721 * KEY_AUTH or KEY_ENCRYPT ?
9723 if (mhp
->ext
[ext
->sadb_ext_type
] != NULL
) {
9724 ipseclog((LOG_DEBUG
,
9725 "key_align: duplicate ext_type %u "
9726 "is passed.\n", ext
->sadb_ext_type
));
9729 PFKEY_STAT_INCREMENT(pfkeystat
.out_dupext
);
9734 ipseclog((LOG_DEBUG
,
9735 "key_align: invalid ext_type %u is passed.\n",
9736 ext
->sadb_ext_type
));
9739 PFKEY_STAT_INCREMENT(pfkeystat
.out_invexttype
);
9743 extlen
= PFKEY_UNUNIT64(ext
->sadb_ext_len
);
9745 if (key_validate_ext(ext
, extlen
)) {
9748 PFKEY_STAT_INCREMENT(pfkeystat
.out_invlen
);
9752 n
= m_pulldown(m
, off
, extlen
, &toff
);
9754 /* m is already freed */
9757 ext
= (struct sadb_ext
*)(void *)(mtod(n
, caddr_t
) + toff
);
9759 mhp
->ext
[ext
->sadb_ext_type
] = ext
;
9760 mhp
->extoff
[ext
->sadb_ext_type
] = off
;
9761 mhp
->extlen
[ext
->sadb_ext_type
] = extlen
;
9767 PFKEY_STAT_INCREMENT(pfkeystat
.out_invlen
);
9776 const struct sadb_ext
*ext
,
9779 struct sockaddr
*sa
;
9780 enum { NONE
, ADDR
} checktype
= NONE
;
9782 const int sal
= offsetof(struct sockaddr
, sa_len
) + sizeof(sa
->sa_len
);
9784 if (len
!= PFKEY_UNUNIT64(ext
->sadb_ext_len
))
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]))
9791 if (!minsize
[ext
->sadb_ext_type
] || len
< minsize
[ext
->sadb_ext_type
])
9793 if (maxsize
[ext
->sadb_ext_type
] && len
> maxsize
[ext
->sadb_ext_type
])
9796 /* more checks based on sadb_ext_type XXX need more */
9797 switch (ext
->sadb_ext_type
) {
9798 case SADB_EXT_ADDRESS_SRC
:
9799 case SADB_EXT_ADDRESS_DST
:
9800 case SADB_EXT_ADDRESS_PROXY
:
9801 case SADB_X_EXT_ADDR_RANGE_SRC_START
:
9802 case SADB_X_EXT_ADDR_RANGE_SRC_END
:
9803 case SADB_X_EXT_ADDR_RANGE_DST_START
:
9804 case SADB_X_EXT_ADDR_RANGE_DST_END
:
9805 case SADB_EXT_MIGRATE_ADDRESS_SRC
:
9806 case SADB_EXT_MIGRATE_ADDRESS_DST
:
9807 baselen
= PFKEY_ALIGN8(sizeof(struct sadb_address
));
9810 case SADB_EXT_IDENTITY_SRC
:
9811 case SADB_EXT_IDENTITY_DST
:
9812 if (((struct sadb_ident
*)(uintptr_t)(size_t)ext
)->
9813 sadb_ident_type
== SADB_X_IDENTTYPE_ADDR
) {
9814 baselen
= PFKEY_ALIGN8(sizeof(struct sadb_ident
));
9824 switch (checktype
) {
9828 sa
= (struct sockaddr
*)((caddr_t
)(uintptr_t)ext
+ baselen
);
9830 if (len
< baselen
+ sal
)
9832 if (baselen
+ PFKEY_ALIGN8(sa
->sa_len
) != len
)
9841 * XXX: maybe This function is called after INBOUND IPsec processing.
9843 * Special check for tunnel-mode packets.
9844 * We must make some checks for consistency between inner and outer IP header.
9846 * xxx more checks to be provided
9849 key_checktunnelsanity(
9850 struct secasvar
*sav
,
9851 __unused u_int family
,
9852 __unused caddr_t src
,
9853 __unused caddr_t dst
)
9857 if (sav
->sah
== NULL
)
9858 panic("sav->sah == NULL at key_checktunnelsanity");
9860 /* XXX: check inner IP header */
9865 /* record data transfer on SA, and update timestamps */
9868 struct secasvar
*sav
,
9874 panic("key_sa_recordxfer called with sav == NULL");
9876 panic("key_sa_recordxfer called with m == NULL");
9880 lck_mtx_lock(sadb_mutex
);
9882 * XXX Currently, there is a difference of bytes size
9883 * between inbound and outbound processing.
9885 sav
->lft_c
->sadb_lifetime_bytes
+= m
->m_pkthdr
.len
;
9886 /* to check bytes lifetime is done in key_timehandler(). */
9889 * We use the number of packets as the unit of
9890 * sadb_lifetime_allocations. We increment the variable
9891 * whenever {esp,ah}_{in,out}put is called.
9893 sav
->lft_c
->sadb_lifetime_allocations
++;
9894 /* XXX check for expires? */
9897 * NOTE: We record CURRENT sadb_lifetime_usetime by using wall clock,
9898 * in seconds. HARD and SOFT lifetime are measured by the time
9899 * difference (again in seconds) from sadb_lifetime_usetime.
9903 * -----+-----+--------+---> t
9904 * <--------------> HARD
9910 sav
->lft_c
->sadb_lifetime_usetime
= tv
.tv_sec
;
9911 /* XXX check for expires? */
9913 lck_mtx_unlock(sadb_mutex
);
9921 struct sockaddr
*dst
)
9923 struct secashead
*sah
;
9926 lck_mtx_lock(sadb_mutex
);
9927 LIST_FOREACH(sah
, &sahtree
, chain
) {
9928 ro
= (struct route
*)&sah
->sa_route
;
9929 if (ro
->ro_rt
&& dst
->sa_len
== ro
->ro_dst
.sa_len
9930 && bcmp(dst
, &ro
->ro_dst
, dst
->sa_len
) == 0) {
9934 lck_mtx_unlock(sadb_mutex
);
9941 struct secasvar
*sav
,
9946 panic("key_sa_chgstate called with sav == NULL");
9948 if (sav
->state
== state
)
9951 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
);
9953 if (__LIST_CHAINED(sav
))
9954 LIST_REMOVE(sav
, chain
);
9957 LIST_INSERT_HEAD(&sav
->sah
->savtree
[state
], sav
, chain
);
9963 struct secasvar
*sav
)
9965 lck_mtx_lock(sadb_mutex
);
9967 panic("key_sa_stir_iv called with sav == NULL");
9968 key_randomfill(sav
->iv
, sav
->ivlen
);
9969 lck_mtx_unlock(sadb_mutex
);
9973 static struct mbuf
*
9977 struct mbuf
*m
= NULL
, *n
;
9982 MGET(n
, M_DONTWAIT
, MT_DATA
);
9983 if (n
&& len
> MLEN
)
9984 MCLGET(n
, M_DONTWAIT
);
9992 n
->m_len
= M_TRAILINGSPACE(n
);
9993 /* use the bottom of mbuf, hoping we can prepend afterwards */
9994 if (n
->m_len
> len
) {
9995 t
= (n
->m_len
- len
) & ~(sizeof(long) - 1);
10011 static struct mbuf
*
10012 key_setdumpsastats (u_int32_t dir
,
10013 struct sastat
*stats
,
10014 u_int32_t max_stats
,
10015 u_int64_t session_ids
[],
10019 struct mbuf
*result
= NULL
, *m
= NULL
;
10021 m
= key_setsadbmsg(SADB_GETSASTAT
, 0, 0, seq
, pid
, 0);
10027 m
= key_setsadbsession_id(session_ids
);
10033 m
= key_setsadbsastat(dir
,
10041 if ((result
->m_flags
& M_PKTHDR
) == 0) {
10045 if (result
->m_len
< sizeof(struct sadb_msg
)) {
10046 result
= m_pullup(result
, sizeof(struct sadb_msg
));
10047 if (result
== NULL
) {
10052 result
->m_pkthdr
.len
= 0;
10053 for (m
= result
; m
; m
= m
->m_next
) {
10054 result
->m_pkthdr
.len
+= m
->m_len
;
10057 mtod(result
, struct sadb_msg
*)->sadb_msg_len
=
10058 PFKEY_UNIT64(result
->m_pkthdr
.len
);
10070 * SADB_GETSASTAT processing
10071 * dump all stats for matching entries in SAD.
10073 * m will always be freed.
10077 key_getsastat (struct socket
*so
,
10079 const struct sadb_msghdr
*mhp
)
10081 struct sadb_session_id
*session_id
;
10082 u_int32_t bufsize
, arg_count
, res_count
;
10083 struct sadb_sastat
*sa_stats_arg
;
10084 struct sastat
*sa_stats_sav
= NULL
;
10089 if (so
== NULL
|| m
== NULL
|| mhp
== NULL
|| mhp
->msg
== NULL
)
10090 panic("%s: NULL pointer is passed.\n", __FUNCTION__
);
10092 if (mhp
->ext
[SADB_EXT_SESSION_ID
] == NULL
) {
10093 printf("%s: invalid message is passed. missing session-id.\n", __FUNCTION__
);
10094 return key_senderror(so
, m
, EINVAL
);
10096 if (mhp
->extlen
[SADB_EXT_SESSION_ID
] < sizeof(struct sadb_session_id
)) {
10097 printf("%s: invalid message is passed. short session-id.\n", __FUNCTION__
);
10098 return key_senderror(so
, m
, EINVAL
);
10100 if (mhp
->ext
[SADB_EXT_SASTAT
] == NULL
) {
10101 printf("%s: invalid message is passed. missing stat args.\n", __FUNCTION__
);
10102 return key_senderror(so
, m
, EINVAL
);
10104 if (mhp
->extlen
[SADB_EXT_SASTAT
] < sizeof(*sa_stats_arg
)) {
10105 printf("%s: invalid message is passed. short stat args.\n", __FUNCTION__
);
10106 return key_senderror(so
, m
, EINVAL
);
10109 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
10111 // exit early if there are no active SAs
10112 if (ipsec_sav_count
<= 0) {
10113 printf("%s: No active SAs.\n", __FUNCTION__
);
10117 bufsize
= (ipsec_sav_count
+ 1) * sizeof(*sa_stats_sav
);
10119 KMALLOC_WAIT(sa_stats_sav
, __typeof__(sa_stats_sav
), bufsize
);
10120 if (sa_stats_sav
== NULL
) {
10121 printf("%s: No more memory.\n", __FUNCTION__
);
10125 bzero(sa_stats_sav
, bufsize
);
10127 sa_stats_arg
= (__typeof__(sa_stats_arg
))
10128 (void *)mhp
->ext
[SADB_EXT_SASTAT
];
10129 arg_count
= sa_stats_arg
->sadb_sastat_list_len
;
10130 // exit early if there are no requested SAs
10131 if (arg_count
== 0) {
10132 printf("%s: No SAs requested.\n", __FUNCTION__
);
10138 if (key_getsastatbyspi((struct sastat
*)(sa_stats_arg
+ 1),
10142 printf("%s: Error finding SAs.\n", __FUNCTION__
);
10147 printf("%s: No SAs found.\n", __FUNCTION__
);
10152 session_id
= (__typeof__(session_id
))
10153 (void *)mhp
->ext
[SADB_EXT_SESSION_ID
];
10155 /* send this to the userland. */
10156 n
= key_setdumpsastats(sa_stats_arg
->sadb_sastat_dir
,
10159 session_id
->sadb_session_id_v
,
10160 mhp
->msg
->sadb_msg_seq
,
10161 mhp
->msg
->sadb_msg_pid
);
10163 printf("%s: No bufs to dump stats.\n", __FUNCTION__
);
10168 key_sendup_mbuf(so
, n
, KEY_SENDUP_ALL
);
10170 if (sa_stats_sav
) {
10171 KFREE(sa_stats_sav
);
10175 return key_senderror(so
, m
, error
);
10182 key_update_natt_keepalive_timestamp (struct secasvar
*sav_sent
,
10183 struct secasvar
*sav_update
)
10185 struct secasindex saidx_swap_sent_addr
;
10187 // exit early if two SAs are identical, or if sav_update is current
10188 if (sav_sent
== sav_update
||
10189 sav_update
->natt_last_activity
== natt_now
) {
10193 // assuming that (sav_update->remote_ike_port != 0 && (esp_udp_encap_port & 0xFFFF) != 0)
10195 bzero(&saidx_swap_sent_addr
, sizeof(saidx_swap_sent_addr
));
10196 memcpy(&saidx_swap_sent_addr
.src
, &sav_sent
->sah
->saidx
.dst
, sizeof(saidx_swap_sent_addr
.src
));
10197 memcpy(&saidx_swap_sent_addr
.dst
, &sav_sent
->sah
->saidx
.src
, sizeof(saidx_swap_sent_addr
.dst
));
10198 saidx_swap_sent_addr
.proto
= sav_sent
->sah
->saidx
.proto
;
10199 saidx_swap_sent_addr
.mode
= sav_sent
->sah
->saidx
.mode
;
10200 // we ignore reqid for split-tunnel setups
10202 if (key_cmpsaidx(&sav_sent
->sah
->saidx
, &sav_update
->sah
->saidx
, CMP_MODE
| CMP_PORT
) ||
10203 key_cmpsaidx(&saidx_swap_sent_addr
, &sav_update
->sah
->saidx
, CMP_MODE
| CMP_PORT
)) {
10204 sav_update
->natt_last_activity
= natt_now
;
10209 key_send_delsp (struct secpolicy
*sp
)
10211 struct mbuf
*result
= NULL
, *m
;
10216 /* set msg header */
10217 m
= key_setsadbmsg(SADB_X_SPDDELETE
, 0, 0, 0, 0, 0);
10223 /* set sadb_address(es) for source */
10224 if (sp
->spidx
.src_range
.start
.ss_len
> 0) {
10225 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_START
,
10226 (struct sockaddr
*)&sp
->spidx
.src_range
.start
, sp
->spidx
.prefs
,
10227 sp
->spidx
.ul_proto
);
10232 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_SRC_END
,
10233 (struct sockaddr
*)&sp
->spidx
.src_range
.end
, sp
->spidx
.prefs
,
10234 sp
->spidx
.ul_proto
);
10239 m
= key_setsadbaddr(SADB_EXT_ADDRESS_SRC
,
10240 (struct sockaddr
*)&sp
->spidx
.src
, sp
->spidx
.prefs
,
10241 sp
->spidx
.ul_proto
);
10247 /* set sadb_address(es) for destination */
10248 if (sp
->spidx
.dst_range
.start
.ss_len
> 0) {
10249 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_START
,
10250 (struct sockaddr
*)&sp
->spidx
.dst_range
.start
, sp
->spidx
.prefd
,
10251 sp
->spidx
.ul_proto
);
10256 m
= key_setsadbaddr(SADB_X_EXT_ADDR_RANGE_DST_END
,
10257 (struct sockaddr
*)&sp
->spidx
.dst_range
.end
, sp
->spidx
.prefd
,
10258 sp
->spidx
.ul_proto
);
10263 m
= key_setsadbaddr(SADB_EXT_ADDRESS_DST
,
10264 (struct sockaddr
*)&sp
->spidx
.dst
, sp
->spidx
.prefd
,
10265 sp
->spidx
.ul_proto
);
10271 /* set secpolicy */
10272 m
= key_sp2msg(sp
);
10278 if ((result
->m_flags
& M_PKTHDR
) == 0) {
10282 if (result
->m_len
< sizeof(struct sadb_msg
)) {
10283 result
= m_pullup(result
, sizeof(struct sadb_msg
));
10284 if (result
== NULL
) {
10289 result
->m_pkthdr
.len
= 0;
10290 for (m
= result
; m
; m
= m
->m_next
)
10291 result
->m_pkthdr
.len
+= m
->m_len
;
10293 mtod(result
, struct sadb_msg
*)->sadb_msg_len
= PFKEY_UNIT64(result
->m_pkthdr
.len
);
10295 return key_sendup_mbuf(NULL
, result
, KEY_SENDUP_REGISTERED
);
10304 key_delsp_for_ipsec_if (ifnet_t ipsec_if
)
10306 struct secashead
*sah
;
10307 struct secasvar
*sav
, *nextsav
;
10310 struct secpolicy
*sp
, *nextsp
;
10313 if (ipsec_if
== NULL
)
10316 LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
10318 lck_mtx_lock(sadb_mutex
);
10320 for (dir
= 0; dir
< IPSEC_DIR_MAX
; dir
++) {
10321 for (sp
= LIST_FIRST(&sptree
[dir
]);
10325 nextsp
= LIST_NEXT(sp
, chain
);
10327 if (sp
->ipsec_if
== ipsec_if
) {
10328 ifnet_release(sp
->ipsec_if
);
10329 sp
->ipsec_if
= NULL
;
10331 key_send_delsp(sp
);
10333 sp
->state
= IPSEC_SPSTATE_DEAD
;
10334 key_freesp(sp
, KEY_SADB_LOCKED
);
10339 LIST_FOREACH(sah
, &sahtree
, chain
) {
10340 if (sah
->ipsec_if
== ipsec_if
) {
10341 /* This SAH is linked to the IPSec interface. It now needs to close. */
10342 ifnet_release(sah
->ipsec_if
);
10343 sah
->ipsec_if
= NULL
;
10345 for (stateidx
= 0; stateidx
< _ARRAYLEN(saorder_state_alive
); stateidx
++) {
10346 state
= saorder_state_any
[stateidx
];
10347 for (sav
= LIST_FIRST(&sah
->savtree
[state
]); sav
!= NULL
; sav
= nextsav
) {
10348 nextsav
= LIST_NEXT(sav
, chain
);
10350 key_sa_chgstate(sav
, SADB_SASTATE_DEAD
);
10351 key_freesav(sav
, KEY_SADB_LOCKED
);
10355 sah
->state
= SADB_SASTATE_DEAD
;
10359 lck_mtx_unlock(sadb_mutex
);
10362 __private_extern__ u_int32_t
10363 key_fill_offload_frames_for_savs (ifnet_t ifp
,
10364 struct ifnet_keepalive_offload_frame
*frames_array
,
10365 u_int32_t frames_array_count
,
10366 size_t frame_data_offset
)
10368 struct secashead
*sah
= NULL
;
10369 struct secasvar
*sav
= NULL
;
10370 struct ifnet_keepalive_offload_frame
*frame
= frames_array
;
10371 u_int32_t frame_index
= 0;
10373 if (frame
== NULL
|| frames_array_count
== 0) {
10374 return (frame_index
);
10377 lck_mtx_lock(sadb_mutex
);
10378 LIST_FOREACH(sah
, &sahtree
, chain
) {
10379 LIST_FOREACH(sav
, &sah
->savtree
[SADB_SASTATE_MATURE
], chain
) {
10380 if (ipsec_fill_offload_frame(ifp
, sav
, frame
, frame_data_offset
)) {
10382 if (frame_index
>= frames_array_count
) {
10383 lck_mtx_unlock(sadb_mutex
);
10384 return (frame_index
);
10386 frame
= &(frames_array
[frame_index
]);
10390 lck_mtx_unlock(sadb_mutex
);
10392 return (frame_index
);