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