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