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