1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright 2017 Jason King.
27 * Copyright 2017 Joyent, Inc.
28 */
29
30 /*
31 * Manipulation and storage of IKEv2 Security Associations (SAs).
32 */
33 #include <umem.h>
34 #include <pthread.h>
35 #include <errno.h>
36 #include <strings.h>
37 #include <locale.h>
38 #include <stddef.h>
39 #include <sys/types.h>
40 #include <sys/sysmacros.h>
41 #include <sys/debug.h>
42 #include <limits.h>
43 #include <note.h>
44 #include <ipsec_util.h>
45 #include <libuutil.h>
46 #include "defs.h"
47 #include "buf.h"
48 #include "timer.h"
49 #include "pkcs11.h"
50 #include "ikev2_pkt.h"
51 #include "ikev2_sa.h"
52 #include "random.h"
53 #include "worker.h"
54 #include "config.h"
55
56 /* Our hashes */
57 enum {
58 LSPI,
59 RHASH
60 };
61
62 struct i2sa_bucket {
63 pthread_mutex_t lock; /* bucket lock */
64 uu_list_t *chain; /* hash chain of ikev2_sa_t's */
65 };
66
67 typedef struct i2sa_cmp_arg {
68 sockaddr_u_t laddr;
69 sockaddr_u_t raddr;
70 const pkt_t *init_pkt;
71 uint64_t lspi;
72 uint64_t rspi;
73 int hash;
74 } i2sa_cmp_arg_t;
75
76 static const struct {
77 const char *name;
78 offset_t offset;
79 } pool_names[] = {
80 { "ikev2_lspi_chain", offsetof(ikev2_sa_t, lspi_node) },
81 { "ikev2_rhash_chain", offsetof(ikev2_sa_t, rhash_node) }
82 };
83
84 static volatile uint_t half_open; /* # of larval/half open IKEv2 SAs */
85 static uint_t num_buckets; /* Use same value for all hashes */
86 static uint32_t remote_noise; /* random noise for rhash */
87 static i2sa_bucket_t *hash[I2SA_NUM_HASH];
88 static uu_list_pool_t *list_pool[I2SA_NUM_HASH];
89 static umem_cache_t *i2sa_cache;
90
91 #define I2SA_KEY_LADDR "laddr"
92 #define I2SA_KEY_LPORT "lport"
93 #define I2SA_KEY_RADDR "raddr"
94 #define I2SA_KEY_RPORT "rport"
95 #define I2SA_KEY_LSPI "lspi"
96 #define I2SA_KEY_RSPI "rspi"
97 #define I2SA_KEY_INITIATOR "initiator"
98
99 #define IKEV2_SA_HASH_SPI(spi) \
100 P2PHASE_TYPED((spi), num_buckets, uint64_t)
101
102 #define IKEV2_SA_RHASH(ss, spi) \
103 P2PHASE_TYPED(i2sa_rhash((ss), (spi)), num_buckets, uint64_t)
104
105 static void i2sa_init(ikev2_sa_t *);
106 static uint32_t i2sa_rhash(const struct sockaddr_storage *, uint64_t);
107
108 static ikev2_sa_t *i2sa_verify(ikev2_sa_t *restrict, uint64_t,
109 const struct sockaddr_storage *restrict,
110 const struct sockaddr_storage *restrict);
111 static boolean_t i2sa_add_to_hash(int, ikev2_sa_t *);
112
113 static void i2sa_unlink(ikev2_sa_t *);
114 static void i2sa_expire_cb(te_event_t, void *data);
115
116 static boolean_t i2sa_key_add_addr(ikev2_sa_t *, const char *, const char *,
117 const struct sockaddr_storage *);
118 static int i2sa_ctor(void *, void *, int);
119 static void i2sa_dtor(void *, void *);
120
121 static void inc_half_open(void);
122 static void dec_half_open(void);
123
124 /*
125 * Attempt to find an IKEv2 SA that matches the given criteria, or return
126 * NULL if not found.
127 */
128 ikev2_sa_t *
129 ikev2_sa_get(uint64_t l_spi, uint64_t r_spi,
130 const struct sockaddr_storage *restrict l_addr,
131 const struct sockaddr_storage *restrict r_addr,
132 const pkt_t *restrict init_pkt)
133 {
134 i2sa_bucket_t *bucket;
135 ikev2_sa_t *sa;
136 i2sa_cmp_arg_t arg = { 0 };
137
138 arg.lspi = l_spi;
139 arg.rspi = r_spi;
140 arg.init_pkt = init_pkt;
141 arg.laddr.sau_ss = (struct sockaddr_storage *)l_addr;
142 arg.raddr.sau_ss = (struct sockaddr_storage *)r_addr;
143
144 if (l_spi != 0) {
145 /*
146 * We assign the local SPIs, so if there is one, we should
147 * only need that to find it.
148 */
149 bucket = hash[LSPI] + IKEV2_SA_HASH_SPI(l_spi);
150 arg.hash = LSPI;
151 } else {
152 /* Otherwise gotta use the other stuff */
153 bucket = hash[RHASH] + IKEV2_SA_RHASH(r_addr, r_spi);
154 arg.hash = RHASH;
155 }
156
157 PTH(pthread_mutex_lock(&bucket->lock));
158 sa = (ikev2_sa_t *)uu_list_find(bucket->chain, NULL, &arg, NULL);
159 if (sa != NULL)
160 I2SA_REFHOLD(sa);
161 PTH(pthread_mutex_unlock(&bucket->lock));
162
163 return (i2sa_verify(sa, r_spi, l_addr, r_addr));
164 }
165
166 /*
167 * Allocate a larval IKEv2 SA.
168 *
169 * Obtains a unique local SPI and assigns it to the SA and adds the SA to
170 * the local SPI hash. If the packet used to trigger the creation of the SA
171 * is given, take over management of it. Also create an SA expiration timer.
172 *
173 * If we initiated the SA creation, the remote SPI will not be known initially.
174 * Once the protocol has proceeded enough to determine the remote SPI,
175 * ikev2_sa_set_rspi() should be called.
176 *
177 * Parameters:
178 * initiator Was this SA locally initiated
179 * init_pkt The packet that trigged the creation of the SA.
180 * laddr,
181 * raddr The local and remote addresses of this SA.
182 *
183 * On successful create, the larval IKEv2 SA is returned.
184 * On failure, NULL is returned. Caller maintains responsibility for
185 * init_pkt in this instance.
186 */
187 ikev2_sa_t *
188 ikev2_sa_alloc(boolean_t initiator,
189 pkt_t *restrict init_pkt,
190 const struct sockaddr_storage *restrict laddr,
191 const struct sockaddr_storage *restrict raddr)
192 {
193 ikev2_sa_t *i2sa = NULL;
194
195 if ((i2sa = umem_cache_alloc(i2sa_cache, UMEM_DEFAULT)) == NULL)
196 return (NULL);
197
198 if ((bunyan_child(log, &i2sa->i2sa_log) != 0)) {
199 umem_cache_free(i2sa_cache, i2sa);
200 return (NULL);
201 }
202
203 /* Keep anyone else out while we initialize */
204 PTH(pthread_mutex_lock(&i2sa->lock));
205
206 ASSERT((init_pkt == NULL) ||
207 (init_pkt->hdr.exch_type == IKEV2_EXCHANGE_IKE_SA_INIT));
208
209 i2sa->flags |= (initiator) ? I2SA_INITIATOR : 0;
210
211 (void) memcpy(&i2sa->laddr, laddr, sizeof (i2sa->laddr));
212 (void) memcpy(&i2sa->raddr, raddr, sizeof (i2sa->raddr));
213
214 /* Get a random number for the local SPI that's currently unusued */
215 while (1) {
216 /*CONSTCOND*/
217 uint64_t spi;
218
219 /* 0 is never valid, exteremely unlikely, but easy to handle */
220 if ((spi = random_low_64()) == 0)
221 continue;
222
223 if (initiator)
224 i2sa->i_spi = spi;
225 else
226 i2sa->r_spi = spi;
227
228 if (i2sa_add_to_hash(LSPI, i2sa)) {
229 ASSERT(i2sa->refcnt == 1);
230
231 /* XXX: refhold i2sa in init_pkt */
232 i2sa->init = init_pkt;
233
234 /* refhold for caller */
235 I2SA_REFHOLD(i2sa);
236 break;
237 }
238 };
239
240 inc_half_open();
241
242 if (!i2sa_key_add_addr(i2sa, I2SA_KEY_LADDR, I2SA_KEY_LPORT, laddr) ||
243 !i2sa_key_add_addr(i2sa, I2SA_KEY_RADDR, I2SA_KEY_RPORT, raddr) ||
244 bunyan_key_add(i2sa->i2sa_log,
245 BUNYAN_T_UINT64, I2SA_KEY_LSPI, I2SA_LOCAL_SPI(i2sa),
246 BUNYAN_T_UINT64, I2SA_KEY_RSPI, I2SA_REMOTE_SPI(i2sa),
247 BUNYAN_T_BOOLEAN, I2SA_KEY_INITIATOR,
248 (i2sa->flags & I2SA_INITIATOR) ? B_TRUE : B_FALSE,
249 BUNYAN_T_END) != 0)
250 goto fail;
251
252 /*
253 * Start SA expiration timer.
254 * XXX: Should this be reset after we've successfully authenticated?
255 */
256
257 I2SA_REFHOLD(i2sa); /* for the timer */
258 if (!schedule_timeout(TE_SA_EXPIRE, i2sa_expire_cb, i2sa,
259 /* XXX: fixme */ 999 * NANOSEC)) {
260 bunyan_warn(i2sa->i2sa_log, "aborting larval IKEv2 SA creation",
261 BUNYAN_T_END);
262
263 /* remove from hashes */
264 PTH(pthread_mutex_lock(&i2sa->lock));
265 i2sa_unlink(i2sa);
266 PTH(pthread_mutex_unlock(&i2sa->lock));
267
268 /* should be free'd once these references are released */
269 ASSERT(i2sa->refcnt == 2);
270 I2SA_REFRELE(i2sa); /* timer */
271 goto fail;
272 }
273
274 return (i2sa);
275
276 fail:
277 ASSERT(i2sa->refcnt == 1);
278 I2SA_REFRELE(i2sa);
279 return (NULL);
280 }
281
282 /*
283 * Invoked when an SA has expired. REF from timer is passed to this
284 * function.
285 */
286 static void
287 i2sa_expire_cb(te_event_t evt, void *data)
288 {
289 NOTE(ARGUNUSED(evt))
290
291 ikev2_sa_t *i2sa = (ikev2_sa_t *)data;
292
293 /* XXX: todo */
294 I2SA_REFRELE(i2sa);
295 }
296
297 void
298 ikev2_sa_flush(void)
299 {
300 /* TODO: implement me */
301 }
302
303 void
304 ikev2_sa_condemn(ikev2_sa_t *i2sa)
305 {
306 }
307
308 void
309 ikev2_sa_free(ikev2_sa_t *i2sa)
310 {
311 if (i2sa == NULL)
312 return;
313
314 ASSERT(i2sa->refcnt == 0);
315
316 if (i2sa->i2sa_rule != NULL)
317 CONFIG_REFRELE(i2sa->i2sa_rule->rule_config);
318
319 /* All unauthenticated IKEv2 SAs are considered larval */
320 if (!(i2sa->flags & I2SA_AUTHENTICATED))
321 dec_half_open();
322
323 /*
324 * XXX: we have potential circular references here
325 * as ikev2_pkt_t->sa and i2sa->init,
326 * i2sa->last_{resp_sent,sent,recvd} reference each other.
327 *
328 * We will need to sit and think about the lifecycles of
329 * these packets to make sure when we want this SA to go
330 * away for any reason, everything is properly cleaned up.
331 *
332 * For now, my thought is to punt until after the
333 * IKE_SA_INIT and IKE_AUTH exchanges are written, as that
334 * will likely help identify the best approach to resolving this.
335 */
336 pkt_free(i2sa->init);
337 pkt_free(i2sa->last_resp_sent);
338 pkt_free(i2sa->last_sent);
339 pkt_free(i2sa->last_recvd);
340
341 #define DESTROY(x, y) pkcs11_destroy_obj(#y, &(x)->y, i2sa->i2sa_log)
342 DESTROY(i2sa, dh_pubkey);
343 DESTROY(i2sa, dh_privkey);
344 DESTROY(i2sa, dh_key);
345 DESTROY(i2sa, sk_d);
346 DESTROY(i2sa, sk_ai);
347 DESTROY(i2sa, sk_ar);
348 DESTROY(i2sa, sk_ei);
349 DESTROY(i2sa, sk_er);
350 DESTROY(i2sa, sk_pi);
351 DESTROY(i2sa, sk_pr);
352 #undef DESTROY
353
354 /* TODO: free child SAs */
355
356 bunyan_fini(i2sa->i2sa_log);
357
358 i2sa_dtor(i2sa, NULL);
359 i2sa_ctor(i2sa, NULL, 0);
360 umem_cache_free(i2sa_cache, i2sa);
361 }
362
363 void
364 ikev2_sa_set_hashsize(uint_t numbuckets)
365 {
366 i2sa_bucket_t *old[I2SA_NUM_HASH];
367 int i, hashtbl;
368 boolean_t startup;
369
370 for (i = 0; i < I2SA_NUM_HASH; i++)
371 old[i] = hash[i];
372
373 if (old[LSPI] == NULL)
374 startup = B_TRUE;
375 else
376 startup = B_FALSE;
377
378 if (!startup)
379 worker_suspend();
380
381 /* round up to a power of two if not already */
382 if (!ISP2(numbuckets)) {
383 ASSERT(sizeof (numbuckets) == 4);
384 --numbuckets;
385 for (i = 1; i <= 16; i++)
386 numbuckets |= (numbuckets >> i);
387 ++numbuckets;
388 }
389 VERIFY(ISP2(numbuckets));
390
391 for (i = 0; i < I2SA_NUM_HASH; i++)
392 hash[i] = NULL;
393
394 /* Allocate new buckets */
395 for (i = 0; i < I2SA_NUM_HASH; i++) {
396 hash[i] = calloc(numbuckets, sizeof (i2sa_bucket_t));
397 if (hash[i] == NULL)
398 goto nomem;
399 }
400
401 uint32_t flags = UU_LIST_SORTED;
402
403 #ifdef DEBUG
404 flags |= UU_LIST_DEBUG;
405 #endif
406
407 for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++) {
408 for (i = 0; i < numbuckets; i++) {
409 hash[hashtbl][i].chain =
410 uu_list_create(list_pool[hashtbl], NULL, flags);
411 if (hash[hashtbl][i].chain == NULL)
412 goto nomem;
413
414 PTH(pthread_mutex_init(&hash[hashtbl][i].lock, NULL));
415 }
416 }
417
418 /* New tables means a new fudge factor. Pick one randomly. */
419 remote_noise = random_low_32();
420
421 i = num_buckets;
422
423 /* Set this so the hash functions work on the new buckets */
424 num_buckets = numbuckets;
425
426 if (startup)
427 return;
428
429 /*
430 * At this point, we've allocated all the necessary structures, so
431 * we can just move everything over to the new buckets. Since the
432 * only remaining reference to the old number of buckets here is i,
433 * we work backwards to free each chain, and invert the normal
434 * inner/outer loop order.
435 */
436 while (--i >= 0) {
437 for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++) {
438 uu_list_t *list;
439 ikev2_sa_t *i2sa;
440 void *cookie;
441
442 cookie = NULL;
443 list = hash[hashtbl][i].chain;
444 for (i2sa = uu_list_teardown(list, &cookie);
445 i2sa != NULL;
446 i2sa = uu_list_teardown(list, &cookie)) {
447 /*
448 * i2sa_add_to_hash() will create a new
449 * ref, so we cannot transfer the ref from
450 * the old hash into the new one, but must
451 * release it instead.
452 */
453 VERIFY(i2sa_add_to_hash(hashtbl, i2sa));
454 I2SA_REFRELE(i2sa);
455 }
456
457 PTH(pthread_mutex_destroy(&old[hashtbl][i].lock));
458 uu_list_destroy(old[hashtbl][i].chain);
459 }
460 }
461
462 for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++)
463 free(old[hashtbl]);
464
465 worker_resume();
466 return;
467
468 nomem:
469 if (startup)
470 errx(EXIT_FAILURE, "out of memory");
471
472 /* This will probably fail too, but worth a shot */
473 (void) bunyan_error(log, "out of memory", BUNYAN_T_STRING);
474
475 /*
476 * Free what the new stuff we've constructed so far, and put the
477 * old buckets back into place
478 */
479 for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++) {
480 if (hash[hashtbl] == NULL)
481 continue;
482 for (i = 0; i < numbuckets; i++) {
483 if (hash[hashtbl][i].chain != NULL)
484 uu_list_destroy(hash[hashtbl][i].chain);
485 }
486 free(hash[hashtbl]);
487 hash[hashtbl] = old[hashtbl];
488 }
489
490 worker_resume();
491 }
492
493 /*
494 * Set the remote SPI of an IKEv2 SA and add to the rhash
495 */
496 void
497 ikev2_sa_set_rspi(ikev2_sa_t *i2sa, uint64_t r_spi)
498 {
499 /* better not be set already */
500 ASSERT(i2sa->r_spi == 0);
501
502 /* never a valid SPI value */
503 ASSERT(r_spi != 0);
504
505 /*
506 * A bit confusing at times, but if we are the initiator of the
507 * SA, the responder (ikev2_sa_t->r_spi) is the remote spi,
508 * otherwise we are the responder, so the remote spi is the
509 * initiator (ikev2_sa_t->i_spi)
510 */
511 if (i2sa->flags & I2SA_INITIATOR)
512 i2sa->r_spi = r_spi;
513 else
514 i2sa->i_spi = r_spi;
515
516 VERIFY(i2sa_add_to_hash(RHASH, i2sa));
517 }
518
519 static i2sa_bucket_t *
520 i2sa_get_bucket(int hashtbl, ikev2_sa_t *i2sa)
521 {
522 i2sa_bucket_t *bucket;
523
524 VERIFY3S(hashtbl, <, I2SA_NUM_HASH);
525
526 bucket = hash[hashtbl];
527 switch (hashtbl) {
528 case LSPI:
529 bucket += IKEV2_SA_HASH_SPI(I2SA_LOCAL_SPI(i2sa));
530 break;
531 case RHASH:
532 bucket += IKEV2_SA_RHASH(&i2sa->raddr, I2SA_REMOTE_SPI(i2sa));
533 break;
534 }
535 return (bucket);
536 }
537
538
539 /*
540 * Add an IKEv2 SA to the given hash.
541 *
542 * Returns:
543 * B_TRUE successfully added, hash holds ref to IKEv2 SA
544 * B_FALSE IKEv2 SA already exists in hash, no ref held.
545 *
546 */
547 static boolean_t
548 i2sa_add_to_hash(int hashtbl, ikev2_sa_t *i2sa)
549 {
550 i2sa_bucket_t *bucket;
551 void *node;
552 i2sa_cmp_arg_t arg = { 0 };
553 uu_list_index_t idx;
554
555 VERIFY3S(hashtbl, <, I2SA_NUM_HASH);
556
557 bucket = i2sa_get_bucket(hashtbl, i2sa);
558 PTH(pthread_mutex_lock(&bucket->lock));
559
560 arg.hash = hashtbl;
561
562 /* Set idx to where the SA should be inserted */
563 node = uu_list_find(bucket->chain, i2sa, &arg, &idx);
564 if (node != NULL) {
565 /*
566 * Found a match, should only happen while choosing
567 * a local SPI value and we happen to pick one already
568 * in use.
569 */
570
571 VERIFY(node != i2sa);
572
573 /*
574 * XXX: Should we do anything different for an rhash
575 * match?
576 */
577 PTH(pthread_mutex_unlock(&bucket->lock));
578 return (B_FALSE);
579 }
580
581 I2SA_REFHOLD(i2sa); /* ref for chain */
582 i2sa->bucket[hashtbl] = bucket;
583 uu_list_insert(bucket->chain, i2sa, idx);
584 PTH(pthread_mutex_unlock(&bucket->lock));
585
586 return (B_TRUE);
587 }
588
589 static ikev2_sa_t *
590 i2sa_verify(ikev2_sa_t *restrict i2sa, uint64_t rem_spi,
591 const struct sockaddr_storage *laddr,
592 const struct sockaddr_storage *raddr)
593 {
594 if (i2sa == NULL)
595 return (NULL);
596
597 if (rem_spi != 0 && I2SA_REMOTE_SPI(i2sa) != rem_spi) {
598 /* XXX: log message */
599 goto bad_match;
600 }
601
602 if (laddr != NULL && !SA_ADDR_EQ(laddr, &i2sa->laddr)) {
603 /* XXX: log message */
604 goto bad_match;
605 }
606
607 if (raddr != NULL && !SA_ADDR_EQ(raddr, &i2sa->raddr)) {
608 /* XXX: log message */
609 goto bad_match;
610 }
611
612 /*
613 * XXX KEBE ASKS - if remote port changes, do remap?
614 * Probably have caller do this after packet is really legit.
615 */
616
617 /* XXX KEBE SAYS FILL IN OTHER REALITY CHECKS HERE. */
618
619 /* XXX: log full match */
620 return (i2sa);
621
622 bad_match:
623 I2SA_REFRELE(i2sa);
624 return (NULL);
625 }
626
627 static void
628 i2sa_hash_remove(int hashtbl, ikev2_sa_t *i2sa)
629 {
630 i2sa_bucket_t *bucket;
631
632 VERIFY3S(hashtbl, <, I2SA_NUM_HASH);
633 ASSERT(MUTEX_HELD(i2sa));
634
635 /* We shouldn't be holding the lock if this is the last reference */
636 ASSERT(i2sa->refcnt > 1);
637
638 bucket = i2sa_get_bucket(hashtbl, i2sa);
639 PTH(pthread_mutex_lock(&bucket->lock));
640 uu_list_remove(bucket->chain, i2sa);
641 i2sa->bucket[hashtbl] = NULL;
642 PTH(pthread_mutex_unlock(&bucket->lock));
643 I2SA_REFRELE(i2sa);
644 }
645
646 static void
647 i2sa_unlink(ikev2_sa_t *i2sa)
648 {
649 ASSERT(MUTEX_HELD(i2sa));
650 for (int i = 0; i < I2SA_NUM_HASH; i++)
651 i2sa_hash_remove(i, i2sa);
652 }
653
654 /*
655 * Generate a hash value for a remote SA based off the
656 * address and remote SPI.
657 */
658 static uint32_t
659 i2sa_rhash(const struct sockaddr_storage *ss, uint64_t spi)
660 {
661 uint32_t rc = remote_noise;
662 const uint32_t *ptr = (const uint32_t *)&spi;
663 sockaddr_u_t ssu;
664
665 rc ^= ptr[0];
666 rc ^= ptr[1];
667
668 ssu.sau_ss = (struct sockaddr_storage *)ss;
669 if (ss->ss_family == AF_INET6) {
670 ptr = (const uint32_t *)&ssu.sau_sin6->sin6_addr;
671 rc ^= ptr[0];
672 rc ^= ptr[1];
673 rc ^= ptr[2];
674 rc ^= ptr[3];
675 } else {
676 ASSERT(ss->ss_family == AF_INET);
677 rc ^= ssu.sau_sin->sin_addr.s_addr;
678 }
679
680 return (rc);
681 }
682
683 /*
684 * Increase the count of larval SAs. If we reach our threshold for larval SAs,
685 * enable the use of cookies.
686 */
687 static void
688 inc_half_open(void)
689 {
690 atomic_inc_uint(&half_open);
691
692 /* TODO: cookie check */
693 }
694
695 /*
696 * Decrease the count of larval SAs. Disable cookies if the count falls
697 * below the threshold
698 */
699 static void
700 dec_half_open(void)
701 {
702 atomic_dec_uint(&half_open);
703
704 /*
705 * TODO: Add cookie check. Include hystersis to avoid potential
706 * flopping.
707 */
708 }
709
710 static int
711 i2sa_ctor(void *buf, void *dummy, int flags)
712 {
713 _NOTE(ARGUNUSUED(dummy, flags))
714
715 ikev2_sa_t *i2sa = (ikev2_sa_t *)&buf;
716
717 (void) memset(i2sa, 0, sizeof (*i2sa));
718
719 PTH(pthread_mutex_init(&i2sa->lock, NULL));
720 for (size_t i = 0; i < ARRAY_SIZE(pool_names); i++) {
721 uu_list_node_init(buf,
722 (uu_list_node_t *)((uchar_t *)buf + pool_names[i].offset),
723 list_pool[i]);
724 }
725
726 i2sa->msgwin = 1;
727 return (0);
728 }
729
730 static void
731 i2sa_dtor(void *buf, void *dummy)
732 {
733 _NOTE(ARGUNUSUED(dummy))
734
735 ikev2_sa_t *i2sa = (ikev2_sa_t *)buf;
736
737 PTH(pthread_mutex_destroy(&i2sa->lock));
738 for (size_t i = 0; i < I2SA_NUM_HASH; i++) {
739 uu_list_node_fini(buf,
740 (uu_list_node_t *)((uchar_t *)buf + pool_names[i].offset),
741 list_pool[i]);
742 }
743 }
744
745 static int
746 sockaddr_compare(const struct sockaddr_storage *restrict l,
747 const struct sockaddr_storage *restrict r)
748 {
749 sockaddr_u_t lu;
750 sockaddr_u_t ru;
751 int cmp;
752
753 if (l->ss_family > r->ss_family)
754 return (1);
755 if (l->ss_family < r->ss_family)
756 return (-1);
757
758 lu.sau_ss = (struct sockaddr_storage *)l;
759 ru.sau_ss = (struct sockaddr_storage *)r;
760
761 if (l->ss_family == AF_INET) {
762 cmp = memcmp(&lu.sau_sin->sin_addr, &ru.sau_sin->sin_addr,
763 sizeof (lu.sau_sin->sin_addr));
764 if (cmp > 0)
765 return (1);
766 if (cmp < 0)
767 return (-1);
768
769 if (lu.sau_sin->sin_port > ru.sau_sin->sin_port)
770 return (1);
771 if (lu.sau_sin->sin_port < ru.sau_sin->sin_port)
772 return (-1);
773 return (0);
774 }
775
776 ASSERT(l->ss_family == AF_INET6);
777
778 cmp = memcmp(&lu.sau_sin6->sin6_addr, &ru.sau_sin6->sin6_addr,
779 sizeof (lu.sau_sin6->sin6_addr));
780 if (cmp > 0)
781 return (1);
782 if (cmp < 0)
783 return (-1);
784
785 if (lu.sau_sin6->sin6_port > ru.sau_sin6->sin6_port)
786 return (1);
787 if (lu.sau_sin6->sin6_port < ru.sau_sin6->sin6_port)
788 return (-1);
789 return (0);
790 }
791
792 /*
793 * This is called by uu_list_find() to find an IKEv2 SA. Since our
794 * uu_lists are sorted, it is also used to find the insertion spot
795 * in a hash chain. When finding an IKEv2 SA, rarg will be NULL and
796 * arg will have the information to compare. When finding an insertion
797 * spot, rarg will be the IKEv2 SA to insert to determine its location.
798 */
799 static int
800 i2sa_compare(const void *larg, const void *rarg, void *arg)
801 {
802 const ikev2_sa_t *l = (const ikev2_sa_t *)larg;
803 const ikev2_sa_t *r = (const ikev2_sa_t *)rarg;
804 i2sa_cmp_arg_t *carg = (i2sa_cmp_arg_t *)arg;
805 const uchar_t *lbuf, *rbuf;
806 uint64_t spi;
807 size_t lsz, rsz;
808 int cmp;
809
810 if (carg->hash == LSPI) {
811 ASSERT(MUTEX_HELD(&l->bucket[LSPI]->lock));
812 if (r != NULL) {
813 ASSERT(l->bucket[LSPI] == r->bucket[LSPI]);
814 spi = I2SA_LOCAL_SPI(r);
815 } else {
816 spi = carg->lspi;
817 }
818
819 ASSERT(spi != 0);
820
821 /*
822 * Since we assign the local SPI, we enforce that
823 * they are globally unique
824 */
825 if (I2SA_LOCAL_SPI(l) > spi)
826 return (1);
827 if (I2SA_LOCAL_SPI(l) < spi)
828 return (-1);
829 return (0);
830 }
831
832 ASSERT(carg->hash == RHASH);
833 ASSERT(MUTEX_HELD(l->bucket_lock_rhash));
834
835 i2sa_cmp_arg_t cmpdata = { 0 };
836 if (r != NULL) {
837 ASSERT3U(l->bucket_lock_rhash, ==, r->bucket_lock_rhash);
838 cmpdata.hash = RHASH;
839 cmpdata.rspi = I2SA_REMOTE_SPI(r);
840 cmpdata.raddr.sau_ss = (struct sockaddr_storage *)&r->raddr;
841 cmpdata.laddr.sau_ss = (struct sockaddr_storage *)&r->laddr;
842 cmpdata.init_pkt = r->init;
843 carg = &cmpdata;
844 }
845
846 if (I2SA_REMOTE_SPI(l) > carg->rspi)
847 return (1);
848 if (I2SA_REMOTE_SPI(l) < carg->rspi)
849 return (-1);
850
851 /* more likely to be different, so check these first */
852 cmp = sockaddr_compare(&l->raddr, carg->raddr.sau_ss);
853 if (cmp > 0)
854 return (1);
855 if (cmp < 0)
856 return (-1);
857
858 /* a multihomed system might have different local addresses */
859 cmp = sockaddr_compare(&l->laddr, carg->laddr.sau_ss);
860 if (cmp > 0)
861 return (1);
862 if (cmp < 0)
863 return (-1);
864
865 /*
866 * RFC5996 2.1 - We cannot merely rely on the remote SPI and
867 * address as clients behind NATs might choose the same SPI by chance.
868 * We must in addition look at the initial packet. This is only
869 * an issue for half-opened remotely initiated SAs, as this is the
870 * only time the local SPI is not yet known.
871 */
872 cmp = memcmp(l->init->pkt_raw, carg->init_pkt->pkt_raw,
873 MIN(pkt_len(l->init), pkt_len(carg->init_pkt)));
874 if (cmp != 0)
875 return ((cmp < 0) ? -1 : 1);
876 if (pkt_len(l->init) < pkt_len(carg->init_pkt))
877 return (-1);
878 if (pkt_len(l->init) > pkt_len(carg->init_pkt))
879 return (1);
880
881 return (0);
882 }
883
884 static boolean_t
885 i2sa_key_add_addr(ikev2_sa_t *i2sa, const char *addr_key, const char *port_key,
886 const struct sockaddr_storage *addr)
887 {
888 sockaddr_u_t sau;
889 sau.sau_ss = (struct sockaddr_storage *)addr;
890 int rc = 0;
891
892 switch (addr->ss_family) {
893 case AF_INET:
894 rc = bunyan_key_add(i2sa->i2sa_log,
895 BUNYAN_T_IP, addr_key, &sau.sau_sin->sin_addr,
896 BUNYAN_T_UINT32, port_key, (uint32_t)sau.sau_sin->sin_port,
897 BUNYAN_T_END);
898 break;
899 case AF_INET6:
900 rc = bunyan_key_add(i2sa->i2sa_log,
901 BUNYAN_T_IP6, addr_key, &sau.sau_sin6->sin6_addr,
902 BUNYAN_T_UINT32, port_key,
903 (uint32_t)sau.sau_sin6->sin6_port,
904 BUNYAN_T_END);
905 break;
906 default:
907 INVALID("addr->ss_family");
908 }
909
910 return ((rc == 0) ? B_TRUE : B_FALSE);
911 }
912
913 void
914 ikev2_sa_init(void)
915 {
916 uint32_t flag = UU_LIST_SORTED;
917
918 if ((i2sa_cache = umem_cache_create("IKEv2 SAs", sizeof (ikev2_sa_t),
919 0, i2sa_ctor, i2sa_dtor, NULL, NULL, NULL, 0)) == NULL)
920 err(EXIT_FAILURE, "Unable to allocate IKEv2 SA cache");
921
922 #ifdef DEBUG
923 flag |= UU_LIST_POOL_DEBUG;
924 #endif
925
926 for (int i = 0; i < ARRAY_SIZE(pool_names); i++) {
927 list_pool[i] = uu_list_pool_create(pool_names[i].name,
928 sizeof (ikev2_sa_t), pool_names[i].offset, i2sa_compare,
929 flag);
930
931 if (list_pool[i] != NULL)
932 err(EXIT_FAILURE,
933 "Unable to allocate IKEv2 SA hash chains");
934 }
935 }
936
937 void
938 ikev2_sa_fini(void)
939 {
940 umem_cache_destroy(i2sa_cache);
941 for (int i = 0; i < I2SA_NUM_HASH; i++)
942 uu_list_pool_destroy(list_pool[i]);
943 }