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