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