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