Merge commit 'ea01a15a654b9e1c7b37d958f4d1911882ed7781'
[unleashed.git] / kernel / net / ip / sadb.c
blobeb17669fe2731c096a6706a7371440937bdea669
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2018 Joyent, Inc.
28 #include <sys/types.h>
29 #include <sys/stream.h>
30 #include <sys/stropts.h>
31 #include <sys/strsubr.h>
32 #include <sys/errno.h>
33 #include <sys/ddi.h>
34 #include <sys/debug.h>
35 #include <sys/cmn_err.h>
36 #include <sys/stream.h>
37 #include <sys/strlog.h>
38 #include <sys/kmem.h>
39 #include <sys/sunddi.h>
40 #include <sys/tihdr.h>
41 #include <sys/atomic.h>
42 #include <sys/socket.h>
43 #include <sys/sysmacros.h>
44 #include <sys/crypto/common.h>
45 #include <sys/crypto/api.h>
46 #include <sys/zone.h>
47 #include <netinet/in.h>
48 #include <net/if.h>
49 #include <net/pfkeyv2.h>
50 #include <net/pfpolicy.h>
51 #include <inet/common.h>
52 #include <netinet/ip6.h>
53 #include <inet/ip.h>
54 #include <inet/ip_ire.h>
55 #include <inet/ip6.h>
56 #include <inet/ipsec_info.h>
57 #include <inet/tcp.h>
58 #include <inet/sadb.h>
59 #include <inet/ipsec_impl.h>
60 #include <inet/ipsecah.h>
61 #include <inet/ipsecesp.h>
62 #include <sys/random.h>
63 #include <sys/dlpi.h>
64 #include <sys/strsun.h>
65 #include <sys/strsubr.h>
66 #include <inet/ip_if.h>
67 #include <inet/ipdrop.h>
68 #include <inet/ipclassifier.h>
69 #include <inet/sctp_ip.h>
72 * This source file contains Security Association Database (SADB) common
73 * routines. They are linked in with the AH module. Since AH has no chance
74 * of falling under export control, it was safe to link it in there.
77 static uint8_t *sadb_action_to_ecomb(uint8_t *, uint8_t *, ipsec_action_t *,
78 netstack_t *);
79 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *);
80 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t,
81 netstack_t *);
82 static void sadb_destroy(sadb_t *, netstack_t *);
83 static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *);
85 static time_t sadb_add_time(time_t, uint64_t);
86 static void lifetime_fuzz(ipsa_t *);
87 static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t);
88 static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *);
89 static void init_ipsa_pair(ipsap_t *);
90 static void destroy_ipsa_pair(ipsap_t *);
91 static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *);
92 static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset);
95 * ipsacq_maxpackets is defined here to make it tunable
96 * from /etc/system.
98 extern uint64_t ipsacq_maxpackets;
100 #define SET_EXPIRE(sa, delta, exp) { \
101 if (((sa)->ipsa_ ## delta) != 0) { \
102 (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime, \
103 (sa)->ipsa_ ## delta); \
107 #define UPDATE_EXPIRE(sa, delta, exp) { \
108 if (((sa)->ipsa_ ## delta) != 0) { \
109 time_t tmp = sadb_add_time((sa)->ipsa_usetime, \
110 (sa)->ipsa_ ## delta); \
111 if (((sa)->ipsa_ ## exp) == 0) \
112 (sa)->ipsa_ ## exp = tmp; \
113 else \
114 (sa)->ipsa_ ## exp = \
115 MIN((sa)->ipsa_ ## exp, tmp); \
120 /* wrap the macro so we can pass it as a function pointer */
121 void
122 sadb_sa_refrele(void *target)
124 IPSA_REFRELE(((ipsa_t *)target));
128 * We presume that sizeof (long) == sizeof (time_t) and that time_t is
129 * a signed type.
131 #define TIME_MAX LONG_MAX
134 * PF_KEY gives us lifetimes in uint64_t seconds. We presume that
135 * time_t is defined to be a signed type with the same range as
136 * "long". On ILP32 systems, we thus run the risk of wrapping around
137 * at end of time, as well as "overwrapping" the clock back around
138 * into a seemingly valid but incorrect future date earlier than the
139 * desired expiration.
141 * In order to avoid odd behavior (either negative lifetimes or loss
142 * of high order bits) when someone asks for bizarrely long SA
143 * lifetimes, we do a saturating add for expire times.
145 * We presume that ILP32 systems will be past end of support life when
146 * the 32-bit time_t overflows (a dangerous assumption, mind you..).
148 * On LP64, 2^64 seconds are about 5.8e11 years, at which point we
149 * will hopefully have figured out clever ways to avoid the use of
150 * fixed-sized integers in computation.
152 static time_t
153 sadb_add_time(time_t base, uint64_t delta)
155 time_t sum;
158 * Clip delta to the maximum possible time_t value to
159 * prevent "overwrapping" back into a shorter-than-desired
160 * future time.
162 if (delta > TIME_MAX)
163 delta = TIME_MAX;
165 * This sum may still overflow.
167 sum = base + delta;
170 * .. so if the result is less than the base, we overflowed.
172 if (sum < base)
173 sum = TIME_MAX;
175 return (sum);
179 * Callers of this function have already created a working security
180 * association, and have found the appropriate table & hash chain. All this
181 * function does is check duplicates, and insert the SA. The caller needs to
182 * hold the hash bucket lock and increment the refcnt before insertion.
184 * Return 0 if success, EEXIST if collision.
186 #define SA_UNIQUE_MATCH(sa1, sa2) \
187 (((sa1)->ipsa_unique_id & (sa1)->ipsa_unique_mask) == \
188 ((sa2)->ipsa_unique_id & (sa2)->ipsa_unique_mask))
191 sadb_insertassoc(ipsa_t *ipsa, isaf_t *bucket)
193 ipsa_t **ptpn = NULL;
194 ipsa_t *walker;
195 boolean_t unspecsrc;
197 ASSERT(MUTEX_HELD(&bucket->isaf_lock));
199 unspecsrc = IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_srcaddr, ipsa->ipsa_addrfam);
201 walker = bucket->isaf_ipsa;
202 ASSERT(walker == NULL || ipsa->ipsa_addrfam == walker->ipsa_addrfam);
205 * Find insertion point (pointed to with **ptpn). Insert at the head
206 * of the list unless there's an unspecified source address, then
207 * insert it after the last SA with a specified source address.
209 * BTW, you'll have to walk the whole chain, matching on {DST, SPI}
210 * checking for collisions.
213 while (walker != NULL) {
214 if (IPSA_ARE_ADDR_EQUAL(walker->ipsa_dstaddr,
215 ipsa->ipsa_dstaddr, ipsa->ipsa_addrfam)) {
216 if (walker->ipsa_spi == ipsa->ipsa_spi)
217 return (EEXIST);
219 mutex_enter(&walker->ipsa_lock);
220 if (ipsa->ipsa_state == IPSA_STATE_MATURE &&
221 (walker->ipsa_flags & IPSA_F_USED) &&
222 SA_UNIQUE_MATCH(walker, ipsa)) {
223 walker->ipsa_flags |= IPSA_F_CINVALID;
225 mutex_exit(&walker->ipsa_lock);
228 if (ptpn == NULL && unspecsrc) {
229 if (IPSA_IS_ADDR_UNSPEC(walker->ipsa_srcaddr,
230 walker->ipsa_addrfam))
231 ptpn = walker->ipsa_ptpn;
232 else if (walker->ipsa_next == NULL)
233 ptpn = &walker->ipsa_next;
236 walker = walker->ipsa_next;
239 if (ptpn == NULL)
240 ptpn = &bucket->isaf_ipsa;
241 ipsa->ipsa_next = *ptpn;
242 ipsa->ipsa_ptpn = ptpn;
243 if (ipsa->ipsa_next != NULL)
244 ipsa->ipsa_next->ipsa_ptpn = &ipsa->ipsa_next;
245 *ptpn = ipsa;
246 ipsa->ipsa_linklock = &bucket->isaf_lock;
248 return (0);
250 #undef SA_UNIQUE_MATCH
253 * Free a security association. Its reference count is 0, which means
254 * I must free it. The SA must be unlocked and must not be linked into
255 * any fanout list.
257 static void
258 sadb_freeassoc(ipsa_t *ipsa)
260 ipsec_stack_t *ipss = ipsa->ipsa_netstack->netstack_ipsec;
261 mblk_t *asyncmp, *mp;
263 ASSERT(ipss != NULL);
264 ASSERT(MUTEX_NOT_HELD(&ipsa->ipsa_lock));
265 ASSERT(ipsa->ipsa_refcnt == 0);
266 ASSERT(ipsa->ipsa_next == NULL);
267 ASSERT(ipsa->ipsa_ptpn == NULL);
270 asyncmp = sadb_clear_lpkt(ipsa);
271 if (asyncmp != NULL) {
272 mp = ip_recv_attr_free_mblk(asyncmp);
273 ip_drop_packet(mp, B_TRUE, NULL,
274 DROPPER(ipss, ipds_sadb_inlarval_timeout),
275 &ipss->ipsec_sadb_dropper);
277 mutex_enter(&ipsa->ipsa_lock);
279 ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_AUTH);
280 ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_ENCR);
281 mutex_exit(&ipsa->ipsa_lock);
283 /* bzero() these fields for paranoia's sake. */
284 if (ipsa->ipsa_authkey != NULL) {
285 bzero(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
286 kmem_free(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
288 if (ipsa->ipsa_encrkey != NULL) {
289 bzero(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
290 kmem_free(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
292 if (ipsa->ipsa_nonce_buf != NULL) {
293 bzero(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
294 kmem_free(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
296 if (ipsa->ipsa_src_cid != NULL) {
297 IPSID_REFRELE(ipsa->ipsa_src_cid);
299 if (ipsa->ipsa_dst_cid != NULL) {
300 IPSID_REFRELE(ipsa->ipsa_dst_cid);
302 if (ipsa->ipsa_emech.cm_param != NULL)
303 kmem_free(ipsa->ipsa_emech.cm_param,
304 ipsa->ipsa_emech.cm_param_len);
306 mutex_destroy(&ipsa->ipsa_lock);
307 kmem_free(ipsa, sizeof (*ipsa));
311 * Unlink a security association from a hash bucket. Assume the hash bucket
312 * lock is held, but the association's lock is not.
314 * Note that we do not bump the bucket's generation number here because
315 * we might not be making a visible change to the set of visible SA's.
316 * All callers MUST bump the bucket's generation number before they unlock
317 * the bucket if they use sadb_unlinkassoc to permanetly remove an SA which
318 * was present in the bucket at the time it was locked.
320 void
321 sadb_unlinkassoc(ipsa_t *ipsa)
323 ASSERT(ipsa->ipsa_linklock != NULL);
324 ASSERT(MUTEX_HELD(ipsa->ipsa_linklock));
326 /* These fields are protected by the link lock. */
327 *(ipsa->ipsa_ptpn) = ipsa->ipsa_next;
328 if (ipsa->ipsa_next != NULL) {
329 ipsa->ipsa_next->ipsa_ptpn = ipsa->ipsa_ptpn;
330 ipsa->ipsa_next = NULL;
333 ipsa->ipsa_ptpn = NULL;
335 /* This may destroy the SA. */
336 IPSA_REFRELE(ipsa);
340 * Create a larval security association with the specified SPI. All other
341 * fields are zeroed.
343 static ipsa_t *
344 sadb_makelarvalassoc(uint32_t spi, uint32_t *src, uint32_t *dst, int addrfam,
345 netstack_t *ns)
347 ipsa_t *newbie;
350 * Allocate...
353 newbie = (ipsa_t *)kmem_zalloc(sizeof (ipsa_t), KM_NOSLEEP);
354 if (newbie == NULL) {
355 /* Can't make new larval SA. */
356 return (NULL);
359 /* Assigned requested SPI, assume caller does SPI allocation magic. */
360 newbie->ipsa_spi = spi;
361 newbie->ipsa_netstack = ns; /* No netstack_hold */
364 * Copy addresses...
367 IPSA_COPY_ADDR(newbie->ipsa_srcaddr, src, addrfam);
368 IPSA_COPY_ADDR(newbie->ipsa_dstaddr, dst, addrfam);
370 newbie->ipsa_addrfam = addrfam;
373 * Set common initialization values, including refcnt.
375 mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
376 newbie->ipsa_state = IPSA_STATE_LARVAL;
377 newbie->ipsa_refcnt = 1;
378 newbie->ipsa_freefunc = sadb_freeassoc;
381 * There aren't a lot of other common initialization values, as
382 * they are copied in from the PF_KEY message.
385 return (newbie);
389 * Call me to initialize a security association fanout.
391 static int
392 sadb_init_fanout(isaf_t **tablep, uint_t size, int kmflag)
394 isaf_t *table;
395 int i;
397 table = (isaf_t *)kmem_alloc(size * sizeof (*table), kmflag);
398 *tablep = table;
400 if (table == NULL)
401 return (ENOMEM);
403 for (i = 0; i < size; i++) {
404 mutex_init(&(table[i].isaf_lock), NULL, MUTEX_DEFAULT, NULL);
405 table[i].isaf_ipsa = NULL;
406 table[i].isaf_gen = 0;
409 return (0);
413 * Call me to initialize an acquire fanout
415 static int
416 sadb_init_acfanout(iacqf_t **tablep, uint_t size, int kmflag)
418 iacqf_t *table;
419 int i;
421 table = (iacqf_t *)kmem_alloc(size * sizeof (*table), kmflag);
422 *tablep = table;
424 if (table == NULL)
425 return (ENOMEM);
427 for (i = 0; i < size; i++) {
428 mutex_init(&(table[i].iacqf_lock), NULL, MUTEX_DEFAULT, NULL);
429 table[i].iacqf_ipsacq = NULL;
432 return (0);
436 * Attempt to initialize an SADB instance. On failure, return ENOMEM;
437 * caller must clean up partial allocations.
439 static int
440 sadb_init_trial(sadb_t *sp, uint_t size, int kmflag)
442 ASSERT(sp->sdb_of == NULL);
443 ASSERT(sp->sdb_if == NULL);
444 ASSERT(sp->sdb_acq == NULL);
446 sp->sdb_hashsize = size;
447 if (sadb_init_fanout(&sp->sdb_of, size, kmflag) != 0)
448 return (ENOMEM);
449 if (sadb_init_fanout(&sp->sdb_if, size, kmflag) != 0)
450 return (ENOMEM);
451 if (sadb_init_acfanout(&sp->sdb_acq, size, kmflag) != 0)
452 return (ENOMEM);
454 return (0);
458 * Call me to initialize an SADB instance; fall back to default size on failure.
460 static void
461 sadb_init(const char *name, sadb_t *sp, uint_t size, uint_t ver,
462 netstack_t *ns)
464 ASSERT(sp->sdb_of == NULL);
465 ASSERT(sp->sdb_if == NULL);
466 ASSERT(sp->sdb_acq == NULL);
468 if (size < IPSEC_DEFAULT_HASH_SIZE)
469 size = IPSEC_DEFAULT_HASH_SIZE;
471 if (sadb_init_trial(sp, size, KM_NOSLEEP) != 0) {
473 cmn_err(CE_WARN,
474 "Unable to allocate %u entry IPv%u %s SADB hash table",
475 size, ver, name);
477 sadb_destroy(sp, ns);
478 size = IPSEC_DEFAULT_HASH_SIZE;
479 cmn_err(CE_WARN, "Falling back to %d entries", size);
480 (void) sadb_init_trial(sp, size, KM_SLEEP);
486 * Initialize an SADB-pair.
488 void
489 sadbp_init(const char *name, sadbp_t *sp, int type, int size, netstack_t *ns)
491 sadb_init(name, &sp->s_v4, size, 4, ns);
492 sadb_init(name, &sp->s_v6, size, 6, ns);
494 sp->s_satype = type;
496 ASSERT((type == SADB_SATYPE_AH) || (type == SADB_SATYPE_ESP));
497 if (type == SADB_SATYPE_AH) {
498 ipsec_stack_t *ipss = ns->netstack_ipsec;
500 ip_drop_register(&ipss->ipsec_sadb_dropper, "IPsec SADB");
501 sp->s_addflags = AH_ADD_SETTABLE_FLAGS;
502 sp->s_updateflags = AH_UPDATE_SETTABLE_FLAGS;
503 } else {
504 sp->s_addflags = ESP_ADD_SETTABLE_FLAGS;
505 sp->s_updateflags = ESP_UPDATE_SETTABLE_FLAGS;
510 * Deliver a single SADB_DUMP message representing a single SA. This is
511 * called many times by sadb_dump().
513 * If the return value of this is ENOBUFS (not the same as ENOMEM), then
514 * the caller should take that as a hint that dupb() on the "original answer"
515 * failed, and that perhaps the caller should try again with a copyb()ed
516 * "original answer".
518 static int
519 sadb_dump_deliver(queue_t *pfkey_q, mblk_t *original_answer, ipsa_t *ipsa,
520 sadb_msg_t *samsg)
522 mblk_t *answer;
524 answer = dupb(original_answer);
525 if (answer == NULL)
526 return (ENOBUFS);
527 answer->b_cont = sadb_sa2msg(ipsa, samsg);
528 if (answer->b_cont == NULL) {
529 freeb(answer);
530 return (ENOMEM);
533 /* Just do a putnext, and let keysock deal with flow control. */
534 putnext(pfkey_q, answer);
535 return (0);
539 * Common function to allocate and prepare a keysock_out_t M_CTL message.
541 mblk_t *
542 sadb_keysock_out(minor_t serial)
544 mblk_t *mp;
545 keysock_out_t *kso;
547 mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
548 if (mp != NULL) {
549 mp->b_datap->db_type = M_CTL;
550 mp->b_wptr += sizeof (ipsec_info_t);
551 kso = (keysock_out_t *)mp->b_rptr;
552 kso->ks_out_type = KEYSOCK_OUT;
553 kso->ks_out_len = sizeof (*kso);
554 kso->ks_out_serial = serial;
557 return (mp);
561 * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
562 * to keysock.
564 static int
565 sadb_dump_fanout(queue_t *pfkey_q, mblk_t *mp, minor_t serial, isaf_t *fanout,
566 int num_entries, boolean_t do_peers, time_t active_time)
568 int i, error = 0;
569 mblk_t *original_answer;
570 ipsa_t *walker;
571 sadb_msg_t *samsg;
572 time_t current;
575 * For each IPSA hash bucket do:
576 * - Hold the mutex
577 * - Walk each entry, doing an sadb_dump_deliver() on it.
579 ASSERT(mp->b_cont != NULL);
580 samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
582 original_answer = sadb_keysock_out(serial);
583 if (original_answer == NULL)
584 return (ENOMEM);
586 current = gethrestime_sec();
587 for (i = 0; i < num_entries; i++) {
588 mutex_enter(&fanout[i].isaf_lock);
589 for (walker = fanout[i].isaf_ipsa; walker != NULL;
590 walker = walker->ipsa_next) {
591 if (!do_peers && walker->ipsa_haspeer)
592 continue;
593 if ((active_time != 0) &&
594 ((current - walker->ipsa_lastuse) > active_time))
595 continue;
596 error = sadb_dump_deliver(pfkey_q, original_answer,
597 walker, samsg);
598 if (error == ENOBUFS) {
599 mblk_t *new_original_answer;
601 /* Ran out of dupb's. Try a copyb. */
602 new_original_answer = copyb(original_answer);
603 if (new_original_answer == NULL) {
604 error = ENOMEM;
605 } else {
606 freeb(original_answer);
607 original_answer = new_original_answer;
608 error = sadb_dump_deliver(pfkey_q,
609 original_answer, walker, samsg);
612 if (error != 0)
613 break; /* out of for loop. */
615 mutex_exit(&fanout[i].isaf_lock);
616 if (error != 0)
617 break; /* out of for loop. */
620 freeb(original_answer);
621 return (error);
625 * Dump an entire SADB; outbound first, then inbound.
629 sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp)
631 int error;
632 time_t active_time = 0;
633 sadb_x_edump_t *edump =
634 (sadb_x_edump_t *)ksi->ks_in_extv[SADB_X_EXT_EDUMP];
636 if (edump != NULL) {
637 active_time = edump->sadb_x_edump_timeout;
640 /* Dump outbound */
641 error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of,
642 sp->sdb_hashsize, B_TRUE, active_time);
643 if (error)
644 return (error);
646 /* Dump inbound */
647 return sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if,
648 sp->sdb_hashsize, B_FALSE, active_time);
652 * Generic sadb table walker.
654 * Call "walkfn" for each SA in each bucket in "table"; pass the
655 * bucket, the entry and "cookie" to the callback function.
656 * Take care to ensure that walkfn can delete the SA without screwing
657 * up our traverse.
659 * The bucket is locked for the duration of the callback, both so that the
660 * callback can just call sadb_unlinkassoc() when it wants to delete something,
661 * and so that no new entries are added while we're walking the list.
663 static void
664 sadb_walker(isaf_t *table, uint_t numentries,
665 void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
666 void *cookie)
668 int i;
669 for (i = 0; i < numentries; i++) {
670 ipsa_t *entry, *next;
672 mutex_enter(&table[i].isaf_lock);
674 for (entry = table[i].isaf_ipsa; entry != NULL;
675 entry = next) {
676 next = entry->ipsa_next;
677 (*walkfn)(&table[i], entry, cookie);
679 mutex_exit(&table[i].isaf_lock);
684 * Call me to free up a security association fanout. Use the forever
685 * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
686 * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
687 * when a module is unloaded).
689 static void
690 sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever,
691 boolean_t inbound)
693 int i;
694 isaf_t *table = *tablep;
695 uint8_t protocol;
696 ipsa_t *sa;
697 netstackid_t sid;
699 if (table == NULL)
700 return;
702 for (i = 0; i < numentries; i++) {
703 mutex_enter(&table[i].isaf_lock);
704 while ((sa = table[i].isaf_ipsa) != NULL)
705 sadb_unlinkassoc(sa);
706 table[i].isaf_gen++;
707 mutex_exit(&table[i].isaf_lock);
708 if (forever)
709 mutex_destroy(&(table[i].isaf_lock));
712 if (forever) {
713 *tablep = NULL;
714 kmem_free(table, numentries * sizeof (*table));
719 * Entry points to sadb_destroyer().
721 static void
722 sadb_flush(sadb_t *sp, netstack_t *ns)
725 * Flush out each bucket, one at a time. Were it not for keysock's
726 * enforcement, there would be a subtlety where I could add on the
727 * heels of a flush. With keysock's enforcement, however, this
728 * makes ESP's job easy.
730 sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE, B_FALSE);
731 sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE, B_TRUE);
733 /* For each acquire, destroy it; leave the bucket mutex alone. */
734 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns);
737 static void
738 sadb_destroy(sadb_t *sp, netstack_t *ns)
740 sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE, B_FALSE);
741 sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE, B_TRUE);
743 /* For each acquire, destroy it, including the bucket mutex. */
744 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns);
746 ASSERT(sp->sdb_of == NULL);
747 ASSERT(sp->sdb_if == NULL);
748 ASSERT(sp->sdb_acq == NULL);
751 void
752 sadbp_flush(sadbp_t *spp, netstack_t *ns)
754 sadb_flush(&spp->s_v4, ns);
755 sadb_flush(&spp->s_v6, ns);
758 void
759 sadbp_destroy(sadbp_t *spp, netstack_t *ns)
761 sadb_destroy(&spp->s_v4, ns);
762 sadb_destroy(&spp->s_v6, ns);
764 if (spp->s_satype == SADB_SATYPE_AH) {
765 ipsec_stack_t *ipss = ns->netstack_ipsec;
767 ip_drop_unregister(&ipss->ipsec_sadb_dropper);
773 * Check hard vs. soft lifetimes. If there's a reality mismatch (e.g.
774 * soft lifetimes > hard lifetimes) return an appropriate diagnostic for
775 * EINVAL.
778 sadb_hardsoftchk(sadb_lifetime_t *hard, sadb_lifetime_t *soft,
779 sadb_lifetime_t *idle)
781 if (hard == NULL || soft == NULL)
782 return (0);
784 if (hard->sadb_lifetime_allocations != 0 &&
785 soft->sadb_lifetime_allocations != 0 &&
786 hard->sadb_lifetime_allocations < soft->sadb_lifetime_allocations)
787 return (SADB_X_DIAGNOSTIC_ALLOC_HSERR);
789 if (hard->sadb_lifetime_bytes != 0 &&
790 soft->sadb_lifetime_bytes != 0 &&
791 hard->sadb_lifetime_bytes < soft->sadb_lifetime_bytes)
792 return (SADB_X_DIAGNOSTIC_BYTES_HSERR);
794 if (hard->sadb_lifetime_addtime != 0 &&
795 soft->sadb_lifetime_addtime != 0 &&
796 hard->sadb_lifetime_addtime < soft->sadb_lifetime_addtime)
797 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
799 if (hard->sadb_lifetime_usetime != 0 &&
800 soft->sadb_lifetime_usetime != 0 &&
801 hard->sadb_lifetime_usetime < soft->sadb_lifetime_usetime)
802 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
804 if (idle != NULL) {
805 if (hard->sadb_lifetime_addtime != 0 &&
806 idle->sadb_lifetime_addtime != 0 &&
807 hard->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
808 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
810 if (soft->sadb_lifetime_addtime != 0 &&
811 idle->sadb_lifetime_addtime != 0 &&
812 soft->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
813 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
815 if (hard->sadb_lifetime_usetime != 0 &&
816 idle->sadb_lifetime_usetime != 0 &&
817 hard->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
818 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
820 if (soft->sadb_lifetime_usetime != 0 &&
821 idle->sadb_lifetime_usetime != 0 &&
822 soft->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
823 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
826 return (0);
830 * Clone a security association for the purposes of inserting a single SA
831 * into inbound and outbound tables respectively. This function should only
832 * be called from sadb_common_add().
834 static ipsa_t *
835 sadb_cloneassoc(ipsa_t *ipsa)
837 ipsa_t *newbie;
838 boolean_t error = B_FALSE;
840 ASSERT(MUTEX_NOT_HELD(&(ipsa->ipsa_lock)));
842 newbie = kmem_alloc(sizeof (ipsa_t), KM_NOSLEEP);
843 if (newbie == NULL)
844 return (NULL);
846 /* Copy over what we can. */
847 *newbie = *ipsa;
849 /* bzero and initialize locks, in case *_init() allocates... */
850 mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
853 * While somewhat dain-bramaged, the most graceful way to
854 * recover from errors is to keep plowing through the
855 * allocations, and getting what I can. It's easier to call
856 * sadb_freeassoc() on the stillborn clone when all the
857 * pointers aren't pointing to the parent's data.
860 if (ipsa->ipsa_authkey != NULL) {
861 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
862 KM_NOSLEEP);
863 if (newbie->ipsa_authkey == NULL) {
864 error = B_TRUE;
865 } else {
866 bcopy(ipsa->ipsa_authkey, newbie->ipsa_authkey,
867 newbie->ipsa_authkeylen);
869 newbie->ipsa_kcfauthkey.ck_data =
870 newbie->ipsa_authkey;
873 if (newbie->ipsa_amech.cm_param != NULL) {
874 newbie->ipsa_amech.cm_param =
875 (char *)&newbie->ipsa_mac_len;
879 if (ipsa->ipsa_encrkey != NULL) {
880 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
881 KM_NOSLEEP);
882 if (newbie->ipsa_encrkey == NULL) {
883 error = B_TRUE;
884 } else {
885 bcopy(ipsa->ipsa_encrkey, newbie->ipsa_encrkey,
886 newbie->ipsa_encrkeylen);
888 newbie->ipsa_kcfencrkey.ck_data =
889 newbie->ipsa_encrkey;
893 newbie->ipsa_authtmpl = NULL;
894 newbie->ipsa_encrtmpl = NULL;
895 newbie->ipsa_haspeer = B_TRUE;
897 if (ipsa->ipsa_src_cid != NULL) {
898 newbie->ipsa_src_cid = ipsa->ipsa_src_cid;
899 IPSID_REFHOLD(ipsa->ipsa_src_cid);
902 if (ipsa->ipsa_dst_cid != NULL) {
903 newbie->ipsa_dst_cid = ipsa->ipsa_dst_cid;
904 IPSID_REFHOLD(ipsa->ipsa_dst_cid);
907 if (error) {
908 sadb_freeassoc(newbie);
909 return (NULL);
912 return (newbie);
916 * Initialize a SADB address extension at the address specified by addrext.
917 * Return a pointer to the end of the new address extension.
919 static uint8_t *
920 sadb_make_addr_ext(uint8_t *start, uint8_t *end, uint16_t exttype,
921 sa_family_t af, uint32_t *addr, uint16_t port, uint8_t proto, int prefix)
923 struct sockaddr_in *sin;
924 struct sockaddr_in6 *sin6;
925 uint8_t *cur = start;
926 int addrext_len;
927 int sin_len;
928 sadb_address_t *addrext = (sadb_address_t *)cur;
930 if (cur == NULL)
931 return (NULL);
933 cur += sizeof (*addrext);
934 if (cur > end)
935 return (NULL);
937 addrext->sadb_address_proto = proto;
938 addrext->sadb_address_prefixlen = prefix;
939 addrext->sadb_address_reserved = 0;
940 addrext->sadb_address_exttype = exttype;
942 switch (af) {
943 case AF_INET:
944 sin = (struct sockaddr_in *)cur;
945 sin_len = sizeof (*sin);
946 cur += sin_len;
947 if (cur > end)
948 return (NULL);
950 sin->sin_family = af;
951 bzero(sin->sin_zero, sizeof (sin->sin_zero));
952 sin->sin_port = port;
953 IPSA_COPY_ADDR(&sin->sin_addr, addr, af);
954 break;
955 case AF_INET6:
956 sin6 = (struct sockaddr_in6 *)cur;
957 sin_len = sizeof (*sin6);
958 cur += sin_len;
959 if (cur > end)
960 return (NULL);
962 bzero(sin6, sizeof (*sin6));
963 sin6->sin6_family = af;
964 sin6->sin6_port = port;
965 IPSA_COPY_ADDR(&sin6->sin6_addr, addr, af);
966 break;
969 addrext_len = roundup(cur - start, sizeof (uint64_t));
970 addrext->sadb_address_len = SADB_8TO64(addrext_len);
972 cur = start + addrext_len;
973 if (cur > end)
974 cur = NULL;
976 return (cur);
980 * Construct a key management cookie extension.
983 static uint8_t *
984 sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint64_t kmc)
986 sadb_x_kmc_t *kmcext = (sadb_x_kmc_t *)cur;
988 if (cur == NULL)
989 return (NULL);
991 cur += sizeof (*kmcext);
993 if (cur > end)
994 return (NULL);
996 kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
997 kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
998 kmcext->sadb_x_kmc_proto = kmp;
999 kmcext->sadb_x_kmc_cookie64 = kmc;
1001 return (cur);
1005 * Given an original message header with sufficient space following it, and an
1006 * SA, construct a full PF_KEY message with all of the relevant extensions.
1007 * This is mostly used for SADB_GET, and SADB_DUMP.
1009 static mblk_t *
1010 sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg)
1012 int alloclen, addrsize, paddrsize, authsize, encrsize;
1013 int srcidsize, dstidsize, senslen, osenslen;
1014 sa_family_t fam, pfam; /* Address family for SADB_EXT_ADDRESS */
1015 /* src/dst and proxy sockaddrs. */
1017 * The following are pointers into the PF_KEY message this PF_KEY
1018 * message creates.
1020 sadb_msg_t *newsamsg;
1021 sadb_sa_t *assoc;
1022 sadb_lifetime_t *lt;
1023 sadb_key_t *key;
1024 sadb_ident_t *ident;
1025 sadb_ext_t *walker; /* For when we need a generic ext. pointer. */
1026 sadb_x_replay_ctr_t *repl_ctr;
1027 sadb_x_pair_t *pair_ext;
1029 mblk_t *mp;
1030 uint8_t *cur, *end;
1031 /* These indicate the presence of the above extension fields. */
1032 boolean_t soft = B_FALSE, hard = B_FALSE;
1033 boolean_t isrc = B_FALSE, idst = B_FALSE;
1034 boolean_t auth = B_FALSE, encr = B_FALSE;
1035 boolean_t srcid = B_FALSE, dstid = B_FALSE;
1036 boolean_t idle;
1037 boolean_t paired;
1038 uint32_t otherspi;
1040 /* First off, figure out the allocation length for this message. */
1042 * Constant stuff. This includes base, SA, address (src, dst),
1043 * and lifetime (current).
1045 alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) +
1046 sizeof (sadb_lifetime_t);
1048 fam = ipsa->ipsa_addrfam;
1049 switch (fam) {
1050 case AF_INET:
1051 addrsize = roundup(sizeof (struct sockaddr_in) +
1052 sizeof (sadb_address_t), sizeof (uint64_t));
1053 break;
1054 case AF_INET6:
1055 addrsize = roundup(sizeof (struct sockaddr_in6) +
1056 sizeof (sadb_address_t), sizeof (uint64_t));
1057 break;
1058 default:
1059 return (NULL);
1062 * Allocate TWO address extensions, for source and destination.
1063 * (Thus, the * 2.)
1065 alloclen += addrsize * 2;
1066 if (ipsa->ipsa_flags & IPSA_F_NATT_REM)
1067 alloclen += addrsize;
1068 if (ipsa->ipsa_flags & IPSA_F_NATT_LOC)
1069 alloclen += addrsize;
1071 if (ipsa->ipsa_flags & IPSA_F_PAIRED) {
1072 paired = B_TRUE;
1073 alloclen += sizeof (sadb_x_pair_t);
1074 otherspi = ipsa->ipsa_otherspi;
1075 } else {
1076 paired = B_FALSE;
1079 /* How 'bout other lifetimes? */
1080 if (ipsa->ipsa_softaddlt != 0 || ipsa->ipsa_softuselt != 0 ||
1081 ipsa->ipsa_softbyteslt != 0 || ipsa->ipsa_softalloc != 0) {
1082 alloclen += sizeof (sadb_lifetime_t);
1083 soft = B_TRUE;
1086 if (ipsa->ipsa_hardaddlt != 0 || ipsa->ipsa_harduselt != 0 ||
1087 ipsa->ipsa_hardbyteslt != 0 || ipsa->ipsa_hardalloc != 0) {
1088 alloclen += sizeof (sadb_lifetime_t);
1089 hard = B_TRUE;
1092 if (ipsa->ipsa_idleaddlt != 0 || ipsa->ipsa_idleuselt != 0) {
1093 alloclen += sizeof (sadb_lifetime_t);
1094 idle = B_TRUE;
1095 } else {
1096 idle = B_FALSE;
1099 /* Inner addresses. */
1100 if (ipsa->ipsa_innerfam != 0) {
1101 pfam = ipsa->ipsa_innerfam;
1102 switch (pfam) {
1103 case AF_INET6:
1104 paddrsize = roundup(sizeof (struct sockaddr_in6) +
1105 sizeof (sadb_address_t), sizeof (uint64_t));
1106 break;
1107 case AF_INET:
1108 paddrsize = roundup(sizeof (struct sockaddr_in) +
1109 sizeof (sadb_address_t), sizeof (uint64_t));
1110 break;
1111 default:
1112 cmn_err(CE_PANIC,
1113 "IPsec SADB: Proxy length failure.\n");
1114 break;
1116 isrc = B_TRUE;
1117 idst = B_TRUE;
1118 alloclen += 2 * paddrsize;
1121 /* For the following fields, assume that length != 0 ==> stuff */
1122 if (ipsa->ipsa_authkeylen != 0) {
1123 authsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_authkeylen,
1124 sizeof (uint64_t));
1125 alloclen += authsize;
1126 auth = B_TRUE;
1129 if (ipsa->ipsa_encrkeylen != 0) {
1130 encrsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_encrkeylen +
1131 ipsa->ipsa_nonce_len, sizeof (uint64_t));
1132 alloclen += encrsize;
1133 encr = B_TRUE;
1134 } else {
1135 encr = B_FALSE;
1139 * Must use strlen() here for lengths. Identities use NULL
1140 * pointers to indicate their nonexistence.
1142 if (ipsa->ipsa_src_cid != NULL) {
1143 srcidsize = roundup(sizeof (sadb_ident_t) +
1144 strlen(ipsa->ipsa_src_cid->ipsid_cid) + 1,
1145 sizeof (uint64_t));
1146 alloclen += srcidsize;
1147 srcid = B_TRUE;
1150 if (ipsa->ipsa_dst_cid != NULL) {
1151 dstidsize = roundup(sizeof (sadb_ident_t) +
1152 strlen(ipsa->ipsa_dst_cid->ipsid_cid) + 1,
1153 sizeof (uint64_t));
1154 alloclen += dstidsize;
1155 dstid = B_TRUE;
1158 if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0))
1159 alloclen += sizeof (sadb_x_kmc_t);
1161 if (ipsa->ipsa_replay != 0) {
1162 alloclen += sizeof (sadb_x_replay_ctr_t);
1165 /* Make sure the allocation length is a multiple of 8 bytes. */
1166 ASSERT((alloclen & 0x7) == 0);
1168 /* XXX Possibly make it esballoc, with a bzero-ing free_ftn. */
1169 mp = allocb(alloclen, BPRI_HI);
1170 if (mp == NULL)
1171 return (NULL);
1172 bzero(mp->b_rptr, alloclen);
1174 mp->b_wptr += alloclen;
1175 end = mp->b_wptr;
1176 newsamsg = (sadb_msg_t *)mp->b_rptr;
1177 *newsamsg = *samsg;
1178 newsamsg->sadb_msg_len = (uint16_t)SADB_8TO64(alloclen);
1180 mutex_enter(&ipsa->ipsa_lock); /* Since I'm grabbing SA fields... */
1182 newsamsg->sadb_msg_satype = ipsa->ipsa_type;
1184 assoc = (sadb_sa_t *)(newsamsg + 1);
1185 assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc));
1186 assoc->sadb_sa_exttype = SADB_EXT_SA;
1187 assoc->sadb_sa_spi = ipsa->ipsa_spi;
1188 assoc->sadb_sa_replay = ipsa->ipsa_replay_wsize;
1189 assoc->sadb_sa_state = ipsa->ipsa_state;
1190 assoc->sadb_sa_auth = ipsa->ipsa_auth_alg;
1191 assoc->sadb_sa_encrypt = ipsa->ipsa_encr_alg;
1192 assoc->sadb_sa_flags = ipsa->ipsa_flags;
1194 lt = (sadb_lifetime_t *)(assoc + 1);
1195 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1196 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
1197 /* We do not support the concept. */
1198 lt->sadb_lifetime_allocations = 0;
1199 lt->sadb_lifetime_bytes = ipsa->ipsa_bytes;
1200 lt->sadb_lifetime_addtime = ipsa->ipsa_addtime;
1201 lt->sadb_lifetime_usetime = ipsa->ipsa_usetime;
1203 if (hard) {
1204 lt++;
1205 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1206 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1207 lt->sadb_lifetime_allocations = ipsa->ipsa_hardalloc;
1208 lt->sadb_lifetime_bytes = ipsa->ipsa_hardbyteslt;
1209 lt->sadb_lifetime_addtime = ipsa->ipsa_hardaddlt;
1210 lt->sadb_lifetime_usetime = ipsa->ipsa_harduselt;
1213 if (soft) {
1214 lt++;
1215 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1216 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1217 lt->sadb_lifetime_allocations = ipsa->ipsa_softalloc;
1218 lt->sadb_lifetime_bytes = ipsa->ipsa_softbyteslt;
1219 lt->sadb_lifetime_addtime = ipsa->ipsa_softaddlt;
1220 lt->sadb_lifetime_usetime = ipsa->ipsa_softuselt;
1223 if (idle) {
1224 lt++;
1225 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1226 lt->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
1227 lt->sadb_lifetime_addtime = ipsa->ipsa_idleaddlt;
1228 lt->sadb_lifetime_usetime = ipsa->ipsa_idleuselt;
1231 cur = (uint8_t *)(lt + 1);
1233 /* NOTE: Don't fill in ports here if we are a tunnel-mode SA. */
1234 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, fam,
1235 ipsa->ipsa_srcaddr, (!isrc && !idst) ? SA_SRCPORT(ipsa) : 0,
1236 SA_PROTO(ipsa), 0);
1237 if (cur == NULL) {
1238 freemsg(mp);
1239 mp = NULL;
1240 goto bail;
1243 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, fam,
1244 ipsa->ipsa_dstaddr, (!isrc && !idst) ? SA_DSTPORT(ipsa) : 0,
1245 SA_PROTO(ipsa), 0);
1246 if (cur == NULL) {
1247 freemsg(mp);
1248 mp = NULL;
1249 goto bail;
1252 if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) {
1253 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_LOC,
1254 fam, &ipsa->ipsa_natt_addr_loc, ipsa->ipsa_local_nat_port,
1255 IPPROTO_UDP, 0);
1256 if (cur == NULL) {
1257 freemsg(mp);
1258 mp = NULL;
1259 goto bail;
1263 if (ipsa->ipsa_flags & IPSA_F_NATT_REM) {
1264 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_REM,
1265 fam, &ipsa->ipsa_natt_addr_rem, ipsa->ipsa_remote_nat_port,
1266 IPPROTO_UDP, 0);
1267 if (cur == NULL) {
1268 freemsg(mp);
1269 mp = NULL;
1270 goto bail;
1274 /* If we are a tunnel-mode SA, fill in the inner-selectors. */
1275 if (isrc) {
1276 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
1277 pfam, ipsa->ipsa_innersrc, SA_SRCPORT(ipsa),
1278 SA_IPROTO(ipsa), ipsa->ipsa_innersrcpfx);
1279 if (cur == NULL) {
1280 freemsg(mp);
1281 mp = NULL;
1282 goto bail;
1286 if (idst) {
1287 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
1288 pfam, ipsa->ipsa_innerdst, SA_DSTPORT(ipsa),
1289 SA_IPROTO(ipsa), ipsa->ipsa_innerdstpfx);
1290 if (cur == NULL) {
1291 freemsg(mp);
1292 mp = NULL;
1293 goto bail;
1297 if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) {
1298 cur = sadb_make_kmc_ext(cur, end,
1299 ipsa->ipsa_kmp, ipsa->ipsa_kmc);
1300 if (cur == NULL) {
1301 freemsg(mp);
1302 mp = NULL;
1303 goto bail;
1307 walker = (sadb_ext_t *)cur;
1308 if (auth) {
1309 key = (sadb_key_t *)walker;
1310 key->sadb_key_len = SADB_8TO64(authsize);
1311 key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
1312 key->sadb_key_bits = ipsa->ipsa_authkeybits;
1313 key->sadb_key_reserved = 0;
1314 bcopy(ipsa->ipsa_authkey, key + 1, ipsa->ipsa_authkeylen);
1315 walker = (sadb_ext_t *)((uint64_t *)walker +
1316 walker->sadb_ext_len);
1319 if (encr) {
1320 uint8_t *buf_ptr;
1321 key = (sadb_key_t *)walker;
1322 key->sadb_key_len = SADB_8TO64(encrsize);
1323 key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1324 key->sadb_key_bits = ipsa->ipsa_encrkeybits;
1325 key->sadb_key_reserved = ipsa->ipsa_saltbits;
1326 buf_ptr = (uint8_t *)(key + 1);
1327 bcopy(ipsa->ipsa_encrkey, buf_ptr, ipsa->ipsa_encrkeylen);
1328 if (ipsa->ipsa_salt != NULL) {
1329 buf_ptr += ipsa->ipsa_encrkeylen;
1330 bcopy(ipsa->ipsa_salt, buf_ptr, ipsa->ipsa_saltlen);
1332 walker = (sadb_ext_t *)((uint64_t *)walker +
1333 walker->sadb_ext_len);
1336 if (srcid) {
1337 ident = (sadb_ident_t *)walker;
1338 ident->sadb_ident_len = SADB_8TO64(srcidsize);
1339 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
1340 ident->sadb_ident_type = ipsa->ipsa_src_cid->ipsid_type;
1341 ident->sadb_ident_id = 0;
1342 ident->sadb_ident_reserved = 0;
1343 (void) strcpy((char *)(ident + 1),
1344 ipsa->ipsa_src_cid->ipsid_cid);
1345 walker = (sadb_ext_t *)((uint64_t *)walker +
1346 walker->sadb_ext_len);
1349 if (dstid) {
1350 ident = (sadb_ident_t *)walker;
1351 ident->sadb_ident_len = SADB_8TO64(dstidsize);
1352 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
1353 ident->sadb_ident_type = ipsa->ipsa_dst_cid->ipsid_type;
1354 ident->sadb_ident_id = 0;
1355 ident->sadb_ident_reserved = 0;
1356 (void) strcpy((char *)(ident + 1),
1357 ipsa->ipsa_dst_cid->ipsid_cid);
1358 walker = (sadb_ext_t *)((uint64_t *)walker +
1359 walker->sadb_ext_len);
1362 if (paired) {
1363 pair_ext = (sadb_x_pair_t *)walker;
1365 pair_ext->sadb_x_pair_len = SADB_8TO64(sizeof (sadb_x_pair_t));
1366 pair_ext->sadb_x_pair_exttype = SADB_X_EXT_PAIR;
1367 pair_ext->sadb_x_pair_spi = otherspi;
1369 walker = (sadb_ext_t *)((uint64_t *)walker +
1370 walker->sadb_ext_len);
1373 if (ipsa->ipsa_replay != 0) {
1374 repl_ctr = (sadb_x_replay_ctr_t *)walker;
1375 repl_ctr->sadb_x_rc_len = SADB_8TO64(sizeof (*repl_ctr));
1376 repl_ctr->sadb_x_rc_exttype = SADB_X_EXT_REPLAY_VALUE;
1377 repl_ctr->sadb_x_rc_replay32 = ipsa->ipsa_replay;
1378 repl_ctr->sadb_x_rc_replay64 = 0;
1379 walker = (sadb_ext_t *)(repl_ctr + 1);
1382 bail:
1383 /* Pardon any delays... */
1384 mutex_exit(&ipsa->ipsa_lock);
1386 return (mp);
1390 * Strip out key headers or unmarked headers (SADB_EXT_KEY_*, SADB_EXT_UNKNOWN)
1391 * and adjust base message accordingly.
1393 * Assume message is pulled up in one piece of contiguous memory.
1395 * Say if we start off with:
1397 * +------+----+-------------+-----------+---------------+---------------+
1398 * | base | SA | source addr | dest addr | rsrvd. or key | soft lifetime |
1399 * +------+----+-------------+-----------+---------------+---------------+
1401 * we will end up with
1403 * +------+----+-------------+-----------+---------------+
1404 * | base | SA | source addr | dest addr | soft lifetime |
1405 * +------+----+-------------+-----------+---------------+
1407 static void
1408 sadb_strip(sadb_msg_t *samsg)
1410 sadb_ext_t *ext;
1411 uint8_t *target = NULL;
1412 uint8_t *msgend;
1413 int sofar = SADB_8TO64(sizeof (*samsg));
1414 int copylen;
1416 ext = (sadb_ext_t *)(samsg + 1);
1417 msgend = (uint8_t *)samsg;
1418 msgend += SADB_64TO8(samsg->sadb_msg_len);
1419 while ((uint8_t *)ext < msgend) {
1420 if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1421 ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1422 ext->sadb_ext_type == SADB_X_EXT_EDUMP ||
1423 ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1425 * Aha! I found a header to be erased.
1428 if (target != NULL) {
1430 * If I had a previous header to be erased,
1431 * copy over it. I can get away with just
1432 * copying backwards because the target will
1433 * always be 8 bytes behind the source.
1435 copylen = ((uint8_t *)ext) - (target +
1436 SADB_64TO8(
1437 ((sadb_ext_t *)target)->sadb_ext_len));
1438 ovbcopy(((uint8_t *)ext - copylen), target,
1439 copylen);
1440 target += copylen;
1441 ((sadb_ext_t *)target)->sadb_ext_len =
1442 SADB_8TO64(((uint8_t *)ext) - target +
1443 SADB_64TO8(ext->sadb_ext_len));
1444 } else {
1445 target = (uint8_t *)ext;
1447 } else {
1448 sofar += ext->sadb_ext_len;
1451 ext = (sadb_ext_t *)(((uint64_t *)ext) + ext->sadb_ext_len);
1454 ASSERT((uint8_t *)ext == msgend);
1456 if (target != NULL) {
1457 copylen = ((uint8_t *)ext) - (target +
1458 SADB_64TO8(((sadb_ext_t *)target)->sadb_ext_len));
1459 if (copylen != 0)
1460 ovbcopy(((uint8_t *)ext - copylen), target, copylen);
1463 /* Adjust samsg. */
1464 samsg->sadb_msg_len = (uint16_t)sofar;
1466 /* Assume all of the rest is cleared by caller in sadb_pfkey_echo(). */
1470 * AH needs to send an error to PF_KEY. Assume mp points to an M_CTL
1471 * followed by an M_DATA with a PF_KEY message in it. The serial of
1472 * the sending keysock instance is included.
1474 void
1475 sadb_pfkey_error(queue_t *pfkey_q, mblk_t *mp, int error, int diagnostic,
1476 uint_t serial)
1478 mblk_t *msg = mp->b_cont;
1479 sadb_msg_t *samsg;
1480 keysock_out_t *kso;
1483 * Enough functions call this to merit a NULL queue check.
1485 if (pfkey_q == NULL) {
1486 freemsg(mp);
1487 return;
1490 ASSERT(msg != NULL);
1491 ASSERT((mp->b_wptr - mp->b_rptr) == sizeof (ipsec_info_t));
1492 ASSERT((msg->b_wptr - msg->b_rptr) >= sizeof (sadb_msg_t));
1493 samsg = (sadb_msg_t *)msg->b_rptr;
1494 kso = (keysock_out_t *)mp->b_rptr;
1496 kso->ks_out_type = KEYSOCK_OUT;
1497 kso->ks_out_len = sizeof (*kso);
1498 kso->ks_out_serial = serial;
1501 * Only send the base message up in the event of an error.
1502 * Don't worry about bzero()-ing, because it was probably bogus
1503 * anyway.
1505 msg->b_wptr = msg->b_rptr + sizeof (*samsg);
1506 samsg = (sadb_msg_t *)msg->b_rptr;
1507 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
1508 samsg->sadb_msg_errno = (uint8_t)error;
1509 if (diagnostic != SADB_X_DIAGNOSTIC_PRESET)
1510 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
1512 putnext(pfkey_q, mp);
1516 * Send a successful return packet back to keysock via the queue in pfkey_q.
1518 * Often, an SA is associated with the reply message, it's passed in if needed,
1519 * and NULL if not. BTW, that ipsa will have its refcnt appropriately held,
1520 * and the caller will release said refcnt.
1522 void
1523 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1524 keysock_in_t *ksi, ipsa_t *ipsa)
1526 keysock_out_t *kso;
1527 mblk_t *mp1;
1528 sadb_msg_t *newsamsg;
1529 uint8_t *oldend;
1531 ASSERT((mp->b_cont != NULL) &&
1532 ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1533 ((void *)mp->b_rptr == (void *)ksi));
1535 switch (samsg->sadb_msg_type) {
1536 case SADB_ADD:
1537 case SADB_UPDATE:
1538 case SADB_X_UPDATEPAIR:
1539 case SADB_X_DELPAIR_STATE:
1540 case SADB_FLUSH:
1541 case SADB_DUMP:
1543 * I have all of the message already. I just need to strip
1544 * out the keying material and echo the message back.
1546 * NOTE: for SADB_DUMP, the function sadb_dump() did the
1547 * work. When DUMP reaches here, it should only be a base
1548 * message.
1550 justecho:
1551 if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL ||
1552 ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL ||
1553 ksi->ks_in_extv[SADB_X_EXT_EDUMP] != NULL) {
1554 sadb_strip(samsg);
1555 /* Assume PF_KEY message is contiguous. */
1556 ASSERT(mp->b_cont->b_cont == NULL);
1557 oldend = mp->b_cont->b_wptr;
1558 mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1559 SADB_64TO8(samsg->sadb_msg_len);
1560 bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1562 break;
1563 case SADB_GET:
1565 * Do a lot of work here, because of the ipsa I just found.
1566 * First construct the new PF_KEY message, then abandon
1567 * the old one.
1569 mp1 = sadb_sa2msg(ipsa, samsg);
1570 if (mp1 == NULL) {
1571 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1572 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1573 return;
1575 freemsg(mp->b_cont);
1576 mp->b_cont = mp1;
1577 break;
1578 case SADB_DELETE:
1579 case SADB_X_DELPAIR:
1580 if (ipsa == NULL)
1581 goto justecho;
1583 * Because listening KMds may require more info, treat
1584 * DELETE like a special case of GET.
1586 mp1 = sadb_sa2msg(ipsa, samsg);
1587 if (mp1 == NULL) {
1588 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1589 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1590 return;
1592 newsamsg = (sadb_msg_t *)mp1->b_rptr;
1593 sadb_strip(newsamsg);
1594 oldend = mp1->b_wptr;
1595 mp1->b_wptr = mp1->b_rptr + SADB_64TO8(newsamsg->sadb_msg_len);
1596 bzero(mp1->b_wptr, oldend - mp1->b_wptr);
1597 freemsg(mp->b_cont);
1598 mp->b_cont = mp1;
1599 break;
1600 default:
1601 if (mp != NULL)
1602 freemsg(mp);
1603 return;
1606 /* ksi is now null and void. */
1607 kso = (keysock_out_t *)ksi;
1608 kso->ks_out_type = KEYSOCK_OUT;
1609 kso->ks_out_len = sizeof (*kso);
1610 kso->ks_out_serial = ksi->ks_in_serial;
1611 /* We're ready to send... */
1612 putnext(pfkey_q, mp);
1616 * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1618 void
1619 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1620 void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype)
1622 keysock_hello_ack_t *kha;
1623 queue_t *oldq;
1625 ASSERT(OTHERQ(q) != NULL);
1628 * First, check atomically that I'm the first and only keysock
1629 * instance.
1631 * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1632 * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1633 * messages.
1636 oldq = atomic_cas_ptr((void **)pfkey_qp, NULL, OTHERQ(q));
1637 if (oldq != NULL) {
1638 ASSERT(oldq != q);
1639 cmn_err(CE_WARN, "Danger! Multiple keysocks on top of %s.\n",
1640 (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1641 freemsg(mp);
1642 return;
1645 kha = (keysock_hello_ack_t *)mp->b_rptr;
1646 kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1647 kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1648 kha->ks_hello_satype = (uint8_t)satype;
1651 * If we made it past the atomic_cas_ptr, then we have "exclusive"
1652 * access to the timeout handle. Fire it off after the default ager
1653 * interval.
1655 *top = qtimeout(*pfkey_qp, ager, agerarg,
1656 drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000));
1658 putnext(*pfkey_qp, mp);
1662 * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate.
1664 * Check addresses themselves for wildcard or multicast.
1665 * Check ire table for local/non-local/broadcast.
1668 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial,
1669 netstack_t *ns)
1671 sadb_address_t *addr = (sadb_address_t *)ext;
1672 struct sockaddr_in *sin;
1673 struct sockaddr_in6 *sin6;
1674 int diagnostic, type;
1675 boolean_t normalized = B_FALSE;
1677 ASSERT(ext != NULL);
1678 ASSERT((ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC) ||
1679 (ext->sadb_ext_type == SADB_EXT_ADDRESS_DST) ||
1680 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ||
1681 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) ||
1682 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_LOC) ||
1683 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_REM));
1685 /* Assign both sockaddrs, the compiler will do the right thing. */
1686 sin = (struct sockaddr_in *)(addr + 1);
1687 sin6 = (struct sockaddr_in6 *)(addr + 1);
1689 if (sin6->sin6_family == AF_INET6) {
1690 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1692 * Convert to an AF_INET sockaddr. This means the
1693 * return messages will have the extra space, but have
1694 * AF_INET sockaddrs instead of AF_INET6.
1696 * Yes, RFC 2367 isn't clear on what to do here w.r.t.
1697 * mapped addresses, but since AF_INET6 ::ffff:<v4> is
1698 * equal to AF_INET <v4>, it shouldnt be a huge
1699 * problem.
1701 sin->sin_family = AF_INET;
1702 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
1703 &sin->sin_addr);
1704 bzero(&sin->sin_zero, sizeof (sin->sin_zero));
1705 normalized = B_TRUE;
1707 } else if (sin->sin_family != AF_INET) {
1708 switch (ext->sadb_ext_type) {
1709 case SADB_EXT_ADDRESS_SRC:
1710 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC_AF;
1711 break;
1712 case SADB_EXT_ADDRESS_DST:
1713 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
1714 break;
1715 case SADB_X_EXT_ADDRESS_INNER_SRC:
1716 diagnostic = SADB_X_DIAGNOSTIC_BAD_PROXY_AF;
1717 break;
1718 case SADB_X_EXT_ADDRESS_INNER_DST:
1719 diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF;
1720 break;
1721 case SADB_X_EXT_ADDRESS_NATT_LOC:
1722 diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF;
1723 break;
1724 case SADB_X_EXT_ADDRESS_NATT_REM:
1725 diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF;
1726 break;
1727 /* There is no default, see above ASSERT. */
1729 bail:
1730 if (pfkey_q != NULL) {
1731 sadb_pfkey_error(pfkey_q, mp, EINVAL, diagnostic,
1732 serial);
1733 } else {
1735 * Scribble in sadb_msg that we got passed in.
1736 * Overload "mp" to be an sadb_msg pointer.
1738 sadb_msg_t *samsg = (sadb_msg_t *)mp;
1740 samsg->sadb_msg_errno = EINVAL;
1741 samsg->sadb_x_msg_diagnostic = diagnostic;
1743 return (KS_IN_ADDR_UNKNOWN);
1746 if (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC ||
1747 ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) {
1749 * We need only check for prefix issues.
1752 /* Set diagnostic now, in case we need it later. */
1753 diagnostic =
1754 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ?
1755 SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC :
1756 SADB_X_DIAGNOSTIC_PREFIX_INNER_DST;
1758 if (normalized)
1759 addr->sadb_address_prefixlen -= 96;
1762 * Verify and mask out inner-addresses based on prefix length.
1764 if (sin->sin_family == AF_INET) {
1765 if (addr->sadb_address_prefixlen > 32)
1766 goto bail;
1767 sin->sin_addr.s_addr &=
1768 ip_plen_to_mask(addr->sadb_address_prefixlen);
1769 } else {
1770 in6_addr_t mask;
1772 ASSERT(sin->sin_family == AF_INET6);
1774 * ip_plen_to_mask_v6() returns NULL if the value in
1775 * question is out of range.
1777 if (ip_plen_to_mask_v6(addr->sadb_address_prefixlen,
1778 &mask) == NULL)
1779 goto bail;
1780 sin6->sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
1781 sin6->sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
1782 sin6->sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
1783 sin6->sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
1786 /* We don't care in these cases. */
1787 return (KS_IN_ADDR_DONTCARE);
1790 if (sin->sin_family == AF_INET6) {
1791 /* Check the easy ones now. */
1792 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
1793 return (KS_IN_ADDR_MBCAST);
1794 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
1795 return (KS_IN_ADDR_UNSPEC);
1797 * At this point, we're a unicast IPv6 address.
1799 * XXX Zones alert -> me/notme decision needs to be tempered
1800 * by what zone we're in when we go to zone-aware IPsec.
1802 if (ip_type_v6(&sin6->sin6_addr, ns->netstack_ip) ==
1803 IRE_LOCAL) {
1804 /* Hey hey, it's local. */
1805 return (KS_IN_ADDR_ME);
1807 } else {
1808 ASSERT(sin->sin_family == AF_INET);
1809 if (sin->sin_addr.s_addr == INADDR_ANY)
1810 return (KS_IN_ADDR_UNSPEC);
1811 if (CLASSD(sin->sin_addr.s_addr))
1812 return (KS_IN_ADDR_MBCAST);
1814 * At this point we're a unicast or broadcast IPv4 address.
1816 * Check if the address is IRE_BROADCAST or IRE_LOCAL.
1818 * XXX Zones alert -> me/notme decision needs to be tempered
1819 * by what zone we're in when we go to zone-aware IPsec.
1821 type = ip_type_v4(sin->sin_addr.s_addr, ns->netstack_ip);
1822 switch (type) {
1823 case IRE_LOCAL:
1824 return (KS_IN_ADDR_ME);
1825 case IRE_BROADCAST:
1826 return (KS_IN_ADDR_MBCAST);
1830 return (KS_IN_ADDR_NOTME);
1834 * Address normalizations and reality checks for inbound PF_KEY messages.
1836 * For the case of src == unspecified AF_INET6, and dst == AF_INET, convert
1837 * the source to AF_INET. Do the same for the inner sources.
1839 boolean_t
1840 sadb_addrfix(keysock_in_t *ksi, queue_t *pfkey_q, mblk_t *mp, netstack_t *ns)
1842 struct sockaddr_in *src, *isrc;
1843 struct sockaddr_in6 *dst, *idst;
1844 sadb_address_t *srcext, *dstext;
1845 uint16_t sport;
1846 sadb_ext_t **extv = ksi->ks_in_extv;
1847 int rc;
1849 if (extv[SADB_EXT_ADDRESS_SRC] != NULL) {
1850 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_SRC],
1851 ksi->ks_in_serial, ns);
1852 if (rc == KS_IN_ADDR_UNKNOWN)
1853 return (B_FALSE);
1854 if (rc == KS_IN_ADDR_MBCAST) {
1855 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1856 SADB_X_DIAGNOSTIC_BAD_SRC, ksi->ks_in_serial);
1857 return (B_FALSE);
1859 ksi->ks_in_srctype = rc;
1862 if (extv[SADB_EXT_ADDRESS_DST] != NULL) {
1863 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_DST],
1864 ksi->ks_in_serial, ns);
1865 if (rc == KS_IN_ADDR_UNKNOWN)
1866 return (B_FALSE);
1867 if (rc == KS_IN_ADDR_UNSPEC) {
1868 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1869 SADB_X_DIAGNOSTIC_BAD_DST, ksi->ks_in_serial);
1870 return (B_FALSE);
1872 ksi->ks_in_dsttype = rc;
1876 * NAT-Traversal addrs are simple enough to not require all of
1877 * the checks in sadb_addrcheck(). Just normalize or reject if not
1878 * AF_INET.
1880 if (extv[SADB_X_EXT_ADDRESS_NATT_LOC] != NULL) {
1881 rc = sadb_addrcheck(pfkey_q, mp,
1882 extv[SADB_X_EXT_ADDRESS_NATT_LOC], ksi->ks_in_serial, ns);
1885 * Local NAT-T addresses never use an IRE_LOCAL, so it should
1886 * always be NOTME, or UNSPEC (to handle both tunnel mode
1887 * AND local-port flexibility).
1889 if (rc != KS_IN_ADDR_NOTME && rc != KS_IN_ADDR_UNSPEC) {
1890 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1891 SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC,
1892 ksi->ks_in_serial);
1893 return (B_FALSE);
1895 src = (struct sockaddr_in *)
1896 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_LOC]) + 1);
1897 if (src->sin_family != AF_INET) {
1898 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1899 SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF,
1900 ksi->ks_in_serial);
1901 return (B_FALSE);
1905 if (extv[SADB_X_EXT_ADDRESS_NATT_REM] != NULL) {
1906 rc = sadb_addrcheck(pfkey_q, mp,
1907 extv[SADB_X_EXT_ADDRESS_NATT_REM], ksi->ks_in_serial, ns);
1910 * Remote NAT-T addresses never use an IRE_LOCAL, so it should
1911 * always be NOTME, or UNSPEC if it's a tunnel-mode SA.
1913 if (rc != KS_IN_ADDR_NOTME &&
1914 !(extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL &&
1915 rc == KS_IN_ADDR_UNSPEC)) {
1916 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1917 SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM,
1918 ksi->ks_in_serial);
1919 return (B_FALSE);
1921 src = (struct sockaddr_in *)
1922 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_REM]) + 1);
1923 if (src->sin_family != AF_INET) {
1924 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1925 SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF,
1926 ksi->ks_in_serial);
1927 return (B_FALSE);
1931 if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL) {
1932 if (extv[SADB_X_EXT_ADDRESS_INNER_DST] == NULL) {
1933 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1934 SADB_X_DIAGNOSTIC_MISSING_INNER_DST,
1935 ksi->ks_in_serial);
1936 return (B_FALSE);
1939 if (sadb_addrcheck(pfkey_q, mp,
1940 extv[SADB_X_EXT_ADDRESS_INNER_DST], ksi->ks_in_serial, ns)
1941 == KS_IN_ADDR_UNKNOWN ||
1942 sadb_addrcheck(pfkey_q, mp,
1943 extv[SADB_X_EXT_ADDRESS_INNER_SRC], ksi->ks_in_serial, ns)
1944 == KS_IN_ADDR_UNKNOWN)
1945 return (B_FALSE);
1947 isrc = (struct sockaddr_in *)
1948 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC]) +
1950 idst = (struct sockaddr_in6 *)
1951 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST]) +
1953 if (isrc->sin_family != idst->sin6_family) {
1954 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1955 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH,
1956 ksi->ks_in_serial);
1957 return (B_FALSE);
1959 } else if (extv[SADB_X_EXT_ADDRESS_INNER_DST] != NULL) {
1960 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1961 SADB_X_DIAGNOSTIC_MISSING_INNER_SRC,
1962 ksi->ks_in_serial);
1963 return (B_FALSE);
1964 } else {
1965 isrc = NULL; /* For inner/outer port check below. */
1968 dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST];
1969 srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC];
1971 if (dstext == NULL || srcext == NULL)
1972 return (B_TRUE);
1974 dst = (struct sockaddr_in6 *)(dstext + 1);
1975 src = (struct sockaddr_in *)(srcext + 1);
1977 if (isrc != NULL &&
1978 (isrc->sin_port != 0 || idst->sin6_port != 0) &&
1979 (src->sin_port != 0 || dst->sin6_port != 0)) {
1980 /* Can't set inner and outer ports in one SA. */
1981 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1982 SADB_X_DIAGNOSTIC_DUAL_PORT_SETS,
1983 ksi->ks_in_serial);
1984 return (B_FALSE);
1987 if (dst->sin6_family == src->sin_family)
1988 return (B_TRUE);
1990 if (srcext->sadb_address_proto != dstext->sadb_address_proto) {
1991 if (srcext->sadb_address_proto == 0) {
1992 srcext->sadb_address_proto = dstext->sadb_address_proto;
1993 } else if (dstext->sadb_address_proto == 0) {
1994 dstext->sadb_address_proto = srcext->sadb_address_proto;
1995 } else {
1996 /* Inequal protocols, neither were 0. Report error. */
1997 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1998 SADB_X_DIAGNOSTIC_PROTO_MISMATCH,
1999 ksi->ks_in_serial);
2000 return (B_FALSE);
2005 * With the exception of an unspec IPv6 source and an IPv4
2006 * destination, address families MUST me matched.
2008 if (src->sin_family == AF_INET ||
2009 ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC) {
2010 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2011 SADB_X_DIAGNOSTIC_AF_MISMATCH, ksi->ks_in_serial);
2012 return (B_FALSE);
2016 * Convert "src" to AF_INET INADDR_ANY. We rely on sin_port being
2017 * in the same place for sockaddr_in and sockaddr_in6.
2019 sport = src->sin_port;
2020 bzero(src, sizeof (*src));
2021 src->sin_family = AF_INET;
2022 src->sin_port = sport;
2024 return (B_TRUE);
2028 * Set the results in "addrtype", given an IRE as requested by
2029 * sadb_addrcheck().
2032 sadb_addrset(ire_t *ire)
2034 if ((ire->ire_type & IRE_BROADCAST) ||
2035 (ire->ire_ipversion == IPV4_VERSION && CLASSD(ire->ire_addr)) ||
2036 (ire->ire_ipversion == IPV6_VERSION &&
2037 IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6))))
2038 return (KS_IN_ADDR_MBCAST);
2039 if (ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK))
2040 return (KS_IN_ADDR_ME);
2041 return (KS_IN_ADDR_NOTME);
2045 * Match primitives..
2046 * !!! TODO: short term: inner selectors
2047 * ipv6 scope id (ifindex)
2048 * longer term: zone id. sensitivity label. uid.
2050 boolean_t
2051 sadb_match_spi(ipsa_query_t *sq, ipsa_t *sa)
2053 return (sq->spi == sa->ipsa_spi);
2056 boolean_t
2057 sadb_match_dst_v6(ipsa_query_t *sq, ipsa_t *sa)
2059 return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_dstaddr, sq->dstaddr, AF_INET6));
2062 boolean_t
2063 sadb_match_src_v6(ipsa_query_t *sq, ipsa_t *sa)
2065 return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_srcaddr, sq->srcaddr, AF_INET6));
2068 boolean_t
2069 sadb_match_dst_v4(ipsa_query_t *sq, ipsa_t *sa)
2071 return (sq->dstaddr[0] == sa->ipsa_dstaddr[0]);
2074 boolean_t
2075 sadb_match_src_v4(ipsa_query_t *sq, ipsa_t *sa)
2077 return (sq->srcaddr[0] == sa->ipsa_srcaddr[0]);
2080 boolean_t
2081 sadb_match_dstid(ipsa_query_t *sq, ipsa_t *sa)
2083 return ((sa->ipsa_dst_cid != NULL) &&
2084 (sq->didtype == sa->ipsa_dst_cid->ipsid_type) &&
2085 (strcmp(sq->didstr, sa->ipsa_dst_cid->ipsid_cid) == 0));
2088 boolean_t
2089 sadb_match_srcid(ipsa_query_t *sq, ipsa_t *sa)
2091 return ((sa->ipsa_src_cid != NULL) &&
2092 (sq->sidtype == sa->ipsa_src_cid->ipsid_type) &&
2093 (strcmp(sq->sidstr, sa->ipsa_src_cid->ipsid_cid) == 0));
2096 boolean_t
2097 sadb_match_kmc(ipsa_query_t *sq, ipsa_t *sa)
2099 #define M(a, b) (((a) == 0) || ((b) == 0) || ((a) == (b)))
2101 return (M(sq->kmc, sa->ipsa_kmc) && M(sq->kmp, sa->ipsa_kmp));
2103 #undef M
2107 * Common function which extracts several PF_KEY extensions for ease of
2108 * SADB matching.
2110 * XXX TODO: weed out ipsa_query_t fields not used during matching
2111 * or afterwards?
2114 sadb_form_query(keysock_in_t *ksi, uint32_t req, uint32_t match,
2115 ipsa_query_t *sq, int *diagnostic)
2117 int i;
2118 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2120 for (i = 0; i < IPSA_NMATCH; i++)
2121 sq->matchers[i] = NULL;
2123 ASSERT((req & ~match) == 0);
2125 sq->req = req;
2126 sq->dstext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2127 sq->srcext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2128 sq->assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2130 if ((req & IPSA_Q_DST) && (sq->dstext == NULL)) {
2131 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2132 return (EINVAL);
2134 if ((req & IPSA_Q_SRC) && (sq->srcext == NULL)) {
2135 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2136 return (EINVAL);
2138 if ((req & IPSA_Q_SA) && (sq->assoc == NULL)) {
2139 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2140 return (EINVAL);
2143 if (match & IPSA_Q_SA) {
2144 *mfpp++ = sadb_match_spi;
2145 sq->spi = sq->assoc->sadb_sa_spi;
2148 if (sq->dstext != NULL)
2149 sq->dst = (struct sockaddr_in *)(sq->dstext + 1);
2150 else {
2151 sq->dst = NULL;
2152 sq->dst6 = NULL;
2153 sq->dstaddr = NULL;
2156 if (sq->srcext != NULL)
2157 sq->src = (struct sockaddr_in *)(sq->srcext + 1);
2158 else {
2159 sq->src = NULL;
2160 sq->src6 = NULL;
2161 sq->srcaddr = NULL;
2164 if (sq->dst != NULL)
2165 sq->af = sq->dst->sin_family;
2166 else if (sq->src != NULL)
2167 sq->af = sq->src->sin_family;
2168 else
2169 sq->af = AF_INET;
2171 if (sq->af == AF_INET6) {
2172 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2173 *mfpp++ = sadb_match_dst_v6;
2174 sq->dst6 = (struct sockaddr_in6 *)sq->dst;
2175 sq->dstaddr = (uint32_t *)&(sq->dst6->sin6_addr);
2176 } else {
2177 match &= ~IPSA_Q_DST;
2178 sq->dstaddr = ALL_ZEROES_PTR;
2181 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2182 sq->src6 = (struct sockaddr_in6 *)(sq->srcext + 1);
2183 sq->srcaddr = (uint32_t *)&sq->src6->sin6_addr;
2184 if (sq->src6->sin6_family != AF_INET6) {
2185 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2186 return (EINVAL);
2188 *mfpp++ = sadb_match_src_v6;
2189 } else {
2190 match &= ~IPSA_Q_SRC;
2191 sq->srcaddr = ALL_ZEROES_PTR;
2193 } else {
2194 sq->src6 = sq->dst6 = NULL;
2195 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2196 *mfpp++ = sadb_match_dst_v4;
2197 sq->dstaddr = (uint32_t *)&sq->dst->sin_addr;
2198 } else {
2199 match &= ~IPSA_Q_DST;
2200 sq->dstaddr = ALL_ZEROES_PTR;
2202 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2203 sq->srcaddr = (uint32_t *)&sq->src->sin_addr;
2204 if (sq->src->sin_family != AF_INET) {
2205 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2206 return (EINVAL);
2208 *mfpp++ = sadb_match_src_v4;
2209 } else {
2210 match &= ~IPSA_Q_SRC;
2211 sq->srcaddr = ALL_ZEROES_PTR;
2215 sq->dstid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
2216 if ((match & IPSA_Q_DSTID) && (sq->dstid != NULL)) {
2217 sq->didstr = (char *)(sq->dstid + 1);
2218 sq->didtype = sq->dstid->sadb_ident_type;
2219 *mfpp++ = sadb_match_dstid;
2222 sq->srcid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
2224 if ((match & IPSA_Q_SRCID) && (sq->srcid != NULL)) {
2225 sq->sidstr = (char *)(sq->srcid + 1);
2226 sq->sidtype = sq->srcid->sadb_ident_type;
2227 *mfpp++ = sadb_match_srcid;
2230 sq->kmcext = (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2231 sq->kmc = 0;
2232 sq->kmp = 0;
2234 if ((match & IPSA_Q_KMC) && (sq->kmcext)) {
2235 sq->kmp = sq->kmcext->sadb_x_kmc_proto;
2237 * Be liberal in what we receive. Special-case the IKEv1
2238 * cookie, which closed-source in.iked assumes is 32 bits.
2239 * Now that we store all 64 bits, we should pre-zero the
2240 * reserved field on behalf of closed-source in.iked.
2242 if (sq->kmp == SADB_X_KMP_IKE) {
2243 /* Just in case in.iked is misbehaving... */
2244 sq->kmcext->sadb_x_kmc_reserved = 0;
2246 sq->kmc = sq->kmcext->sadb_x_kmc_cookie64;
2247 *mfpp++ = sadb_match_kmc;
2250 if (match & (IPSA_Q_INBOUND|IPSA_Q_OUTBOUND)) {
2251 if (sq->af == AF_INET6)
2252 sq->sp = &sq->spp->s_v6;
2253 else
2254 sq->sp = &sq->spp->s_v4;
2255 } else {
2256 sq->sp = NULL;
2259 if (match & IPSA_Q_INBOUND) {
2260 sq->inhash = INBOUND_HASH(sq->sp, sq->assoc->sadb_sa_spi);
2261 sq->inbound = &sq->sp->sdb_if[sq->inhash];
2262 } else {
2263 sq->inhash = 0;
2264 sq->inbound = NULL;
2267 if (match & IPSA_Q_OUTBOUND) {
2268 if (sq->af == AF_INET6) {
2269 sq->outhash = OUTBOUND_HASH_V6(sq->sp, *(sq->dstaddr));
2270 } else {
2271 sq->outhash = OUTBOUND_HASH_V4(sq->sp, *(sq->dstaddr));
2273 sq->outbound = &sq->sp->sdb_of[sq->outhash];
2274 } else {
2275 sq->outhash = 0;
2276 sq->outbound = NULL;
2278 sq->match = match;
2279 return (0);
2283 * Match an initialized query structure with a security association;
2284 * return B_TRUE on a match, B_FALSE on a miss.
2285 * Applies match functions set up by sadb_form_query() until one returns false.
2287 boolean_t
2288 sadb_match_query(ipsa_query_t *sq, ipsa_t *sa)
2290 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2291 ipsa_match_fn_t mfp;
2293 for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) {
2294 if (!mfp(sq, sa))
2295 return (B_FALSE);
2297 return (B_TRUE);
2301 * Walker callback function to delete sa's based on src/dst address.
2302 * Assumes that we're called with *head locked, no other locks held;
2303 * Conveniently, and not coincidentally, this is both what sadb_walker
2304 * gives us and also what sadb_unlinkassoc expects.
2306 struct sadb_purge_state
2308 ipsa_query_t sq;
2309 boolean_t inbnd;
2310 uint8_t sadb_sa_state;
2313 static void
2314 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2316 struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2318 ASSERT(MUTEX_HELD(&head->isaf_lock));
2320 mutex_enter(&entry->ipsa_lock);
2322 if (entry->ipsa_state == IPSA_STATE_LARVAL ||
2323 !sadb_match_query(&ps->sq, entry)) {
2324 mutex_exit(&entry->ipsa_lock);
2325 return;
2328 entry->ipsa_state = IPSA_STATE_DEAD;
2329 (void) sadb_torch_assoc(head, entry);
2333 * Common code to purge an SA with a matching src or dst address.
2334 * Don't kill larval SA's in such a purge.
2337 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2338 int *diagnostic, queue_t *pfkey_q)
2340 struct sadb_purge_state ps;
2341 int error = sadb_form_query(ksi, 0,
2342 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2343 &ps.sq, diagnostic);
2345 if (error != 0)
2346 return (error);
2349 * This is simple, crude, and effective.
2350 * Unimplemented optimizations (TBD):
2351 * - we can limit how many places we search based on where we
2352 * think the SA is filed.
2353 * - if we get a dst address, we can hash based on dst addr to find
2354 * the correct bucket in the outbound table.
2356 ps.inbnd = B_TRUE;
2357 sadb_walker(sp->sdb_if, sp->sdb_hashsize, sadb_purge_cb, &ps);
2358 ps.inbnd = B_FALSE;
2359 sadb_walker(sp->sdb_of, sp->sdb_hashsize, sadb_purge_cb, &ps);
2361 ASSERT(mp->b_cont != NULL);
2362 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2363 NULL);
2364 return (0);
2367 static void
2368 sadb_delpair_state_one(isaf_t *head, ipsa_t *entry, void *cookie)
2370 struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2371 isaf_t *inbound_bucket;
2372 ipsa_t *peer_assoc;
2373 ipsa_query_t *sq = &ps->sq;
2375 ASSERT(MUTEX_HELD(&head->isaf_lock));
2377 mutex_enter(&entry->ipsa_lock);
2379 if ((entry->ipsa_state != ps->sadb_sa_state) ||
2380 ((sq->srcaddr != NULL) &&
2381 !IPSA_ARE_ADDR_EQUAL(entry->ipsa_srcaddr, sq->srcaddr, sq->af))) {
2382 mutex_exit(&entry->ipsa_lock);
2383 return;
2387 * The isaf_t *, which is passed in , is always an outbound bucket,
2388 * and we are preserving the outbound-then-inbound hash-bucket lock
2389 * ordering. The sadb_walker() which triggers this function is called
2390 * only on the outbound fanout, and the corresponding inbound bucket
2391 * lock is safe to acquire here.
2394 if (entry->ipsa_haspeer) {
2395 inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_spi);
2396 mutex_enter(&inbound_bucket->isaf_lock);
2397 peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2398 entry->ipsa_spi, entry->ipsa_srcaddr,
2399 entry->ipsa_dstaddr, entry->ipsa_addrfam);
2400 } else {
2401 inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_otherspi);
2402 mutex_enter(&inbound_bucket->isaf_lock);
2403 peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2404 entry->ipsa_otherspi, entry->ipsa_dstaddr,
2405 entry->ipsa_srcaddr, entry->ipsa_addrfam);
2408 entry->ipsa_state = IPSA_STATE_DEAD;
2409 (void) sadb_torch_assoc(head, entry);
2410 if (peer_assoc != NULL) {
2411 mutex_enter(&peer_assoc->ipsa_lock);
2412 peer_assoc->ipsa_state = IPSA_STATE_DEAD;
2413 (void) sadb_torch_assoc(inbound_bucket, peer_assoc);
2415 mutex_exit(&inbound_bucket->isaf_lock);
2418 static int
2419 sadb_delpair_state(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2420 int *diagnostic, queue_t *pfkey_q)
2422 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2423 struct sadb_purge_state ps;
2424 int error;
2426 ps.sq.spp = spp; /* XXX param */
2428 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SRC,
2429 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2430 &ps.sq, diagnostic);
2431 if (error != 0)
2432 return (error);
2434 ps.inbnd = B_FALSE;
2435 ps.sadb_sa_state = assoc->sadb_sa_state;
2436 sadb_walker(ps.sq.sp->sdb_of, ps.sq.sp->sdb_hashsize,
2437 sadb_delpair_state_one, &ps);
2439 ASSERT(mp->b_cont != NULL);
2440 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
2441 ksi, NULL);
2442 return (0);
2446 * Common code to delete/get an SA.
2449 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2450 int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type)
2452 ipsa_query_t sq;
2453 ipsa_t *echo_target = NULL;
2454 ipsap_t ipsapp;
2455 uint_t error = 0;
2457 if (sadb_msg_type == SADB_X_DELPAIR_STATE)
2458 return (sadb_delpair_state(mp, ksi, spp, diagnostic, pfkey_q));
2460 sq.spp = spp; /* XXX param */
2461 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA,
2462 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
2463 &sq, diagnostic);
2464 if (error != 0)
2465 return (error);
2467 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
2468 if (error != 0) {
2469 return (error);
2472 echo_target = ipsapp.ipsap_sa_ptr;
2473 if (echo_target == NULL)
2474 echo_target = ipsapp.ipsap_psa_ptr;
2476 if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) {
2478 * Bucket locks will be required if SA is actually unlinked.
2479 * get_ipsa_pair() returns valid hash bucket pointers even
2480 * if it can't find a pair SA pointer. To prevent a potential
2481 * deadlock, always lock the outbound bucket before the inbound.
2483 if (ipsapp.in_inbound_table) {
2484 mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2485 mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2486 } else {
2487 mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2488 mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2491 if (ipsapp.ipsap_sa_ptr != NULL) {
2492 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
2493 ipsapp.ipsap_sa_ptr->ipsa_state = IPSA_STATE_DEAD;
2494 (void) sadb_torch_assoc(ipsapp.ipsap_bucket,
2495 ipsapp.ipsap_sa_ptr);
2497 * sadb_torch_assoc() releases the ipsa_lock
2498 * and calls sadb_unlinkassoc() which does a
2499 * IPSA_REFRELE.
2502 if (ipsapp.ipsap_psa_ptr != NULL) {
2503 mutex_enter(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2504 if (sadb_msg_type == SADB_X_DELPAIR ||
2505 ipsapp.ipsap_psa_ptr->ipsa_haspeer) {
2506 ipsapp.ipsap_psa_ptr->ipsa_state =
2507 IPSA_STATE_DEAD;
2508 (void) sadb_torch_assoc(ipsapp.ipsap_pbucket,
2509 ipsapp.ipsap_psa_ptr);
2510 } else {
2512 * Only half of the "pair" has been deleted.
2513 * Update the remaining SA and remove references
2514 * to its pair SA, which is now gone.
2516 ipsapp.ipsap_psa_ptr->ipsa_otherspi = 0;
2517 ipsapp.ipsap_psa_ptr->ipsa_flags &=
2518 ~IPSA_F_PAIRED;
2519 mutex_exit(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2521 } else if (sadb_msg_type == SADB_X_DELPAIR) {
2522 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
2523 error = ESRCH;
2525 mutex_exit(&ipsapp.ipsap_bucket->isaf_lock);
2526 mutex_exit(&ipsapp.ipsap_pbucket->isaf_lock);
2529 ASSERT(mp->b_cont != NULL);
2531 if (error == 0)
2532 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)
2533 mp->b_cont->b_rptr, ksi, echo_target);
2535 destroy_ipsa_pair(&ipsapp);
2537 return (error);
2541 * This function takes a sadb_sa_t and finds the ipsa_t structure
2542 * and the isaf_t (hash bucket) that its stored under. If the security
2543 * association has a peer, the ipsa_t structure and bucket for that security
2544 * association are also searched for. The "pair" of ipsa_t's and isaf_t's
2545 * are returned as a ipsap_t.
2547 * The hash buckets are returned for convenience, if the calling function
2548 * needs to use the hash bucket locks, say to remove the SA's, it should
2549 * take care to observe the convention of locking outbound bucket then
2550 * inbound bucket. The flag in_inbound_table provides direction.
2552 * Note that a "pair" is defined as one (but not both) of the following:
2554 * A security association which has a soft reference to another security
2555 * association via its SPI.
2557 * A security association that is not obviously "inbound" or "outbound" so
2558 * it appears in both hash tables, the "peer" being the same security
2559 * association in the other hash table.
2561 * This function will return NULL if the ipsa_t can't be found in the
2562 * inbound or outbound hash tables (not found). If only one ipsa_t is
2563 * found, the pair ipsa_t will be NULL. Both isaf_t values are valid
2564 * provided at least one ipsa_t is found.
2566 static int
2567 get_ipsa_pair(ipsa_query_t *sq, ipsap_t *ipsapp, int *diagnostic)
2569 uint32_t pair_srcaddr[IPSA_MAX_ADDRLEN];
2570 uint32_t pair_dstaddr[IPSA_MAX_ADDRLEN];
2571 uint32_t pair_spi;
2573 init_ipsa_pair(ipsapp);
2575 ipsapp->in_inbound_table = B_FALSE;
2577 /* Lock down both buckets. */
2578 mutex_enter(&sq->outbound->isaf_lock);
2579 mutex_enter(&sq->inbound->isaf_lock);
2581 if (sq->assoc->sadb_sa_flags & IPSA_F_INBOUND) {
2582 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2583 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2584 if (ipsapp->ipsap_sa_ptr != NULL) {
2585 ipsapp->ipsap_bucket = sq->inbound;
2586 ipsapp->ipsap_pbucket = sq->outbound;
2587 ipsapp->in_inbound_table = B_TRUE;
2588 } else {
2589 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->outbound,
2590 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2591 sq->af);
2592 ipsapp->ipsap_bucket = sq->outbound;
2593 ipsapp->ipsap_pbucket = sq->inbound;
2595 } else {
2596 /* IPSA_F_OUTBOUND is set *or* no directions flags set. */
2597 ipsapp->ipsap_sa_ptr =
2598 ipsec_getassocbyspi(sq->outbound,
2599 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2600 if (ipsapp->ipsap_sa_ptr != NULL) {
2601 ipsapp->ipsap_bucket = sq->outbound;
2602 ipsapp->ipsap_pbucket = sq->inbound;
2603 } else {
2604 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2605 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2606 sq->af);
2607 ipsapp->ipsap_bucket = sq->inbound;
2608 ipsapp->ipsap_pbucket = sq->outbound;
2609 if (ipsapp->ipsap_sa_ptr != NULL)
2610 ipsapp->in_inbound_table = B_TRUE;
2614 if (ipsapp->ipsap_sa_ptr == NULL) {
2615 mutex_exit(&sq->outbound->isaf_lock);
2616 mutex_exit(&sq->inbound->isaf_lock);
2617 *diagnostic = SADB_X_DIAGNOSTIC_SA_NOTFOUND;
2618 return (ESRCH);
2621 if ((ipsapp->ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) &&
2622 ipsapp->in_inbound_table) {
2623 mutex_exit(&sq->outbound->isaf_lock);
2624 mutex_exit(&sq->inbound->isaf_lock);
2625 return (0);
2628 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2629 if (ipsapp->ipsap_sa_ptr->ipsa_haspeer) {
2631 * haspeer implies no sa_pairing, look for same spi
2632 * in other hashtable.
2634 ipsapp->ipsap_psa_ptr =
2635 ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2636 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2637 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2638 mutex_exit(&sq->outbound->isaf_lock);
2639 mutex_exit(&sq->inbound->isaf_lock);
2640 return (0);
2642 pair_spi = ipsapp->ipsap_sa_ptr->ipsa_otherspi;
2643 IPSA_COPY_ADDR(&pair_srcaddr,
2644 ipsapp->ipsap_sa_ptr->ipsa_srcaddr, sq->af);
2645 IPSA_COPY_ADDR(&pair_dstaddr,
2646 ipsapp->ipsap_sa_ptr->ipsa_dstaddr, sq->af);
2647 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2648 mutex_exit(&sq->inbound->isaf_lock);
2649 mutex_exit(&sq->outbound->isaf_lock);
2651 if (pair_spi == 0) {
2652 ASSERT(ipsapp->ipsap_bucket != NULL);
2653 ASSERT(ipsapp->ipsap_pbucket != NULL);
2654 return (0);
2657 /* found sa in outbound sadb, peer should be inbound */
2659 if (ipsapp->in_inbound_table) {
2660 /* Found SA in inbound table, pair will be in outbound. */
2661 if (sq->af == AF_INET6) {
2662 ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V6(sq->sp,
2663 *(uint32_t *)pair_srcaddr);
2664 } else {
2665 ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V4(sq->sp,
2666 *(uint32_t *)pair_srcaddr);
2668 } else {
2669 ipsapp->ipsap_pbucket = INBOUND_BUCKET(sq->sp, pair_spi);
2671 mutex_enter(&ipsapp->ipsap_pbucket->isaf_lock);
2672 ipsapp->ipsap_psa_ptr = ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2673 pair_spi, pair_dstaddr, pair_srcaddr, sq->af);
2674 mutex_exit(&ipsapp->ipsap_pbucket->isaf_lock);
2675 ASSERT(ipsapp->ipsap_bucket != NULL);
2676 ASSERT(ipsapp->ipsap_pbucket != NULL);
2677 return (0);
2681 * Perform NAT-traversal cached checksum offset calculations here.
2683 static void
2684 sadb_nat_calculations(ipsa_t *newbie, sadb_address_t *natt_loc_ext,
2685 sadb_address_t *natt_rem_ext, uint32_t *src_addr_ptr,
2686 uint32_t *dst_addr_ptr)
2688 struct sockaddr_in *natt_loc, *natt_rem;
2689 uint32_t *natt_loc_ptr = NULL, *natt_rem_ptr = NULL;
2690 uint32_t running_sum = 0;
2692 #define DOWN_SUM(x) (x) = ((x) & 0xFFFF) + ((x) >> 16)
2694 if (natt_rem_ext != NULL) {
2695 uint32_t l_src;
2696 uint32_t l_rem;
2698 natt_rem = (struct sockaddr_in *)(natt_rem_ext + 1);
2700 /* Ensured by sadb_addrfix(). */
2701 ASSERT(natt_rem->sin_family == AF_INET);
2703 natt_rem_ptr = (uint32_t *)(&natt_rem->sin_addr);
2704 newbie->ipsa_remote_nat_port = natt_rem->sin_port;
2705 l_src = *src_addr_ptr;
2706 l_rem = *natt_rem_ptr;
2708 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2709 newbie->ipsa_natt_addr_rem = *natt_rem_ptr;
2711 l_src = ntohl(l_src);
2712 DOWN_SUM(l_src);
2713 DOWN_SUM(l_src);
2714 l_rem = ntohl(l_rem);
2715 DOWN_SUM(l_rem);
2716 DOWN_SUM(l_rem);
2719 * We're 1's complement for checksums, so check for wraparound
2720 * here.
2722 if (l_rem > l_src)
2723 l_src--;
2725 running_sum += l_src - l_rem;
2727 DOWN_SUM(running_sum);
2728 DOWN_SUM(running_sum);
2731 if (natt_loc_ext != NULL) {
2732 natt_loc = (struct sockaddr_in *)(natt_loc_ext + 1);
2734 /* Ensured by sadb_addrfix(). */
2735 ASSERT(natt_loc->sin_family == AF_INET);
2737 natt_loc_ptr = (uint32_t *)(&natt_loc->sin_addr);
2738 newbie->ipsa_local_nat_port = natt_loc->sin_port;
2740 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2741 newbie->ipsa_natt_addr_loc = *natt_loc_ptr;
2744 * NAT-T port agility means we may have natt_loc_ext, but
2745 * only for a local-port change.
2747 if (natt_loc->sin_addr.s_addr != INADDR_ANY) {
2748 uint32_t l_dst = ntohl(*dst_addr_ptr);
2749 uint32_t l_loc = ntohl(*natt_loc_ptr);
2751 DOWN_SUM(l_loc);
2752 DOWN_SUM(l_loc);
2753 DOWN_SUM(l_dst);
2754 DOWN_SUM(l_dst);
2757 * We're 1's complement for checksums, so check for
2758 * wraparound here.
2760 if (l_loc > l_dst)
2761 l_dst--;
2763 running_sum += l_dst - l_loc;
2764 DOWN_SUM(running_sum);
2765 DOWN_SUM(running_sum);
2769 newbie->ipsa_inbound_cksum = running_sum;
2770 #undef DOWN_SUM
2774 * This function is called from consumers that need to insert a fully-grown
2775 * security association into its tables. This function takes into account that
2776 * SAs can be "inbound", "outbound", or "both". The "primary" and "secondary"
2777 * hash bucket parameters are set in order of what the SA will be most of the
2778 * time. (For example, an SA with an unspecified source, and a multicast
2779 * destination will primarily be an outbound SA. OTOH, if that destination
2780 * is unicast for this node, then the SA will primarily be inbound.)
2782 * It takes a lot of parameters because even if clone is B_FALSE, this needs
2783 * to check both buckets for purposes of collision.
2785 * Return 0 upon success. Return various errnos (ENOMEM, EEXIST) for
2786 * various error conditions. We may need to set samsg->sadb_x_msg_diagnostic
2787 * with additional diagnostic information because there is at least one EINVAL
2788 * case here.
2791 sadb_common_add(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
2792 keysock_in_t *ksi, isaf_t *primary, isaf_t *secondary,
2793 ipsa_t *newbie, boolean_t clone, boolean_t is_inbound, int *diagnostic,
2794 netstack_t *ns, sadbp_t *spp)
2796 ipsa_t *newbie_clone = NULL, *scratch;
2797 ipsap_t ipsapp;
2798 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2799 sadb_address_t *srcext =
2800 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2801 sadb_address_t *dstext =
2802 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2803 sadb_address_t *isrcext =
2804 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC];
2805 sadb_address_t *idstext =
2806 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_DST];
2807 sadb_x_kmc_t *kmcext =
2808 (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2809 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
2810 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
2811 sadb_x_pair_t *pair_ext =
2812 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
2813 sadb_x_replay_ctr_t *replayext =
2814 (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
2815 uint8_t protocol =
2816 (samsg->sadb_msg_satype == SADB_SATYPE_AH) ? IPPROTO_AH:IPPROTO_ESP;
2817 int salt_offset;
2818 uint8_t *buf_ptr;
2819 struct sockaddr_in *src, *dst, *isrc, *idst;
2820 struct sockaddr_in6 *src6, *dst6, *isrc6, *idst6;
2821 sadb_lifetime_t *soft =
2822 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
2823 sadb_lifetime_t *hard =
2824 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
2825 sadb_lifetime_t *idle =
2826 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
2827 sa_family_t af;
2828 int error = 0;
2829 boolean_t isupdate = (newbie != NULL);
2830 uint32_t *src_addr_ptr, *dst_addr_ptr, *isrc_addr_ptr, *idst_addr_ptr;
2831 ipsec_stack_t *ipss = ns->netstack_ipsec;
2832 ip_stack_t *ipst = ns->netstack_ip;
2833 ipsec_alginfo_t *alg;
2834 int rcode;
2835 boolean_t async = B_FALSE;
2837 init_ipsa_pair(&ipsapp);
2839 if (srcext == NULL) {
2840 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2841 return (EINVAL);
2843 if (dstext == NULL) {
2844 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2845 return (EINVAL);
2847 if (assoc == NULL) {
2848 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2849 return (EINVAL);
2852 src = (struct sockaddr_in *)(srcext + 1);
2853 src6 = (struct sockaddr_in6 *)(srcext + 1);
2854 dst = (struct sockaddr_in *)(dstext + 1);
2855 dst6 = (struct sockaddr_in6 *)(dstext + 1);
2856 if (isrcext != NULL) {
2857 isrc = (struct sockaddr_in *)(isrcext + 1);
2858 isrc6 = (struct sockaddr_in6 *)(isrcext + 1);
2859 ASSERT(idstext != NULL);
2860 idst = (struct sockaddr_in *)(idstext + 1);
2861 idst6 = (struct sockaddr_in6 *)(idstext + 1);
2862 } else {
2863 isrc = NULL;
2864 isrc6 = NULL;
2867 af = src->sin_family;
2869 if (af == AF_INET) {
2870 src_addr_ptr = (uint32_t *)&src->sin_addr;
2871 dst_addr_ptr = (uint32_t *)&dst->sin_addr;
2872 } else {
2873 ASSERT(af == AF_INET6);
2874 src_addr_ptr = (uint32_t *)&src6->sin6_addr;
2875 dst_addr_ptr = (uint32_t *)&dst6->sin6_addr;
2879 * Check to see if the new SA will be cloned AND paired. The
2880 * reason a SA will be cloned is the source or destination addresses
2881 * are not specific enough to determine if the SA goes in the outbound
2882 * or the inbound hash table, so its cloned and put in both. If
2883 * the SA is paired, it's soft linked to another SA for the other
2884 * direction. Keeping track and looking up SA's that are direction
2885 * unspecific and linked is too hard.
2887 if (clone && (pair_ext != NULL)) {
2888 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
2889 return (EINVAL);
2892 if (!isupdate) {
2893 newbie = sadb_makelarvalassoc(assoc->sadb_sa_spi,
2894 src_addr_ptr, dst_addr_ptr, af, ns);
2895 if (newbie == NULL)
2896 return (ENOMEM);
2899 mutex_enter(&newbie->ipsa_lock);
2901 if (isrc != NULL) {
2902 if (isrc->sin_family == AF_INET) {
2903 if (srcext->sadb_address_proto != IPPROTO_ENCAP) {
2904 if (srcext->sadb_address_proto != 0) {
2906 * Mismatched outer-packet protocol
2907 * and inner-packet address family.
2909 mutex_exit(&newbie->ipsa_lock);
2910 error = EPROTOTYPE;
2911 *diagnostic =
2912 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
2913 goto error;
2914 } else {
2915 /* Fill in with explicit protocol. */
2916 srcext->sadb_address_proto =
2917 IPPROTO_ENCAP;
2918 dstext->sadb_address_proto =
2919 IPPROTO_ENCAP;
2922 isrc_addr_ptr = (uint32_t *)&isrc->sin_addr;
2923 idst_addr_ptr = (uint32_t *)&idst->sin_addr;
2924 } else {
2925 ASSERT(isrc->sin_family == AF_INET6);
2926 if (srcext->sadb_address_proto != IPPROTO_IPV6) {
2927 if (srcext->sadb_address_proto != 0) {
2929 * Mismatched outer-packet protocol
2930 * and inner-packet address family.
2932 mutex_exit(&newbie->ipsa_lock);
2933 error = EPROTOTYPE;
2934 *diagnostic =
2935 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
2936 goto error;
2937 } else {
2938 /* Fill in with explicit protocol. */
2939 srcext->sadb_address_proto =
2940 IPPROTO_IPV6;
2941 dstext->sadb_address_proto =
2942 IPPROTO_IPV6;
2945 isrc_addr_ptr = (uint32_t *)&isrc6->sin6_addr;
2946 idst_addr_ptr = (uint32_t *)&idst6->sin6_addr;
2948 newbie->ipsa_innerfam = isrc->sin_family;
2950 IPSA_COPY_ADDR(newbie->ipsa_innersrc, isrc_addr_ptr,
2951 newbie->ipsa_innerfam);
2952 IPSA_COPY_ADDR(newbie->ipsa_innerdst, idst_addr_ptr,
2953 newbie->ipsa_innerfam);
2954 newbie->ipsa_innersrcpfx = isrcext->sadb_address_prefixlen;
2955 newbie->ipsa_innerdstpfx = idstext->sadb_address_prefixlen;
2957 /* Unique value uses inner-ports for Tunnel Mode... */
2958 newbie->ipsa_unique_id = SA_UNIQUE_ID(isrc->sin_port,
2959 idst->sin_port, dstext->sadb_address_proto,
2960 idstext->sadb_address_proto);
2961 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(isrc->sin_port,
2962 idst->sin_port, dstext->sadb_address_proto,
2963 idstext->sadb_address_proto);
2964 } else {
2965 /* ... and outer-ports for Transport Mode. */
2966 newbie->ipsa_unique_id = SA_UNIQUE_ID(src->sin_port,
2967 dst->sin_port, dstext->sadb_address_proto, 0);
2968 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(src->sin_port,
2969 dst->sin_port, dstext->sadb_address_proto, 0);
2971 if (newbie->ipsa_unique_mask != (uint64_t)0)
2972 newbie->ipsa_flags |= IPSA_F_UNIQUE;
2974 sadb_nat_calculations(newbie,
2975 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC],
2976 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM],
2977 src_addr_ptr, dst_addr_ptr);
2979 newbie->ipsa_type = samsg->sadb_msg_satype;
2981 ASSERT((assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
2982 (assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE));
2983 newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
2984 newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
2986 newbie->ipsa_flags |= assoc->sadb_sa_flags;
2987 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_LOC &&
2988 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC] == NULL) {
2989 mutex_exit(&newbie->ipsa_lock);
2990 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_LOC;
2991 error = EINVAL;
2992 goto error;
2994 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_REM &&
2995 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM] == NULL) {
2996 mutex_exit(&newbie->ipsa_lock);
2997 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_REM;
2998 error = EINVAL;
2999 goto error;
3001 if (newbie->ipsa_flags & SADB_X_SAFLAGS_TUNNEL &&
3002 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL) {
3003 mutex_exit(&newbie->ipsa_lock);
3004 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
3005 error = EINVAL;
3006 goto error;
3009 * If unspecified source address, force replay_wsize to 0.
3010 * This is because an SA that has multiple sources of secure
3011 * traffic cannot enforce a replay counter w/o synchronizing the
3012 * senders.
3014 if (ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC)
3015 newbie->ipsa_replay_wsize = assoc->sadb_sa_replay;
3016 else
3017 newbie->ipsa_replay_wsize = 0;
3019 newbie->ipsa_addtime = gethrestime_sec();
3021 if (kmcext != NULL) {
3022 newbie->ipsa_kmp = kmcext->sadb_x_kmc_proto;
3024 * Be liberal in what we receive. Special-case the IKEv1
3025 * cookie, which closed-source in.iked assumes is 32 bits.
3026 * Now that we store all 64 bits, we should pre-zero the
3027 * reserved field on behalf of closed-source in.iked.
3029 if (newbie->ipsa_kmp == SADB_X_KMP_IKE) {
3030 /* Just in case in.iked is misbehaving... */
3031 kmcext->sadb_x_kmc_reserved = 0;
3033 newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie64;
3037 * XXX CURRENT lifetime checks MAY BE needed for an UPDATE.
3038 * The spec says that one can update current lifetimes, but
3039 * that seems impractical, especially in the larval-to-mature
3040 * update that this function performs.
3042 if (soft != NULL) {
3043 newbie->ipsa_softaddlt = soft->sadb_lifetime_addtime;
3044 newbie->ipsa_softuselt = soft->sadb_lifetime_usetime;
3045 newbie->ipsa_softbyteslt = soft->sadb_lifetime_bytes;
3046 newbie->ipsa_softalloc = soft->sadb_lifetime_allocations;
3047 SET_EXPIRE(newbie, softaddlt, softexpiretime);
3049 if (hard != NULL) {
3050 newbie->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
3051 newbie->ipsa_harduselt = hard->sadb_lifetime_usetime;
3052 newbie->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
3053 newbie->ipsa_hardalloc = hard->sadb_lifetime_allocations;
3054 SET_EXPIRE(newbie, hardaddlt, hardexpiretime);
3056 if (idle != NULL) {
3057 newbie->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
3058 newbie->ipsa_idleuselt = idle->sadb_lifetime_usetime;
3059 newbie->ipsa_idleexpiretime = newbie->ipsa_addtime +
3060 newbie->ipsa_idleaddlt;
3061 newbie->ipsa_idletime = newbie->ipsa_idleaddlt;
3064 newbie->ipsa_authtmpl = NULL;
3065 newbie->ipsa_encrtmpl = NULL;
3067 #ifdef IPSEC_LATENCY_TEST
3068 if (akey != NULL && newbie->ipsa_auth_alg != SADB_AALG_NONE) {
3069 #else
3070 if (akey != NULL) {
3071 #endif
3072 async = (ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
3073 IPSEC_ALGS_EXEC_ASYNC);
3075 newbie->ipsa_authkeybits = akey->sadb_key_bits;
3076 newbie->ipsa_authkeylen = SADB_1TO8(akey->sadb_key_bits);
3077 /* In case we have to round up to the next byte... */
3078 if ((akey->sadb_key_bits & 0x7) != 0)
3079 newbie->ipsa_authkeylen++;
3080 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
3081 KM_NOSLEEP);
3082 if (newbie->ipsa_authkey == NULL) {
3083 error = ENOMEM;
3084 mutex_exit(&newbie->ipsa_lock);
3085 goto error;
3087 bcopy(akey + 1, newbie->ipsa_authkey, newbie->ipsa_authkeylen);
3088 bzero(akey + 1, newbie->ipsa_authkeylen);
3091 * Pre-initialize the kernel crypto framework key
3092 * structure.
3094 newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
3095 newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
3096 newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
3098 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3099 alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
3100 [newbie->ipsa_auth_alg];
3101 if (alg != NULL && ALG_VALID(alg)) {
3102 newbie->ipsa_amech.cm_type = alg->alg_mech_type;
3103 newbie->ipsa_amech.cm_param =
3104 (char *)&newbie->ipsa_mac_len;
3105 newbie->ipsa_amech.cm_param_len = sizeof (size_t);
3106 newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
3107 } else {
3108 newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
3110 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
3111 rw_exit(&ipss->ipsec_alg_lock);
3112 if (error != 0) {
3113 mutex_exit(&newbie->ipsa_lock);
3115 * An error here indicates that alg is the wrong type
3116 * (IE: not authentication) or its not in the alg tables
3117 * created by ipsecalgs(1m), or Kcf does not like the
3118 * parameters passed in with this algorithm, which is
3119 * probably a coding error!
3121 *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3123 goto error;
3127 if (ekey != NULL) {
3128 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3129 async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
3130 IPSEC_ALGS_EXEC_ASYNC);
3131 alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
3132 [newbie->ipsa_encr_alg];
3134 if (alg != NULL && ALG_VALID(alg)) {
3135 newbie->ipsa_emech.cm_type = alg->alg_mech_type;
3136 newbie->ipsa_datalen = alg->alg_datalen;
3137 if (alg->alg_flags & ALG_FLAG_COUNTERMODE)
3138 newbie->ipsa_flags |= IPSA_F_COUNTERMODE;
3140 if (alg->alg_flags & ALG_FLAG_COMBINED) {
3141 newbie->ipsa_flags |= IPSA_F_COMBINED;
3142 newbie->ipsa_mac_len = alg->alg_icvlen;
3145 if (alg->alg_flags & ALG_FLAG_CCM)
3146 newbie->ipsa_noncefunc = ccm_params_init;
3147 else if (alg->alg_flags & ALG_FLAG_GCM)
3148 newbie->ipsa_noncefunc = gcm_params_init;
3149 else newbie->ipsa_noncefunc = cbc_params_init;
3151 newbie->ipsa_saltlen = alg->alg_saltlen;
3152 newbie->ipsa_saltbits = SADB_8TO1(newbie->ipsa_saltlen);
3153 newbie->ipsa_iv_len = alg->alg_ivlen;
3154 newbie->ipsa_nonce_len = newbie->ipsa_saltlen +
3155 newbie->ipsa_iv_len;
3156 newbie->ipsa_emech.cm_param = NULL;
3157 newbie->ipsa_emech.cm_param_len = 0;
3158 } else {
3159 newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
3161 rw_exit(&ipss->ipsec_alg_lock);
3164 * The byte stream following the sadb_key_t is made up of:
3165 * key bytes, [salt bytes], [IV initial value]
3166 * All of these have variable length. The IV is typically
3167 * randomly generated by this function and not passed in.
3168 * By supporting the injection of a known IV, the whole
3169 * IPsec subsystem and the underlying crypto subsystem
3170 * can be tested with known test vectors.
3172 * The keying material has been checked by ext_check()
3173 * and ipsec_valid_key_size(), after removing salt/IV
3174 * bits, whats left is the encryption key. If this is too
3175 * short, ipsec_create_ctx_tmpl() will fail and the SA
3176 * won't get created.
3178 * set ipsa_encrkeylen to length of key only.
3180 newbie->ipsa_encrkeybits = ekey->sadb_key_bits;
3181 newbie->ipsa_encrkeybits -= ekey->sadb_key_reserved;
3182 newbie->ipsa_encrkeybits -= newbie->ipsa_saltbits;
3183 newbie->ipsa_encrkeylen = SADB_1TO8(newbie->ipsa_encrkeybits);
3185 /* In case we have to round up to the next byte... */
3186 if ((ekey->sadb_key_bits & 0x7) != 0)
3187 newbie->ipsa_encrkeylen++;
3189 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
3190 KM_NOSLEEP);
3191 if (newbie->ipsa_encrkey == NULL) {
3192 error = ENOMEM;
3193 mutex_exit(&newbie->ipsa_lock);
3194 goto error;
3197 buf_ptr = (uint8_t *)(ekey + 1);
3198 bcopy(buf_ptr, newbie->ipsa_encrkey, newbie->ipsa_encrkeylen);
3200 if (newbie->ipsa_flags & IPSA_F_COMBINED) {
3202 * Combined mode algs need a nonce. Copy the salt and
3203 * IV into a buffer. The ipsa_nonce is a pointer into
3204 * this buffer, some bytes at the start of the buffer
3205 * may be unused, depends on the salt length. The IV
3206 * is 64 bit aligned so it can be incremented as a
3207 * uint64_t. Zero out key in samsg_t before freeing.
3210 newbie->ipsa_nonce_buf = kmem_alloc(
3211 sizeof (ipsec_nonce_t), KM_NOSLEEP);
3212 if (newbie->ipsa_nonce_buf == NULL) {
3213 error = ENOMEM;
3214 mutex_exit(&newbie->ipsa_lock);
3215 goto error;
3218 * Initialize nonce and salt pointers to point
3219 * to the nonce buffer. This is just in case we get
3220 * bad data, the pointers will be valid, the data
3221 * won't be.
3223 * See sadb.h for layout of nonce.
3225 newbie->ipsa_iv = &newbie->ipsa_nonce_buf->iv;
3226 newbie->ipsa_salt = (uint8_t *)newbie->ipsa_nonce_buf;
3227 newbie->ipsa_nonce = newbie->ipsa_salt;
3228 if (newbie->ipsa_saltlen != 0) {
3229 salt_offset = MAXSALTSIZE -
3230 newbie->ipsa_saltlen;
3231 newbie->ipsa_salt = (uint8_t *)
3232 &newbie->ipsa_nonce_buf->salt[salt_offset];
3233 newbie->ipsa_nonce = newbie->ipsa_salt;
3234 buf_ptr += newbie->ipsa_encrkeylen;
3235 bcopy(buf_ptr, newbie->ipsa_salt,
3236 newbie->ipsa_saltlen);
3239 * The IV for CCM/GCM mode increments, it should not
3240 * repeat. Get a random value for the IV, make a
3241 * copy, the SA will expire when/if the IV ever
3242 * wraps back to the initial value. If an Initial IV
3243 * is passed in via PF_KEY, save this in the SA.
3244 * Initialising IV for inbound is pointless as its
3245 * taken from the inbound packet.
3247 if (!is_inbound) {
3248 if (ekey->sadb_key_reserved != 0) {
3249 buf_ptr += newbie->ipsa_saltlen;
3250 bcopy(buf_ptr, (uint8_t *)newbie->
3251 ipsa_iv, SADB_1TO8(ekey->
3252 sadb_key_reserved));
3253 } else {
3254 (void) random_get_pseudo_bytes(
3255 (uint8_t *)newbie->ipsa_iv,
3256 newbie->ipsa_iv_len);
3258 newbie->ipsa_iv_softexpire =
3259 (*newbie->ipsa_iv) << 9;
3260 newbie->ipsa_iv_hardexpire = *newbie->ipsa_iv;
3263 bzero((ekey + 1), SADB_1TO8(ekey->sadb_key_bits));
3266 * Pre-initialize the kernel crypto framework key
3267 * structure.
3269 newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
3270 newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
3271 newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
3273 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3274 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
3275 rw_exit(&ipss->ipsec_alg_lock);
3276 if (error != 0) {
3277 mutex_exit(&newbie->ipsa_lock);
3278 /* See above for error explanation. */
3279 *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3280 goto error;
3284 if (async)
3285 newbie->ipsa_flags |= IPSA_F_ASYNC;
3288 * Ptrs to processing functions.
3290 if (newbie->ipsa_type == SADB_SATYPE_ESP)
3291 ipsecesp_init_funcs(newbie);
3292 else
3293 ipsecah_init_funcs(newbie);
3294 ASSERT(newbie->ipsa_output_func != NULL &&
3295 newbie->ipsa_input_func != NULL);
3298 * Certificate ID stuff.
3300 if (ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC] != NULL) {
3301 sadb_ident_t *id =
3302 (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
3305 * Can assume strlen() will return okay because ext_check() in
3306 * keysock.c prepares the string for us.
3308 newbie->ipsa_src_cid = ipsid_lookup(id->sadb_ident_type,
3309 (char *)(id+1), ns);
3310 if (newbie->ipsa_src_cid == NULL) {
3311 error = ENOMEM;
3312 mutex_exit(&newbie->ipsa_lock);
3313 goto error;
3317 if (ksi->ks_in_extv[SADB_EXT_IDENTITY_DST] != NULL) {
3318 sadb_ident_t *id =
3319 (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
3322 * Can assume strlen() will return okay because ext_check() in
3323 * keysock.c prepares the string for us.
3325 newbie->ipsa_dst_cid = ipsid_lookup(id->sadb_ident_type,
3326 (char *)(id+1), ns);
3327 if (newbie->ipsa_dst_cid == NULL) {
3328 error = ENOMEM;
3329 mutex_exit(&newbie->ipsa_lock);
3330 goto error;
3334 if (replayext != NULL) {
3335 if ((replayext->sadb_x_rc_replay32 == 0) &&
3336 (replayext->sadb_x_rc_replay64 != 0)) {
3337 error = EOPNOTSUPP;
3338 *diagnostic = SADB_X_DIAGNOSTIC_INVALID_REPLAY;
3339 mutex_exit(&newbie->ipsa_lock);
3340 goto error;
3342 newbie->ipsa_replay = replayext->sadb_x_rc_replay32;
3345 /* now that the SA has been updated, set its new state */
3346 newbie->ipsa_state = assoc->sadb_sa_state;
3348 if (clone) {
3349 newbie->ipsa_haspeer = B_TRUE;
3350 } else {
3351 if (!is_inbound) {
3352 lifetime_fuzz(newbie);
3356 * The less locks I hold when doing an insertion and possible cloning,
3357 * the better!
3359 mutex_exit(&newbie->ipsa_lock);
3361 if (clone) {
3362 newbie_clone = sadb_cloneassoc(newbie);
3364 if (newbie_clone == NULL) {
3365 error = ENOMEM;
3366 goto error;
3371 * Enter the bucket locks. The order of entry is outbound,
3372 * inbound. We map "primary" and "secondary" into outbound and inbound
3373 * based on the destination address type. If the destination address
3374 * type is for a node that isn't mine (or potentially mine), the
3375 * "primary" bucket is the outbound one.
3377 if (!is_inbound) {
3378 /* primary == outbound */
3379 mutex_enter(&primary->isaf_lock);
3380 mutex_enter(&secondary->isaf_lock);
3381 } else {
3382 /* primary == inbound */
3383 mutex_enter(&secondary->isaf_lock);
3384 mutex_enter(&primary->isaf_lock);
3388 * sadb_insertassoc() doesn't increment the reference
3389 * count. We therefore have to increment the
3390 * reference count one more time to reflect the
3391 * pointers of the table that reference this SA.
3393 IPSA_REFHOLD(newbie);
3395 if (isupdate) {
3397 * Unlink from larval holding cell in the "inbound" fanout.
3399 ASSERT(newbie->ipsa_linklock == &primary->isaf_lock ||
3400 newbie->ipsa_linklock == &secondary->isaf_lock);
3401 sadb_unlinkassoc(newbie);
3404 mutex_enter(&newbie->ipsa_lock);
3405 error = sadb_insertassoc(newbie, primary);
3406 mutex_exit(&newbie->ipsa_lock);
3408 if (error != 0) {
3410 * Since sadb_insertassoc() failed, we must decrement the
3411 * refcount again so the cleanup code will actually free
3412 * the offending SA.
3414 IPSA_REFRELE(newbie);
3415 goto error_unlock;
3418 if (newbie_clone != NULL) {
3419 mutex_enter(&newbie_clone->ipsa_lock);
3420 error = sadb_insertassoc(newbie_clone, secondary);
3421 mutex_exit(&newbie_clone->ipsa_lock);
3422 if (error != 0) {
3423 /* Collision in secondary table. */
3424 sadb_unlinkassoc(newbie); /* This does REFRELE. */
3425 goto error_unlock;
3427 IPSA_REFHOLD(newbie_clone);
3428 } else {
3429 ASSERT(primary != secondary);
3430 scratch = ipsec_getassocbyspi(secondary, newbie->ipsa_spi,
3431 ALL_ZEROES_PTR, newbie->ipsa_dstaddr, af);
3432 if (scratch != NULL) {
3433 /* Collision in secondary table. */
3434 sadb_unlinkassoc(newbie); /* This does REFRELE. */
3435 /* Set the error, since ipsec_getassocbyspi() can't. */
3436 error = EEXIST;
3437 goto error_unlock;
3441 /* OKAY! So let's do some reality check assertions. */
3443 ASSERT(MUTEX_NOT_HELD(&newbie->ipsa_lock));
3444 ASSERT(newbie_clone == NULL ||
3445 (MUTEX_NOT_HELD(&newbie_clone->ipsa_lock)));
3447 error_unlock:
3450 * We can exit the locks in any order. Only entrance needs to
3451 * follow any protocol.
3453 mutex_exit(&secondary->isaf_lock);
3454 mutex_exit(&primary->isaf_lock);
3456 if (pair_ext != NULL && error == 0) {
3457 /* update pair_spi if it exists. */
3458 ipsa_query_t sq;
3460 sq.spp = spp; /* XXX param */
3461 error = sadb_form_query(ksi, IPSA_Q_DST, IPSA_Q_SRC|IPSA_Q_DST|
3462 IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND, &sq, diagnostic);
3463 if (error)
3464 return (error);
3466 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
3468 if (error != 0)
3469 goto error;
3471 if (ipsapp.ipsap_psa_ptr != NULL) {
3472 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
3473 error = EINVAL;
3474 } else {
3475 /* update_pairing() sets diagnostic */
3476 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
3479 /* Common error point for this routine. */
3480 error:
3481 if (newbie != NULL) {
3482 if (error != 0) {
3483 /* This SA is broken, let the reaper clean up. */
3484 mutex_enter(&newbie->ipsa_lock);
3485 newbie->ipsa_state = IPSA_STATE_DEAD;
3486 newbie->ipsa_hardexpiretime = 1;
3487 mutex_exit(&newbie->ipsa_lock);
3489 IPSA_REFRELE(newbie);
3491 if (newbie_clone != NULL) {
3492 IPSA_REFRELE(newbie_clone);
3495 if (error == 0) {
3497 * Construct favorable PF_KEY return message and send to
3498 * keysock. Update the flags in the original keysock message
3499 * to reflect the actual flags in the new SA.
3500 * (Q: Do I need to pass "newbie"? If I do,
3501 * make sure to REFHOLD, call, then REFRELE.)
3503 assoc->sadb_sa_flags = newbie->ipsa_flags;
3504 sadb_pfkey_echo(pfkey_q, mp, samsg, ksi, NULL);
3507 destroy_ipsa_pair(&ipsapp);
3508 return (error);
3512 * Set the time of first use for a security association. Update any
3513 * expiration times as a result.
3515 void
3516 sadb_set_usetime(ipsa_t *assoc)
3518 time_t snapshot = gethrestime_sec();
3520 mutex_enter(&assoc->ipsa_lock);
3521 assoc->ipsa_lastuse = snapshot;
3522 assoc->ipsa_idleexpiretime = snapshot + assoc->ipsa_idletime;
3525 * Caller does check usetime before calling me usually, and
3526 * double-checking is better than a mutex_enter/exit hit.
3528 if (assoc->ipsa_usetime == 0) {
3530 * This is redundant for outbound SA's, as
3531 * ipsec_getassocbyconn() sets the IPSA_F_USED flag already.
3532 * Inbound SAs, however, have no such protection.
3534 assoc->ipsa_flags |= IPSA_F_USED;
3535 assoc->ipsa_usetime = snapshot;
3538 * After setting the use time, see if we have a use lifetime
3539 * that would cause the actual SA expiration time to shorten.
3541 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
3542 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
3544 mutex_exit(&assoc->ipsa_lock);
3548 * Send up a PF_KEY expire message for this association.
3550 static void
3551 sadb_expire_assoc(queue_t *pfkey_q, ipsa_t *assoc)
3553 mblk_t *mp, *mp1;
3554 int alloclen, af;
3555 sadb_msg_t *samsg;
3556 sadb_lifetime_t *current, *expire;
3557 sadb_sa_t *saext;
3558 uint8_t *end;
3559 boolean_t tunnel_mode;
3561 ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3563 /* Don't bother sending if there's no queue. */
3564 if (pfkey_q == NULL)
3565 return;
3567 mp = sadb_keysock_out(0);
3568 if (mp == NULL) {
3569 /* cmn_err(CE_WARN, */
3570 /* "sadb_expire_assoc: Can't allocate KEYSOCK_OUT.\n"); */
3571 return;
3574 alloclen = sizeof (*samsg) + sizeof (*current) + sizeof (*expire) +
3575 2 * sizeof (sadb_address_t) + sizeof (*saext);
3577 af = assoc->ipsa_addrfam;
3578 switch (af) {
3579 case AF_INET:
3580 alloclen += 2 * sizeof (struct sockaddr_in);
3581 break;
3582 case AF_INET6:
3583 alloclen += 2 * sizeof (struct sockaddr_in6);
3584 break;
3585 default:
3586 /* Won't happen unless there's a kernel bug. */
3587 freeb(mp);
3588 cmn_err(CE_WARN,
3589 "sadb_expire_assoc: Unknown address length.\n");
3590 return;
3593 tunnel_mode = (assoc->ipsa_flags & IPSA_F_TUNNEL);
3594 if (tunnel_mode) {
3595 alloclen += 2 * sizeof (sadb_address_t);
3596 switch (assoc->ipsa_innerfam) {
3597 case AF_INET:
3598 alloclen += 2 * sizeof (struct sockaddr_in);
3599 break;
3600 case AF_INET6:
3601 alloclen += 2 * sizeof (struct sockaddr_in6);
3602 break;
3603 default:
3604 /* Won't happen unless there's a kernel bug. */
3605 freeb(mp);
3606 cmn_err(CE_WARN, "sadb_expire_assoc: "
3607 "Unknown inner address length.\n");
3608 return;
3612 mp->b_cont = allocb(alloclen, BPRI_HI);
3613 if (mp->b_cont == NULL) {
3614 freeb(mp);
3615 /* cmn_err(CE_WARN, */
3616 /* "sadb_expire_assoc: Can't allocate message.\n"); */
3617 return;
3620 mp1 = mp;
3621 mp = mp->b_cont;
3622 end = mp->b_wptr + alloclen;
3624 samsg = (sadb_msg_t *)mp->b_wptr;
3625 mp->b_wptr += sizeof (*samsg);
3626 samsg->sadb_msg_version = PF_KEY_V2;
3627 samsg->sadb_msg_type = SADB_EXPIRE;
3628 samsg->sadb_msg_errno = 0;
3629 samsg->sadb_msg_satype = assoc->ipsa_type;
3630 samsg->sadb_msg_len = SADB_8TO64(alloclen);
3631 samsg->sadb_msg_reserved = 0;
3632 samsg->sadb_msg_seq = 0;
3633 samsg->sadb_msg_pid = 0;
3635 saext = (sadb_sa_t *)mp->b_wptr;
3636 mp->b_wptr += sizeof (*saext);
3637 saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
3638 saext->sadb_sa_exttype = SADB_EXT_SA;
3639 saext->sadb_sa_spi = assoc->ipsa_spi;
3640 saext->sadb_sa_replay = assoc->ipsa_replay_wsize;
3641 saext->sadb_sa_state = assoc->ipsa_state;
3642 saext->sadb_sa_auth = assoc->ipsa_auth_alg;
3643 saext->sadb_sa_encrypt = assoc->ipsa_encr_alg;
3644 saext->sadb_sa_flags = assoc->ipsa_flags;
3646 current = (sadb_lifetime_t *)mp->b_wptr;
3647 mp->b_wptr += sizeof (sadb_lifetime_t);
3648 current->sadb_lifetime_len = SADB_8TO64(sizeof (*current));
3649 current->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
3650 /* We do not support the concept. */
3651 current->sadb_lifetime_allocations = 0;
3652 current->sadb_lifetime_bytes = assoc->ipsa_bytes;
3653 current->sadb_lifetime_addtime = assoc->ipsa_addtime;
3654 current->sadb_lifetime_usetime = assoc->ipsa_usetime;
3656 expire = (sadb_lifetime_t *)mp->b_wptr;
3657 mp->b_wptr += sizeof (*expire);
3658 expire->sadb_lifetime_len = SADB_8TO64(sizeof (*expire));
3660 if (assoc->ipsa_state == IPSA_STATE_DEAD) {
3661 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
3662 expire->sadb_lifetime_allocations = assoc->ipsa_hardalloc;
3663 expire->sadb_lifetime_bytes = assoc->ipsa_hardbyteslt;
3664 expire->sadb_lifetime_addtime = assoc->ipsa_hardaddlt;
3665 expire->sadb_lifetime_usetime = assoc->ipsa_harduselt;
3666 } else if (assoc->ipsa_state == IPSA_STATE_DYING) {
3667 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
3668 expire->sadb_lifetime_allocations = assoc->ipsa_softalloc;
3669 expire->sadb_lifetime_bytes = assoc->ipsa_softbyteslt;
3670 expire->sadb_lifetime_addtime = assoc->ipsa_softaddlt;
3671 expire->sadb_lifetime_usetime = assoc->ipsa_softuselt;
3672 } else {
3673 ASSERT(assoc->ipsa_state == IPSA_STATE_MATURE);
3674 expire->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
3675 expire->sadb_lifetime_allocations = 0;
3676 expire->sadb_lifetime_bytes = 0;
3677 expire->sadb_lifetime_addtime = assoc->ipsa_idleaddlt;
3678 expire->sadb_lifetime_usetime = assoc->ipsa_idleuselt;
3681 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_SRC,
3682 af, assoc->ipsa_srcaddr, tunnel_mode ? 0 : SA_SRCPORT(assoc),
3683 SA_PROTO(assoc), 0);
3684 ASSERT(mp->b_wptr != NULL);
3686 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_DST,
3687 af, assoc->ipsa_dstaddr, tunnel_mode ? 0 : SA_DSTPORT(assoc),
3688 SA_PROTO(assoc), 0);
3689 ASSERT(mp->b_wptr != NULL);
3691 if (tunnel_mode) {
3692 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
3693 SADB_X_EXT_ADDRESS_INNER_SRC, assoc->ipsa_innerfam,
3694 assoc->ipsa_innersrc, SA_SRCPORT(assoc), SA_IPROTO(assoc),
3695 assoc->ipsa_innersrcpfx);
3696 ASSERT(mp->b_wptr != NULL);
3697 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
3698 SADB_X_EXT_ADDRESS_INNER_DST, assoc->ipsa_innerfam,
3699 assoc->ipsa_innerdst, SA_DSTPORT(assoc), SA_IPROTO(assoc),
3700 assoc->ipsa_innerdstpfx);
3701 ASSERT(mp->b_wptr != NULL);
3704 /* Can just putnext, we're ready to go! */
3705 putnext(pfkey_q, mp1);
3709 * "Age" the SA with the number of bytes that was used to protect traffic.
3710 * Send an SADB_EXPIRE message if appropriate. Return B_TRUE if there was
3711 * enough "charge" left in the SA to protect the data. Return B_FALSE
3712 * otherwise. (If B_FALSE is returned, the association either was, or became
3713 * DEAD.)
3715 boolean_t
3716 sadb_age_bytes(queue_t *pfkey_q, ipsa_t *assoc, uint64_t bytes,
3717 boolean_t sendmsg)
3719 boolean_t rc = B_TRUE;
3720 uint64_t newtotal;
3722 mutex_enter(&assoc->ipsa_lock);
3723 newtotal = assoc->ipsa_bytes + bytes;
3724 if (assoc->ipsa_hardbyteslt != 0 &&
3725 newtotal >= assoc->ipsa_hardbyteslt) {
3726 if (assoc->ipsa_state != IPSA_STATE_DEAD) {
3728 * Send EXPIRE message to PF_KEY. May wish to pawn
3729 * this off on another non-interrupt thread. Also
3730 * unlink this SA immediately.
3732 assoc->ipsa_state = IPSA_STATE_DEAD;
3733 if (sendmsg)
3734 sadb_expire_assoc(pfkey_q, assoc);
3736 * Set non-zero expiration time so sadb_age_assoc()
3737 * will work when reaping.
3739 assoc->ipsa_hardexpiretime = (time_t)1;
3740 } /* Else someone beat me to it! */
3741 rc = B_FALSE;
3742 } else if (assoc->ipsa_softbyteslt != 0 &&
3743 (newtotal >= assoc->ipsa_softbyteslt)) {
3744 if (assoc->ipsa_state < IPSA_STATE_DYING) {
3746 * Send EXPIRE message to PF_KEY. May wish to pawn
3747 * this off on another non-interrupt thread.
3749 assoc->ipsa_state = IPSA_STATE_DYING;
3750 assoc->ipsa_bytes = newtotal;
3751 if (sendmsg)
3752 sadb_expire_assoc(pfkey_q, assoc);
3753 } /* Else someone beat me to it! */
3755 if (rc == B_TRUE)
3756 assoc->ipsa_bytes = newtotal;
3757 mutex_exit(&assoc->ipsa_lock);
3758 return (rc);
3762 * "Torch" an individual SA. Returns NULL, so it can be tail-called from
3763 * sadb_age_assoc().
3765 static ipsa_t *
3766 sadb_torch_assoc(isaf_t *head, ipsa_t *sa)
3768 ASSERT(MUTEX_HELD(&head->isaf_lock));
3769 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
3770 ASSERT(sa->ipsa_state == IPSA_STATE_DEAD);
3773 * Force cached SAs to be revalidated..
3775 head->isaf_gen++;
3777 mutex_exit(&sa->ipsa_lock);
3778 sadb_unlinkassoc(sa);
3780 return (NULL);
3784 * Do various SA-is-idle activities depending on delta (the number of idle
3785 * seconds on the SA) and/or other properties of the SA.
3787 * Return B_TRUE if I've sent a packet, because I have to drop the
3788 * association's mutex before sending a packet out the wire.
3790 /* ARGSUSED */
3791 static boolean_t
3792 sadb_idle_activities(ipsa_t *assoc, time_t delta, boolean_t inbound)
3794 ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
3795 int nat_t_interval = espstack->ipsecesp_nat_keepalive_interval;
3797 ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3799 if (!inbound && (assoc->ipsa_flags & IPSA_F_NATT_LOC) &&
3800 delta >= nat_t_interval &&
3801 gethrestime_sec() - assoc->ipsa_last_nat_t_ka >= nat_t_interval) {
3802 ASSERT(assoc->ipsa_type == SADB_SATYPE_ESP);
3803 assoc->ipsa_last_nat_t_ka = gethrestime_sec();
3804 mutex_exit(&assoc->ipsa_lock);
3805 ipsecesp_send_keepalive(assoc);
3806 return (B_TRUE);
3808 return (B_FALSE);
3812 * Return "assoc" if haspeer is true and I send an expire. This allows
3813 * the consumers' aging functions to tidy up an expired SA's peer.
3815 static ipsa_t *
3816 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
3817 time_t current, int reap_delay, boolean_t inbound)
3819 ipsa_t *retval = NULL;
3820 boolean_t dropped_mutex = B_FALSE;
3822 ASSERT(MUTEX_HELD(&head->isaf_lock));
3824 mutex_enter(&assoc->ipsa_lock);
3826 if (((assoc->ipsa_state == IPSA_STATE_LARVAL) ||
3827 ((assoc->ipsa_state == IPSA_STATE_IDLE) ||
3828 (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) &&
3829 (assoc->ipsa_hardexpiretime != 0))) &&
3830 (assoc->ipsa_hardexpiretime <= current)) {
3831 assoc->ipsa_state = IPSA_STATE_DEAD;
3832 return (sadb_torch_assoc(head, assoc));
3836 * Check lifetimes. Fortunately, SA setup is done
3837 * such that there are only two times to look at,
3838 * softexpiretime, and hardexpiretime.
3840 * Check hard first.
3843 if (assoc->ipsa_hardexpiretime != 0 &&
3844 assoc->ipsa_hardexpiretime <= current) {
3845 if (assoc->ipsa_state == IPSA_STATE_DEAD)
3846 return (sadb_torch_assoc(head, assoc));
3849 * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
3851 assoc->ipsa_state = IPSA_STATE_DEAD;
3852 if (assoc->ipsa_haspeer || assoc->ipsa_otherspi != 0) {
3854 * If the SA is paired or peered with another, put
3855 * a copy on a list which can be processed later, the
3856 * pair/peer SA needs to be updated so the both die
3857 * at the same time.
3859 * If I return assoc, I have to bump up its reference
3860 * count to keep with the ipsa_t reference count
3861 * semantics.
3863 IPSA_REFHOLD(assoc);
3864 retval = assoc;
3866 sadb_expire_assoc(pfkey_q, assoc);
3867 assoc->ipsa_hardexpiretime = current + reap_delay;
3868 } else if (assoc->ipsa_softexpiretime != 0 &&
3869 assoc->ipsa_softexpiretime <= current &&
3870 assoc->ipsa_state < IPSA_STATE_DYING) {
3872 * Send EXPIRE message to PF_KEY. May wish to pawn
3873 * this off on another non-interrupt thread.
3875 assoc->ipsa_state = IPSA_STATE_DYING;
3876 if (assoc->ipsa_haspeer) {
3878 * If the SA has a peer, update the peer's state
3879 * on SOFT_EXPIRE, this is mostly to prevent two
3880 * expire messages from effectively the same SA.
3882 * Don't care about paired SA's, then can (and should)
3883 * be able to soft expire at different times.
3885 * If I return assoc, I have to bump up its
3886 * reference count to keep with the ipsa_t reference
3887 * count semantics.
3889 IPSA_REFHOLD(assoc);
3890 retval = assoc;
3892 sadb_expire_assoc(pfkey_q, assoc);
3893 } else if (assoc->ipsa_idletime != 0 &&
3894 assoc->ipsa_idleexpiretime <= current) {
3895 if (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) {
3896 assoc->ipsa_state = IPSA_STATE_IDLE;
3900 * Need to handle Mature case
3902 if (assoc->ipsa_state == IPSA_STATE_MATURE) {
3903 sadb_expire_assoc(pfkey_q, assoc);
3905 } else {
3906 /* Check idle time activities. */
3907 dropped_mutex = sadb_idle_activities(assoc,
3908 current - assoc->ipsa_lastuse, inbound);
3911 if (!dropped_mutex)
3912 mutex_exit(&assoc->ipsa_lock);
3913 return (retval);
3917 * Called by a consumer protocol to do ther dirty work of reaping dead
3918 * Security Associations.
3920 * NOTE: sadb_age_assoc() marks expired SA's as DEAD but only removed
3921 * SA's that are already marked DEAD, so expired SA's are only reaped
3922 * the second time sadb_ager() runs.
3924 void
3925 sadb_ager(sadb_t *sp, queue_t *pfkey_q, int reap_delay, netstack_t *ns)
3927 int i;
3928 isaf_t *bucket;
3929 ipsa_t *assoc, *spare;
3930 iacqf_t *acqlist;
3931 ipsacq_t *acqrec, *spareacq;
3932 templist_t *haspeerlist, *newbie;
3933 /* Snapshot current time now. */
3934 time_t current = gethrestime_sec();
3935 haspeerlist = NULL;
3938 * Do my dirty work. This includes aging real entries, aging
3939 * larvals, and aging outstanding ACQUIREs.
3941 * I hope I don't tie up resources for too long.
3944 /* Age acquires. */
3946 for (i = 0; i < sp->sdb_hashsize; i++) {
3947 acqlist = &sp->sdb_acq[i];
3948 mutex_enter(&acqlist->iacqf_lock);
3949 for (acqrec = acqlist->iacqf_ipsacq; acqrec != NULL;
3950 acqrec = spareacq) {
3951 spareacq = acqrec->ipsacq_next;
3952 if (current > acqrec->ipsacq_expire)
3953 sadb_destroy_acquire(acqrec, ns);
3955 mutex_exit(&acqlist->iacqf_lock);
3958 /* Age inbound associations. */
3959 for (i = 0; i < sp->sdb_hashsize; i++) {
3960 bucket = &(sp->sdb_if[i]);
3961 mutex_enter(&bucket->isaf_lock);
3962 for (assoc = bucket->isaf_ipsa; assoc != NULL;
3963 assoc = spare) {
3964 spare = assoc->ipsa_next;
3965 if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
3966 reap_delay, B_TRUE) != NULL) {
3968 * Put SA's which have a peer or SA's which
3969 * are paired on a list for processing after
3970 * all the hash tables have been walked.
3972 * sadb_age_assoc() increments the refcnt,
3973 * effectively doing an IPSA_REFHOLD().
3975 newbie = kmem_alloc(sizeof (*newbie),
3976 KM_NOSLEEP);
3977 if (newbie == NULL) {
3979 * Don't forget to REFRELE().
3981 IPSA_REFRELE(assoc);
3982 continue; /* for loop... */
3984 newbie->next = haspeerlist;
3985 newbie->ipsa = assoc;
3986 haspeerlist = newbie;
3989 mutex_exit(&bucket->isaf_lock);
3992 age_pair_peer_list(haspeerlist, sp, B_FALSE);
3993 haspeerlist = NULL;
3995 /* Age outbound associations. */
3996 for (i = 0; i < sp->sdb_hashsize; i++) {
3997 bucket = &(sp->sdb_of[i]);
3998 mutex_enter(&bucket->isaf_lock);
3999 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4000 assoc = spare) {
4001 spare = assoc->ipsa_next;
4002 if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4003 reap_delay, B_FALSE) != NULL) {
4005 * sadb_age_assoc() increments the refcnt,
4006 * effectively doing an IPSA_REFHOLD().
4008 newbie = kmem_alloc(sizeof (*newbie),
4009 KM_NOSLEEP);
4010 if (newbie == NULL) {
4012 * Don't forget to REFRELE().
4014 IPSA_REFRELE(assoc);
4015 continue; /* for loop... */
4017 newbie->next = haspeerlist;
4018 newbie->ipsa = assoc;
4019 haspeerlist = newbie;
4022 mutex_exit(&bucket->isaf_lock);
4025 age_pair_peer_list(haspeerlist, sp, B_TRUE);
4028 * Run a GC pass to clean out dead identities.
4030 ipsid_gc(ns);
4034 * Figure out when to reschedule the ager.
4036 timeout_id_t
4037 sadb_retimeout(hrtime_t begin, queue_t *pfkey_q, void (*ager)(void *),
4038 void *agerarg, uint_t *intp, uint_t intmax, short mid)
4040 hrtime_t end = gethrtime();
4041 uint_t interval = *intp; /* "interval" is in ms. */
4044 * See how long this took. If it took too long, increase the
4045 * aging interval.
4047 if ((end - begin) > MSEC2NSEC(interval)) {
4048 if (interval >= intmax) {
4049 /* XXX Rate limit this? Or recommend flush? */
4050 (void) strlog(mid, 0, 0, SL_ERROR | SL_WARN,
4051 "Too many SA's to age out in %d msec.\n",
4052 intmax);
4053 } else {
4054 /* Double by shifting by one bit. */
4055 interval <<= 1;
4056 interval = min(interval, intmax);
4058 } else if ((end - begin) <= (MSEC2NSEC(interval) / 2) &&
4059 interval > SADB_AGE_INTERVAL_DEFAULT) {
4061 * If I took less than half of the interval, then I should
4062 * ratchet the interval back down. Never automatically
4063 * shift below the default aging interval.
4065 * NOTE:This even overrides manual setting of the age
4066 * interval using NDD to lower the setting past the
4067 * default. In other words, if you set the interval
4068 * lower than the default, and your SADB gets too big,
4069 * the interval will only self-lower back to the default.
4071 /* Halve by shifting one bit. */
4072 interval >>= 1;
4073 interval = max(interval, SADB_AGE_INTERVAL_DEFAULT);
4075 *intp = interval;
4076 return (qtimeout(pfkey_q, ager, agerarg,
4077 drv_usectohz(interval * (MICROSEC / MILLISEC))));
4082 * Update the lifetime values of an SA. This is the path an SADB_UPDATE
4083 * message takes when updating a MATURE or DYING SA.
4085 static void
4086 sadb_update_lifetimes(ipsa_t *assoc, sadb_lifetime_t *hard,
4087 sadb_lifetime_t *soft, sadb_lifetime_t *idle, boolean_t outbound)
4089 mutex_enter(&assoc->ipsa_lock);
4092 * XXX RFC 2367 mentions how an SADB_EXT_LIFETIME_CURRENT can be
4093 * passed in during an update message. We currently don't handle
4094 * these.
4097 if (hard != NULL) {
4098 if (hard->sadb_lifetime_bytes != 0)
4099 assoc->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
4100 if (hard->sadb_lifetime_usetime != 0)
4101 assoc->ipsa_harduselt = hard->sadb_lifetime_usetime;
4102 if (hard->sadb_lifetime_addtime != 0)
4103 assoc->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
4104 if (assoc->ipsa_hardaddlt != 0) {
4105 assoc->ipsa_hardexpiretime =
4106 assoc->ipsa_addtime + assoc->ipsa_hardaddlt;
4108 if (assoc->ipsa_harduselt != 0 &&
4109 assoc->ipsa_flags & IPSA_F_USED) {
4110 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
4112 if (hard->sadb_lifetime_allocations != 0)
4113 assoc->ipsa_hardalloc = hard->sadb_lifetime_allocations;
4116 if (soft != NULL) {
4117 if (soft->sadb_lifetime_bytes != 0) {
4118 if (soft->sadb_lifetime_bytes >
4119 assoc->ipsa_hardbyteslt) {
4120 assoc->ipsa_softbyteslt =
4121 assoc->ipsa_hardbyteslt;
4122 } else {
4123 assoc->ipsa_softbyteslt =
4124 soft->sadb_lifetime_bytes;
4127 if (soft->sadb_lifetime_usetime != 0) {
4128 if (soft->sadb_lifetime_usetime >
4129 assoc->ipsa_harduselt) {
4130 assoc->ipsa_softuselt =
4131 assoc->ipsa_harduselt;
4132 } else {
4133 assoc->ipsa_softuselt =
4134 soft->sadb_lifetime_usetime;
4137 if (soft->sadb_lifetime_addtime != 0) {
4138 if (soft->sadb_lifetime_addtime >
4139 assoc->ipsa_hardexpiretime) {
4140 assoc->ipsa_softexpiretime =
4141 assoc->ipsa_hardexpiretime;
4142 } else {
4143 assoc->ipsa_softaddlt =
4144 soft->sadb_lifetime_addtime;
4147 if (assoc->ipsa_softaddlt != 0) {
4148 assoc->ipsa_softexpiretime =
4149 assoc->ipsa_addtime + assoc->ipsa_softaddlt;
4151 if (assoc->ipsa_softuselt != 0 &&
4152 assoc->ipsa_flags & IPSA_F_USED) {
4153 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
4155 if (outbound && assoc->ipsa_softexpiretime != 0) {
4156 if (assoc->ipsa_state == IPSA_STATE_MATURE)
4157 lifetime_fuzz(assoc);
4160 if (soft->sadb_lifetime_allocations != 0)
4161 assoc->ipsa_softalloc = soft->sadb_lifetime_allocations;
4164 if (idle != NULL) {
4165 time_t current = gethrestime_sec();
4166 if ((assoc->ipsa_idleexpiretime <= current) &&
4167 (assoc->ipsa_idleaddlt == idle->sadb_lifetime_addtime)) {
4168 assoc->ipsa_idleexpiretime =
4169 current + assoc->ipsa_idleaddlt;
4171 if (idle->sadb_lifetime_addtime != 0)
4172 assoc->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
4173 if (idle->sadb_lifetime_usetime != 0)
4174 assoc->ipsa_idleuselt = idle->sadb_lifetime_usetime;
4175 if (assoc->ipsa_idleaddlt != 0) {
4176 assoc->ipsa_idleexpiretime =
4177 current + idle->sadb_lifetime_addtime;
4178 assoc->ipsa_idletime = idle->sadb_lifetime_addtime;
4180 if (assoc->ipsa_idleuselt != 0) {
4181 if (assoc->ipsa_idletime != 0) {
4182 assoc->ipsa_idletime = min(assoc->ipsa_idletime,
4183 assoc->ipsa_idleuselt);
4184 assoc->ipsa_idleexpiretime =
4185 current + assoc->ipsa_idletime;
4186 } else {
4187 assoc->ipsa_idleexpiretime =
4188 current + assoc->ipsa_idleuselt;
4189 assoc->ipsa_idletime = assoc->ipsa_idleuselt;
4193 mutex_exit(&assoc->ipsa_lock);
4196 static int
4197 sadb_update_state(ipsa_t *assoc, uint_t new_state, mblk_t **ipkt_lst)
4199 int rcode = 0;
4200 time_t current = gethrestime_sec();
4202 mutex_enter(&assoc->ipsa_lock);
4204 switch (new_state) {
4205 case SADB_X_SASTATE_ACTIVE_ELSEWHERE:
4206 if (assoc->ipsa_state == SADB_X_SASTATE_IDLE) {
4207 assoc->ipsa_state = IPSA_STATE_ACTIVE_ELSEWHERE;
4208 assoc->ipsa_idleexpiretime =
4209 current + assoc->ipsa_idletime;
4211 break;
4212 case SADB_X_SASTATE_IDLE:
4213 if (assoc->ipsa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4214 assoc->ipsa_state = IPSA_STATE_IDLE;
4215 assoc->ipsa_idleexpiretime =
4216 current + assoc->ipsa_idletime;
4217 } else {
4218 rcode = EINVAL;
4220 break;
4222 case SADB_X_SASTATE_ACTIVE:
4223 if (assoc->ipsa_state != SADB_X_SASTATE_IDLE) {
4224 rcode = EINVAL;
4225 break;
4227 assoc->ipsa_state = IPSA_STATE_MATURE;
4228 assoc->ipsa_idleexpiretime = current + assoc->ipsa_idletime;
4230 if (ipkt_lst == NULL) {
4231 break;
4234 if (assoc->ipsa_bpkt_head != NULL) {
4235 *ipkt_lst = assoc->ipsa_bpkt_head;
4236 assoc->ipsa_bpkt_head = assoc->ipsa_bpkt_tail = NULL;
4237 assoc->ipsa_mblkcnt = 0;
4238 } else {
4239 *ipkt_lst = NULL;
4241 break;
4242 default:
4243 rcode = EINVAL;
4244 break;
4247 mutex_exit(&assoc->ipsa_lock);
4248 return (rcode);
4252 * Check a proposed KMC update for sanity.
4254 static int
4255 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
4257 uint32_t kmp = sq->kmp;
4258 uint64_t kmc = sq->kmc;
4260 if (sa == NULL)
4261 return (0);
4263 if (sa->ipsa_state == IPSA_STATE_DEAD)
4264 return (ESRCH); /* DEAD == Not there, in this case. */
4266 if ((kmp != 0) && (sa->ipsa_kmp != 0) && (sa->ipsa_kmp != kmp)) {
4267 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
4268 return (EINVAL);
4271 /* Allow IKEv2 KMCs to update the kmc value for rekeying */
4272 if ((kmp != SADB_X_KMP_IKEV2) && (kmc != 0) && (sa->ipsa_kmc != 0) &&
4273 (sa->ipsa_kmc != kmc)) {
4274 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
4275 return (EINVAL);
4278 return (0);
4282 * Actually update the KMC info.
4284 static void
4285 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
4287 uint32_t kmp = sq->kmp;
4288 uint64_t kmc = sq->kmc;
4290 if (kmp != 0)
4291 sa->ipsa_kmp = kmp;
4292 if (kmc != 0)
4293 sa->ipsa_kmc = kmc;
4297 * Common code to update an SA.
4301 sadb_update_sa(mblk_t *mp, keysock_in_t *ksi, mblk_t **ipkt_lst,
4302 sadbp_t *spp, int *diagnostic, queue_t *pfkey_q,
4303 int (*add_sa_func)(mblk_t *, keysock_in_t *, int *, netstack_t *),
4304 netstack_t *ns, uint8_t sadb_msg_type)
4306 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
4307 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
4308 sadb_x_replay_ctr_t *replext =
4309 (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
4310 sadb_lifetime_t *soft =
4311 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
4312 sadb_lifetime_t *hard =
4313 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
4314 sadb_lifetime_t *idle =
4315 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
4316 sadb_x_pair_t *pair_ext =
4317 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4318 ipsa_t *echo_target = NULL;
4319 ipsap_t ipsapp;
4320 ipsa_query_t sq;
4321 time_t current = gethrestime_sec();
4323 sq.spp = spp; /* XXX param */
4324 int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
4325 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND|
4326 IPSA_Q_KMC,
4327 &sq, diagnostic);
4329 if (error != 0)
4330 return (error);
4332 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
4333 if (error != 0)
4334 return (error);
4336 if (ipsapp.ipsap_psa_ptr == NULL && ipsapp.ipsap_sa_ptr != NULL) {
4337 if (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) {
4339 * REFRELE the target and let the add_sa_func()
4340 * deal with updating a larval SA.
4342 destroy_ipsa_pair(&ipsapp);
4343 return (add_sa_func(mp, ksi, diagnostic, ns));
4348 * At this point we have an UPDATE to a MATURE SA. There should
4349 * not be any keying material present.
4351 if (akey != NULL) {
4352 *diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
4353 error = EINVAL;
4354 goto bail;
4356 if (ekey != NULL) {
4357 *diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
4358 error = EINVAL;
4359 goto bail;
4362 if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4363 if (ipsapp.ipsap_sa_ptr != NULL &&
4364 ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4365 if ((error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4366 sq.assoc->sadb_sa_state, NULL)) != 0) {
4367 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4368 goto bail;
4371 if (ipsapp.ipsap_psa_ptr != NULL &&
4372 ipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4373 if ((error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4374 sq.assoc->sadb_sa_state, NULL)) != 0) {
4375 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4376 goto bail;
4380 if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE) {
4381 if (ipsapp.ipsap_sa_ptr != NULL) {
4382 error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4383 sq.assoc->sadb_sa_state,
4384 (ipsapp.ipsap_sa_ptr->ipsa_flags &
4385 IPSA_F_INBOUND) ? ipkt_lst : NULL);
4386 if (error) {
4387 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4388 goto bail;
4391 if (ipsapp.ipsap_psa_ptr != NULL) {
4392 error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4393 sq.assoc->sadb_sa_state,
4394 (ipsapp.ipsap_psa_ptr->ipsa_flags &
4395 IPSA_F_INBOUND) ? ipkt_lst : NULL);
4396 if (error) {
4397 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4398 goto bail;
4401 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4402 ksi, echo_target);
4403 goto bail;
4407 * Reality checks for updates of active associations.
4408 * Sundry first-pass UPDATE-specific reality checks.
4409 * Have to do the checks here, because it's after the add_sa code.
4410 * XXX STATS : logging/stats here?
4413 if (!((sq.assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
4414 (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE))) {
4415 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4416 error = EINVAL;
4417 goto bail;
4419 if (sq.assoc->sadb_sa_flags & ~spp->s_updateflags) {
4420 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
4421 error = EINVAL;
4422 goto bail;
4424 if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
4425 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_LIFETIME;
4426 error = EOPNOTSUPP;
4427 goto bail;
4430 if ((*diagnostic = sadb_hardsoftchk(hard, soft, idle)) != 0) {
4431 error = EINVAL;
4432 goto bail;
4435 error = sadb_check_kmc(&sq, ipsapp.ipsap_sa_ptr, diagnostic);
4436 if (error != 0)
4437 goto bail;
4439 error = sadb_check_kmc(&sq, ipsapp.ipsap_psa_ptr, diagnostic);
4440 if (error != 0)
4441 goto bail;
4444 if (ipsapp.ipsap_sa_ptr != NULL) {
4446 * Do not allow replay value change for MATURE or LARVAL SA.
4449 if ((replext != NULL) &&
4450 ((ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) ||
4451 (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_MATURE))) {
4452 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4453 error = EINVAL;
4454 goto bail;
4459 if (ipsapp.ipsap_sa_ptr != NULL) {
4460 sadb_update_lifetimes(ipsapp.ipsap_sa_ptr, hard, soft,
4461 idle, B_TRUE);
4462 sadb_update_kmc(&sq, ipsapp.ipsap_sa_ptr);
4463 if ((replext != NULL) &&
4464 (ipsapp.ipsap_sa_ptr->ipsa_replay_wsize != 0)) {
4466 * If an inbound SA, update the replay counter
4467 * and check off all the other sequence number
4469 if (ksi->ks_in_dsttype == KS_IN_ADDR_ME) {
4470 if (!sadb_replay_check(ipsapp.ipsap_sa_ptr,
4471 replext->sadb_x_rc_replay32)) {
4472 *diagnostic =
4473 SADB_X_DIAGNOSTIC_INVALID_REPLAY;
4474 error = EINVAL;
4475 goto bail;
4477 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4478 ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4479 current +
4480 ipsapp.ipsap_sa_ptr->ipsa_idletime;
4481 mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4482 } else {
4483 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4484 ipsapp.ipsap_sa_ptr->ipsa_replay =
4485 replext->sadb_x_rc_replay32;
4486 ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4487 current +
4488 ipsapp.ipsap_sa_ptr->ipsa_idletime;
4489 mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4494 if (sadb_msg_type == SADB_X_UPDATEPAIR) {
4495 if (ipsapp.ipsap_psa_ptr != NULL) {
4496 sadb_update_lifetimes(ipsapp.ipsap_psa_ptr, hard, soft,
4497 idle, B_FALSE);
4498 sadb_update_kmc(&sq, ipsapp.ipsap_psa_ptr);
4499 } else {
4500 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
4501 error = ESRCH;
4502 goto bail;
4506 if (pair_ext != NULL)
4507 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
4509 if (error == 0)
4510 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4511 ksi, echo_target);
4512 bail:
4514 destroy_ipsa_pair(&ipsapp);
4516 return (error);
4520 static int
4521 update_pairing(ipsap_t *ipsapp, ipsa_query_t *sq, keysock_in_t *ksi,
4522 int *diagnostic)
4524 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
4525 sadb_x_pair_t *pair_ext =
4526 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4527 int error = 0;
4528 ipsap_t oipsapp;
4529 boolean_t undo_pair = B_FALSE;
4530 uint32_t ipsa_flags;
4532 if (pair_ext->sadb_x_pair_spi == 0 || pair_ext->sadb_x_pair_spi ==
4533 assoc->sadb_sa_spi) {
4534 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4535 return (EINVAL);
4539 * Assume for now that the spi value provided in the SADB_UPDATE
4540 * message was valid, update the SA with its pair spi value.
4541 * If the spi turns out to be bogus or the SA no longer exists
4542 * then this will be detected when the reverse update is made
4543 * below.
4545 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4546 ipsapp->ipsap_sa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4547 ipsapp->ipsap_sa_ptr->ipsa_otherspi = pair_ext->sadb_x_pair_spi;
4548 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4551 * After updating the ipsa_otherspi element of the SA, get_ipsa_pair()
4552 * should now return pointers to the SA *AND* its pair, if this is not
4553 * the case, the "otherspi" either did not exist or was deleted. Also
4554 * check that "otherspi" is not already paired. If everything looks
4555 * good, complete the update. IPSA_REFRELE the first pair_pointer
4556 * after this update to ensure its not deleted until we are done.
4558 error = get_ipsa_pair(sq, &oipsapp, diagnostic);
4559 if (error != 0) {
4561 * This should never happen, calling function still has
4562 * IPSA_REFHELD on the SA we just updated.
4564 return (error); /* XXX EINVAL instead of ESRCH? */
4567 if (oipsapp.ipsap_psa_ptr == NULL) {
4568 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4569 error = EINVAL;
4570 undo_pair = B_TRUE;
4571 } else {
4572 ipsa_flags = oipsapp.ipsap_psa_ptr->ipsa_flags;
4573 if ((oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DEAD) ||
4574 (oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DYING)) {
4575 /* Its dead Jim! */
4576 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4577 undo_pair = B_TRUE;
4578 } else if ((ipsa_flags & (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) ==
4579 (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) {
4580 /* This SA is in both hashtables. */
4581 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4582 undo_pair = B_TRUE;
4583 } else if (ipsa_flags & IPSA_F_PAIRED) {
4584 /* This SA is already paired with another. */
4585 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
4586 undo_pair = B_TRUE;
4590 if (undo_pair) {
4591 /* The pair SA does not exist. */
4592 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4593 ipsapp->ipsap_sa_ptr->ipsa_flags &= ~IPSA_F_PAIRED;
4594 ipsapp->ipsap_sa_ptr->ipsa_otherspi = 0;
4595 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4596 } else {
4597 mutex_enter(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4598 oipsapp.ipsap_psa_ptr->ipsa_otherspi = assoc->sadb_sa_spi;
4599 oipsapp.ipsap_psa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4600 mutex_exit(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4603 destroy_ipsa_pair(&oipsapp);
4604 return (error);
4608 * The following functions deal with ACQUIRE LISTS. An ACQUIRE list is
4609 * a list of outstanding SADB_ACQUIRE messages. If ipsec_getassocbyconn() fails
4610 * for an outbound datagram, that datagram is queued up on an ACQUIRE record,
4611 * and an SADB_ACQUIRE message is sent up. Presumably, a user-space key
4612 * management daemon will process the ACQUIRE, use a SADB_GETSPI to reserve
4613 * an SPI value and a larval SA, then SADB_UPDATE the larval SA, and ADD the
4614 * other direction's SA.
4618 * Check the ACQUIRE lists. If there's an existing ACQUIRE record,
4619 * grab it, lock it, and return it. Otherwise return NULL.
4621 static ipsacq_t *
4622 sadb_checkacquire(iacqf_t *bucket, ipsec_action_t *ap, ipsec_policy_t *pp,
4623 uint32_t *src, uint32_t *dst, uint32_t *isrc, uint32_t *idst,
4624 uint64_t unique_id)
4626 ipsacq_t *walker;
4627 sa_family_t fam;
4628 uint32_t blank_address[4] = {0, 0, 0, 0};
4630 if (isrc == NULL) {
4631 ASSERT(idst == NULL);
4632 isrc = idst = blank_address;
4636 * Scan list for duplicates. Check for UNIQUE, src/dest, policy.
4638 * XXX May need search for duplicates based on other things too!
4640 for (walker = bucket->iacqf_ipsacq; walker != NULL;
4641 walker = walker->ipsacq_next) {
4642 mutex_enter(&walker->ipsacq_lock);
4643 fam = walker->ipsacq_addrfam;
4644 if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
4645 IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
4646 ip_addr_match((uint8_t *)isrc, walker->ipsacq_innersrcpfx,
4647 (in6_addr_t *)walker->ipsacq_innersrc) &&
4648 ip_addr_match((uint8_t *)idst, walker->ipsacq_innerdstpfx,
4649 (in6_addr_t *)walker->ipsacq_innerdst) &&
4650 (ap == walker->ipsacq_act) &&
4651 (pp == walker->ipsacq_policy) &&
4652 /* XXX do deep compares of ap/pp? */
4653 (unique_id == walker->ipsacq_unique_id))
4654 break; /* everything matched */
4655 mutex_exit(&walker->ipsacq_lock);
4658 return (walker);
4662 * Generate an SADB_ACQUIRE base message mblk, including KEYSOCK_OUT metadata.
4663 * In other words, this will return, upon success, a two-mblk chain.
4665 static inline mblk_t *
4666 sadb_acquire_msg_base(minor_t serial, uint8_t satype, uint32_t seq, pid_t pid)
4668 mblk_t *mp;
4669 sadb_msg_t *samsg;
4671 mp = sadb_keysock_out(serial);
4672 if (mp == NULL)
4673 return (NULL);
4674 mp->b_cont = allocb(sizeof (sadb_msg_t), BPRI_HI);
4675 if (mp->b_cont == NULL) {
4676 freeb(mp);
4677 return (NULL);
4680 samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
4681 mp->b_cont->b_wptr += sizeof (*samsg);
4682 samsg->sadb_msg_version = PF_KEY_V2;
4683 samsg->sadb_msg_type = SADB_ACQUIRE;
4684 samsg->sadb_msg_errno = 0;
4685 samsg->sadb_msg_reserved = 0;
4686 samsg->sadb_msg_satype = satype;
4687 samsg->sadb_msg_seq = seq;
4688 samsg->sadb_msg_pid = pid;
4690 return (mp);
4694 * Generate address and TX/MLS sensitivity label PF_KEY extensions that are
4695 * common to both regular and extended ACQUIREs.
4697 static mblk_t *
4698 sadb_acquire_msg_common(ipsec_selector_t *sel, ipsec_policy_t *pp,
4699 ipsec_action_t *ap, boolean_t tunnel_mode)
4701 size_t len;
4702 mblk_t *mp;
4703 uint8_t *start, *cur, *end;
4704 uint32_t *saddrptr, *daddrptr;
4705 sa_family_t af;
4706 ipsec_action_t *oldap;
4707 ipsec_selkey_t *ipsl;
4708 uint8_t proto, pfxlen;
4709 uint16_t lport, rport;
4712 * Get action pointer set if it isn't already.
4714 oldap = ap;
4715 if (pp != NULL) {
4716 ap = pp->ipsp_act;
4717 if (ap == NULL)
4718 ap = oldap;
4722 * Biggest-case scenario:
4723 * 4x (sadb_address_t + struct sockaddr_in6)
4724 * (src, dst, isrc, idst)
4725 * (COMING SOON, 6x, because of triggering-packet contents.)
4726 * sadb_x_kmc_t
4727 * sadb_sens_t
4728 * And wiggle room for label bitvectors. Luckily there are
4729 * programmatic ways to find it.
4731 len = 4 * (sizeof (sadb_address_t) + sizeof (struct sockaddr_in6));
4733 mp = allocb(len, BPRI_HI);
4734 if (mp == NULL)
4735 return (NULL);
4737 start = mp->b_rptr;
4738 end = start + len;
4739 cur = start;
4742 * Address extensions first, from most-recently-defined to least.
4743 * (This should immediately trigger surprise or verify robustness on
4744 * older apps, like in.iked.)
4746 if (tunnel_mode) {
4748 * Form inner address extensions based NOT on the inner
4749 * selectors (i.e. the packet data), but on the policy's
4750 * selector key (i.e. the policy's selector information).
4752 * NOTE: The position of IPv4 and IPv6 addresses is the
4753 * same in ipsec_selkey_t (unless the compiler does very
4754 * strange things with unions, consult your local C language
4755 * lawyer for details).
4757 ASSERT(pp != NULL);
4759 ipsl = &(pp->ipsp_sel->ipsl_key);
4760 if (ipsl->ipsl_valid & IPSL_IPV4) {
4761 af = AF_INET;
4762 ASSERT(sel->ips_protocol == IPPROTO_ENCAP);
4763 ASSERT(!(ipsl->ipsl_valid & IPSL_IPV6));
4764 } else {
4765 af = AF_INET6;
4766 ASSERT(sel->ips_protocol == IPPROTO_IPV6);
4767 ASSERT(ipsl->ipsl_valid & IPSL_IPV6);
4770 if (ipsl->ipsl_valid & IPSL_LOCAL_ADDR) {
4771 saddrptr = (uint32_t *)(&ipsl->ipsl_local);
4772 pfxlen = ipsl->ipsl_local_pfxlen;
4773 } else {
4774 saddrptr = (uint32_t *)(&ipv6_all_zeros);
4775 pfxlen = 0;
4777 /* XXX What about ICMP type/code? */
4778 lport = (ipsl->ipsl_valid & IPSL_LOCAL_PORT) ?
4779 ipsl->ipsl_lport : 0;
4780 proto = (ipsl->ipsl_valid & IPSL_PROTOCOL) ?
4781 ipsl->ipsl_proto : 0;
4783 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
4784 af, saddrptr, lport, proto, pfxlen);
4785 if (cur == NULL) {
4786 freeb(mp);
4787 return (NULL);
4790 if (ipsl->ipsl_valid & IPSL_REMOTE_ADDR) {
4791 daddrptr = (uint32_t *)(&ipsl->ipsl_remote);
4792 pfxlen = ipsl->ipsl_remote_pfxlen;
4793 } else {
4794 daddrptr = (uint32_t *)(&ipv6_all_zeros);
4795 pfxlen = 0;
4797 /* XXX What about ICMP type/code? */
4798 rport = (ipsl->ipsl_valid & IPSL_REMOTE_PORT) ?
4799 ipsl->ipsl_rport : 0;
4801 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
4802 af, daddrptr, rport, proto, pfxlen);
4803 if (cur == NULL) {
4804 freeb(mp);
4805 return (NULL);
4808 * TODO - if we go to 3884's dream of transport mode IP-in-IP
4809 * _with_ inner-packet address selectors, we'll need to further
4810 * distinguish tunnel mode here. For now, having inner
4811 * addresses and/or ports is sufficient.
4813 * Meanwhile, whack proto/ports to reflect IP-in-IP for the
4814 * outer addresses.
4816 proto = sel->ips_protocol; /* Either _ENCAP or _IPV6 */
4817 lport = rport = 0;
4818 } else if ((ap != NULL) && (!ap->ipa_want_unique)) {
4820 * For cases when the policy calls out specific ports (or not).
4822 proto = 0;
4823 lport = 0;
4824 rport = 0;
4825 if (pp != NULL) {
4826 ipsl = &(pp->ipsp_sel->ipsl_key);
4827 if (ipsl->ipsl_valid & IPSL_PROTOCOL)
4828 proto = ipsl->ipsl_proto;
4829 if (ipsl->ipsl_valid & IPSL_REMOTE_PORT)
4830 rport = ipsl->ipsl_rport;
4831 if (ipsl->ipsl_valid & IPSL_LOCAL_PORT)
4832 lport = ipsl->ipsl_lport;
4834 } else {
4836 * For require-unique-SA policies.
4838 proto = sel->ips_protocol;
4839 lport = sel->ips_local_port;
4840 rport = sel->ips_remote_port;
4844 * Regular addresses. These are outer-packet ones for tunnel mode.
4845 * Or for transport mode, the regulard address & port information.
4847 af = sel->ips_isv4 ? AF_INET : AF_INET6;
4850 * NOTE: The position of IPv4 and IPv6 addresses is the same in
4851 * ipsec_selector_t.
4853 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
4854 (uint32_t *)(&sel->ips_local_addr_v6), lport, proto, 0);
4855 if (cur == NULL) {
4856 freeb(mp);
4857 return (NULL);
4860 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
4861 (uint32_t *)(&sel->ips_remote_addr_v6), rport, proto, 0);
4862 if (cur == NULL) {
4863 freeb(mp);
4864 return (NULL);
4868 * If present, generate a sensitivity label.
4870 if (cur > end) {
4871 freeb(mp);
4872 return (NULL);
4874 mp->b_wptr = cur;
4876 return (mp);
4880 * Generate a regular ACQUIRE's proposal extension and KMC information..
4882 static mblk_t *
4883 sadb_acquire_prop(ipsec_action_t *ap, netstack_t *ns, boolean_t do_esp)
4885 ipsec_stack_t *ipss = ns->netstack_ipsec;
4886 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
4887 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
4888 mblk_t *mp = NULL;
4889 sadb_prop_t *prop;
4890 sadb_comb_t *comb;
4891 ipsec_action_t *walker;
4892 int ncombs, allocsize, ealgid, aalgid, aminbits, amaxbits, eminbits,
4893 emaxbits, esaltlen, replay;
4894 uint64_t softbytes, hardbytes, softaddtime, hardaddtime, softusetime,
4895 hardusetime;
4896 uint64_t kmc = 0;
4897 uint32_t kmp = 0;
4900 * Since it's an rwlock read, AND writing to the IPsec algorithms is
4901 * rare, just acquire it once up top, and drop it upon return.
4903 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
4904 if (do_esp) {
4905 uint64_t num_aalgs, num_ealgs;
4907 if (espstack->esp_kstats == NULL)
4908 goto bail;
4910 num_aalgs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
4911 num_ealgs = ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
4912 if (num_ealgs == 0)
4913 goto bail; /* IPsec not loaded yet, apparently. */
4914 num_aalgs++; /* No-auth or self-auth-crypto ESP. */
4916 /* Use netstack's maximum loaded algorithms... */
4917 ncombs = num_ealgs * num_aalgs;
4918 replay = espstack->ipsecesp_replay_size;
4919 } else {
4920 if (ahstack->ah_kstats == NULL)
4921 goto bail;
4923 ncombs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
4925 if (ncombs == 0)
4926 goto bail; /* IPsec not loaded yet, apparently. */
4927 replay = ahstack->ipsecah_replay_size;
4930 allocsize = sizeof (*prop) + ncombs * sizeof (*comb) +
4931 sizeof (sadb_x_kmc_t);
4932 mp = allocb(allocsize, BPRI_HI);
4933 if (mp == NULL)
4934 goto bail;
4935 prop = (sadb_prop_t *)mp->b_rptr;
4936 mp->b_wptr += sizeof (*prop);
4937 comb = (sadb_comb_t *)mp->b_wptr;
4938 /* Decrement allocsize, if it goes to or below 0, stop. */
4939 allocsize -= sizeof (*prop);
4940 prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
4941 prop->sadb_prop_len = SADB_8TO64(sizeof (*prop));
4942 *(uint32_t *)(&prop->sadb_prop_replay) = 0; /* Quick zero-out! */
4943 prop->sadb_prop_replay = replay;
4946 * Based upon algorithm properties, and what-not, prioritize a
4947 * proposal, based on the ordering of the ESP algorithms in the
4948 * alternatives in the policy rule or socket that was placed
4949 * in the acquire record.
4951 * For each action in policy list
4952 * Add combination.
4953 * I should not hit it, but if I've hit limit, return.
4956 for (walker = ap; walker != NULL; walker = walker->ipa_next) {
4957 ipsec_alginfo_t *ealg, *aalg;
4958 ipsec_prot_t *prot;
4960 if (walker->ipa_act.ipa_type != IPSEC_POLICY_APPLY)
4961 continue;
4963 prot = &walker->ipa_act.ipa_apply;
4964 if (walker->ipa_act.ipa_apply.ipp_km_proto != 0)
4965 kmp = walker->ipa_act.ipa_apply.ipp_km_proto;
4966 if (walker->ipa_act.ipa_apply.ipp_km_cookie != 0)
4967 kmc = walker->ipa_act.ipa_apply.ipp_km_cookie;
4968 if (walker->ipa_act.ipa_apply.ipp_replay_depth) {
4969 prop->sadb_prop_replay =
4970 walker->ipa_act.ipa_apply.ipp_replay_depth;
4973 if (do_esp) {
4974 if (!prot->ipp_use_esp)
4975 continue;
4977 if (prot->ipp_esp_auth_alg != 0) {
4978 aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
4979 [prot->ipp_esp_auth_alg];
4980 if (aalg == NULL || !ALG_VALID(aalg))
4981 continue;
4982 } else
4983 aalg = NULL;
4985 ASSERT(prot->ipp_encr_alg > 0);
4986 ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
4987 [prot->ipp_encr_alg];
4988 if (ealg == NULL || !ALG_VALID(ealg))
4989 continue;
4992 * These may want to come from policy rule..
4994 softbytes = espstack->ipsecesp_default_soft_bytes;
4995 hardbytes = espstack->ipsecesp_default_hard_bytes;
4996 softaddtime = espstack->ipsecesp_default_soft_addtime;
4997 hardaddtime = espstack->ipsecesp_default_hard_addtime;
4998 softusetime = espstack->ipsecesp_default_soft_usetime;
4999 hardusetime = espstack->ipsecesp_default_hard_usetime;
5000 } else {
5001 if (!prot->ipp_use_ah)
5002 continue;
5003 ealg = NULL;
5004 aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
5005 [prot->ipp_auth_alg];
5006 if (aalg == NULL || !ALG_VALID(aalg))
5007 continue;
5010 * These may want to come from policy rule..
5012 softbytes = ahstack->ipsecah_default_soft_bytes;
5013 hardbytes = ahstack->ipsecah_default_hard_bytes;
5014 softaddtime = ahstack->ipsecah_default_soft_addtime;
5015 hardaddtime = ahstack->ipsecah_default_hard_addtime;
5016 softusetime = ahstack->ipsecah_default_soft_usetime;
5017 hardusetime = ahstack->ipsecah_default_hard_usetime;
5020 if (ealg == NULL) {
5021 ealgid = eminbits = emaxbits = esaltlen = 0;
5022 } else {
5023 ealgid = ealg->alg_id;
5024 eminbits =
5025 MAX(prot->ipp_espe_minbits, ealg->alg_ef_minbits);
5026 emaxbits =
5027 MIN(prot->ipp_espe_maxbits, ealg->alg_ef_maxbits);
5028 esaltlen = ealg->alg_saltlen;
5031 if (aalg == NULL) {
5032 aalgid = aminbits = amaxbits = 0;
5033 } else {
5034 aalgid = aalg->alg_id;
5035 aminbits = MAX(prot->ipp_espa_minbits,
5036 aalg->alg_ef_minbits);
5037 amaxbits = MIN(prot->ipp_espa_maxbits,
5038 aalg->alg_ef_maxbits);
5041 comb->sadb_comb_flags = 0;
5042 comb->sadb_comb_reserved = 0;
5043 comb->sadb_comb_encrypt = ealgid;
5044 comb->sadb_comb_encrypt_minbits = eminbits;
5045 comb->sadb_comb_encrypt_maxbits = emaxbits;
5046 comb->sadb_x_comb_encrypt_saltbits = SADB_8TO1(esaltlen);
5047 comb->sadb_comb_auth = aalgid;
5048 comb->sadb_comb_auth_minbits = aminbits;
5049 comb->sadb_comb_auth_maxbits = amaxbits;
5050 comb->sadb_comb_soft_allocations = 0;
5051 comb->sadb_comb_hard_allocations = 0;
5052 comb->sadb_comb_soft_bytes = softbytes;
5053 comb->sadb_comb_hard_bytes = hardbytes;
5054 comb->sadb_comb_soft_addtime = softaddtime;
5055 comb->sadb_comb_hard_addtime = hardaddtime;
5056 comb->sadb_comb_soft_usetime = softusetime;
5057 comb->sadb_comb_hard_usetime = hardusetime;
5059 prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
5060 mp->b_wptr += sizeof (*comb);
5061 allocsize -= sizeof (*comb);
5062 /* Should never dip BELOW sizeof (KM cookie extension). */
5063 ASSERT3S(allocsize, >=, sizeof (sadb_x_kmc_t));
5064 if (allocsize <= sizeof (sadb_x_kmc_t))
5065 break; /* out of space.. */
5066 comb++;
5069 /* Don't include KMC extension if there's no room. */
5070 if (((kmp != 0) || (kmc != 0)) && allocsize >= sizeof (sadb_x_kmc_t)) {
5071 if (sadb_make_kmc_ext(mp->b_wptr,
5072 mp->b_wptr + sizeof (sadb_x_kmc_t), kmp, kmc) == NULL) {
5073 freeb(mp);
5074 mp = NULL;
5075 goto bail;
5077 mp->b_wptr += sizeof (sadb_x_kmc_t);
5078 prop->sadb_prop_len += SADB_8TO64(sizeof (sadb_x_kmc_t));
5081 bail:
5082 rw_exit(&ipss->ipsec_alg_lock);
5083 return (mp);
5087 * Generate an extended ACQUIRE's extended-proposal extension.
5089 static mblk_t *
5090 sadb_acquire_extended_prop(ipsec_action_t *ap, netstack_t *ns)
5092 sadb_prop_t *eprop;
5093 uint8_t *cur, *end;
5094 mblk_t *mp;
5095 int allocsize, numecombs = 0, numalgdescs = 0;
5096 uint32_t kmp = 0, replay = 0;
5097 uint64_t kmc = 0;
5098 ipsec_action_t *walker;
5100 allocsize = sizeof (*eprop);
5103 * Going to walk through the action list twice. Once for allocation
5104 * measurement, and once for actual construction.
5106 for (walker = ap; walker != NULL; walker = walker->ipa_next) {
5107 ipsec_prot_t *ipp;
5110 * Skip non-IPsec policies
5112 if (walker->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5113 continue;
5115 ipp = &walker->ipa_act.ipa_apply;
5117 if (walker->ipa_act.ipa_apply.ipp_km_proto)
5118 kmp = ipp->ipp_km_proto;
5119 if (walker->ipa_act.ipa_apply.ipp_km_cookie)
5120 kmc = ipp->ipp_km_cookie;
5121 if (walker->ipa_act.ipa_apply.ipp_replay_depth)
5122 replay = ipp->ipp_replay_depth;
5124 if (ipp->ipp_use_ah)
5125 numalgdescs++;
5126 if (ipp->ipp_use_esp) {
5127 numalgdescs++;
5128 if (ipp->ipp_use_espa)
5129 numalgdescs++;
5132 numecombs++;
5134 ASSERT(numecombs > 0);
5136 allocsize += numecombs * sizeof (sadb_x_ecomb_t) +
5137 numalgdescs * sizeof (sadb_x_algdesc_t) + sizeof (sadb_x_kmc_t);
5138 mp = allocb(allocsize, BPRI_HI);
5139 if (mp == NULL)
5140 return (NULL);
5141 eprop = (sadb_prop_t *)mp->b_rptr;
5142 end = mp->b_rptr + allocsize;
5143 cur = mp->b_rptr + sizeof (*eprop);
5145 eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
5146 eprop->sadb_x_prop_ereserved = 0;
5147 eprop->sadb_x_prop_numecombs = 0;
5148 *(uint32_t *)(&eprop->sadb_prop_replay) = 0; /* Quick zero-out! */
5149 /* Pick ESP's replay default if need be. */
5150 eprop->sadb_prop_replay = (replay == 0) ?
5151 ns->netstack_ipsecesp->ipsecesp_replay_size : replay;
5153 /* This time, walk through and actually allocate. */
5154 for (walker = ap; walker != NULL; walker = walker->ipa_next) {
5156 * Skip non-IPsec policies
5158 if (walker->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5159 continue;
5160 cur = sadb_action_to_ecomb(cur, end, walker, ns);
5161 if (cur == NULL) {
5162 /* NOTE: inverse-ACQUIRE should note this as ENOMEM. */
5163 freeb(mp);
5164 return (NULL);
5166 eprop->sadb_x_prop_numecombs++;
5169 ASSERT(end - cur >= sizeof (sadb_x_kmc_t));
5170 if ((kmp != 0) || (kmc != 0)) {
5171 cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
5172 if (cur == NULL) {
5173 freeb(mp);
5174 return (NULL);
5177 mp->b_wptr = cur;
5178 eprop->sadb_prop_len = SADB_8TO64(cur - mp->b_rptr);
5180 return (mp);
5184 * For this mblk, insert a new acquire record. Assume bucket contains addrs
5185 * of all of the same length. Give up (and drop) if memory
5186 * cannot be allocated for a new one; otherwise, invoke callback to
5187 * send the acquire up..
5189 * In cases where we need both AH and ESP, add the SA to the ESP ACQUIRE
5190 * list. The ah_add_sa_finish() routines can look at the packet's attached
5191 * attributes and handle this case specially.
5193 void
5194 sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah,
5195 boolean_t need_esp)
5197 mblk_t *asyncmp, *regular, *extended, *common, *prop, *eprop;
5198 sadbp_t *spp;
5199 sadb_t *sp;
5200 ipsacq_t *newbie;
5201 iacqf_t *bucket;
5202 ipha_t *ipha = (ipha_t *)datamp->b_rptr;
5203 ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
5204 uint32_t *src, *dst, *isrc, *idst;
5205 ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
5206 ipsec_action_t *ap = ixa->ixa_ipsec_action;
5207 sa_family_t af;
5208 int hashoffset;
5209 uint32_t seq;
5210 uint64_t unique_id = 0;
5211 boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0;
5212 netstack_t *ns = ixa->ixa_ipst->ips_netstack;
5213 ipsec_stack_t *ipss = ns->netstack_ipsec;
5214 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
5215 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
5216 ipsec_selector_t sel;
5217 queue_t *q;
5219 ASSERT((pp != NULL) || (ap != NULL));
5221 ASSERT(need_ah || need_esp);
5223 /* Assign sadb pointers */
5224 if (need_esp) {
5226 * ESP happens first if we need both AH and ESP.
5228 spp = &espstack->esp_sadb;
5229 } else {
5230 spp = &ahstack->ah_sadb;
5232 sp = (ixa->ixa_flags & IXAF_IS_IPV4) ? &spp->s_v4 : &spp->s_v6;
5234 if (ap == NULL)
5235 ap = pp->ipsp_act;
5236 ASSERT(ap != NULL);
5238 if (ap->ipa_act.ipa_apply.ipp_use_unique || tunnel_mode)
5239 unique_id = SA_FORM_UNIQUE_ID(ixa);
5242 * Set up an ACQUIRE record.
5244 * Immediately, make sure the ACQUIRE sequence number doesn't slip
5245 * below the lowest point allowed in the kernel. (In other words,
5246 * make sure the high bit on the sequence number is set.)
5249 seq = keysock_next_seq(ns) | IACQF_LOWEST_SEQ;
5251 if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
5252 src = (uint32_t *)&ipha->ipha_src;
5253 dst = (uint32_t *)&ipha->ipha_dst;
5254 af = AF_INET;
5255 hashoffset = OUTBOUND_HASH_V4(sp, ipha->ipha_dst);
5256 ASSERT(ixa->ixa_flags & IXAF_IS_IPV4);
5257 } else {
5258 ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
5259 src = (uint32_t *)&ip6h->ip6_src;
5260 dst = (uint32_t *)&ip6h->ip6_dst;
5261 af = AF_INET6;
5262 hashoffset = OUTBOUND_HASH_V6(sp, ip6h->ip6_dst);
5263 ASSERT(!(ixa->ixa_flags & IXAF_IS_IPV4));
5266 if (tunnel_mode) {
5267 if (pp == NULL) {
5269 * Tunnel mode with no policy pointer means this is a
5270 * reflected ICMP (like a ECHO REQUEST) that came in
5271 * with self-encapsulated protection. Until we better
5272 * support this, drop the packet.
5274 ip_drop_packet(datamp, B_FALSE, NULL,
5275 DROPPER(ipss, ipds_spd_got_selfencap),
5276 &ipss->ipsec_spd_dropper);
5277 return;
5279 /* Snag inner addresses. */
5280 isrc = ixa->ixa_ipsec_insrc;
5281 idst = ixa->ixa_ipsec_indst;
5282 } else {
5283 isrc = idst = NULL;
5287 * Check buckets to see if there is an existing entry. If so,
5288 * grab it. sadb_checkacquire locks newbie if found.
5290 bucket = &(sp->sdb_acq[hashoffset]);
5291 mutex_enter(&bucket->iacqf_lock);
5292 newbie = sadb_checkacquire(bucket, ap, pp, src, dst, isrc, idst,
5293 unique_id);
5295 if (newbie == NULL) {
5297 * Otherwise, allocate a new one.
5299 newbie = kmem_zalloc(sizeof (*newbie), KM_NOSLEEP);
5300 if (newbie == NULL) {
5301 mutex_exit(&bucket->iacqf_lock);
5302 ip_drop_packet(datamp, B_FALSE, NULL,
5303 DROPPER(ipss, ipds_sadb_acquire_nomem),
5304 &ipss->ipsec_sadb_dropper);
5305 return;
5307 newbie->ipsacq_policy = pp;
5308 if (pp != NULL) {
5309 IPPOL_REFHOLD(pp);
5311 IPACT_REFHOLD(ap);
5312 newbie->ipsacq_act = ap;
5313 newbie->ipsacq_linklock = &bucket->iacqf_lock;
5314 newbie->ipsacq_next = bucket->iacqf_ipsacq;
5315 newbie->ipsacq_ptpn = &bucket->iacqf_ipsacq;
5316 if (newbie->ipsacq_next != NULL)
5317 newbie->ipsacq_next->ipsacq_ptpn = &newbie->ipsacq_next;
5319 bucket->iacqf_ipsacq = newbie;
5320 mutex_init(&newbie->ipsacq_lock, NULL, MUTEX_DEFAULT, NULL);
5321 mutex_enter(&newbie->ipsacq_lock);
5325 * XXX MLS does it actually help us to drop the bucket lock here?
5326 * we have inserted a half-built, locked acquire record into the
5327 * bucket. any competing thread will now be able to lock the bucket
5328 * to scan it, but will immediately pile up on the new acquire
5329 * record's lock; I don't think we gain anything here other than to
5330 * disperse blame for lock contention.
5332 * we might be able to dispense with acquire record locks entirely..
5333 * just use the bucket locks..
5336 mutex_exit(&bucket->iacqf_lock);
5339 * This assert looks silly for now, but we may need to enter newbie's
5340 * mutex during a search.
5342 ASSERT(MUTEX_HELD(&newbie->ipsacq_lock));
5345 * Make the ip_xmit_attr_t into something we can queue.
5346 * If no memory it frees datamp.
5348 asyncmp = ip_xmit_attr_to_mblk(ixa);
5349 if (asyncmp != NULL)
5350 linkb(asyncmp, datamp);
5352 /* Queue up packet. Use b_next. */
5354 if (asyncmp == NULL) {
5355 /* Statistics for allocation failure */
5356 if (ixa->ixa_flags & IXAF_IS_IPV4) {
5357 BUMP_MIB(&ixa->ixa_ipst->ips_ip_mib,
5358 ipIfStatsOutDiscards);
5359 } else {
5360 BUMP_MIB(&ixa->ixa_ipst->ips_ip6_mib,
5361 ipIfStatsOutDiscards);
5363 ip_drop_output("No memory for asyncmp", datamp, NULL);
5364 freemsg(datamp);
5366 * The acquire record will be freed quickly if it's new
5367 * (ipsacq_expire == 0), and will proceed as if no packet
5368 * showed up if not.
5370 mutex_exit(&newbie->ipsacq_lock);
5371 return;
5372 } else if (newbie->ipsacq_numpackets == 0) {
5373 /* First one. */
5374 newbie->ipsacq_mp = asyncmp;
5375 newbie->ipsacq_numpackets = 1;
5376 newbie->ipsacq_expire = gethrestime_sec();
5378 * Extended ACQUIRE with both AH+ESP will use ESP's timeout
5379 * value.
5381 newbie->ipsacq_expire += *spp->s_acquire_timeout;
5382 newbie->ipsacq_seq = seq;
5383 newbie->ipsacq_addrfam = af;
5385 newbie->ipsacq_srcport = ixa->ixa_ipsec_src_port;
5386 newbie->ipsacq_dstport = ixa->ixa_ipsec_dst_port;
5387 newbie->ipsacq_icmp_type = ixa->ixa_ipsec_icmp_type;
5388 newbie->ipsacq_icmp_code = ixa->ixa_ipsec_icmp_code;
5389 if (tunnel_mode) {
5390 newbie->ipsacq_inneraddrfam = ixa->ixa_ipsec_inaf;
5391 newbie->ipsacq_proto = ixa->ixa_ipsec_inaf == AF_INET6 ?
5392 IPPROTO_IPV6 : IPPROTO_ENCAP;
5393 newbie->ipsacq_innersrcpfx = ixa->ixa_ipsec_insrcpfx;
5394 newbie->ipsacq_innerdstpfx = ixa->ixa_ipsec_indstpfx;
5395 IPSA_COPY_ADDR(newbie->ipsacq_innersrc,
5396 ixa->ixa_ipsec_insrc, ixa->ixa_ipsec_inaf);
5397 IPSA_COPY_ADDR(newbie->ipsacq_innerdst,
5398 ixa->ixa_ipsec_indst, ixa->ixa_ipsec_inaf);
5399 } else {
5400 newbie->ipsacq_proto = ixa->ixa_ipsec_proto;
5402 newbie->ipsacq_unique_id = unique_id;
5403 } else {
5404 /* Scan to the end of the list & insert. */
5405 mblk_t *lastone = newbie->ipsacq_mp;
5407 while (lastone->b_next != NULL)
5408 lastone = lastone->b_next;
5409 lastone->b_next = asyncmp;
5410 if (newbie->ipsacq_numpackets++ == ipsacq_maxpackets) {
5411 newbie->ipsacq_numpackets = ipsacq_maxpackets;
5412 lastone = newbie->ipsacq_mp;
5413 newbie->ipsacq_mp = lastone->b_next;
5414 lastone->b_next = NULL;
5416 /* Freeing the async message */
5417 lastone = ip_xmit_attr_free_mblk(lastone);
5418 ip_drop_packet(lastone, B_FALSE, NULL,
5419 DROPPER(ipss, ipds_sadb_acquire_toofull),
5420 &ipss->ipsec_sadb_dropper);
5421 } else {
5422 IP_ACQUIRE_STAT(ipss, qhiwater,
5423 newbie->ipsacq_numpackets);
5428 * Reset addresses. Set them to the most recently added mblk chain,
5429 * so that the address pointers in the acquire record will point
5430 * at an mblk still attached to the acquire list.
5433 newbie->ipsacq_srcaddr = src;
5434 newbie->ipsacq_dstaddr = dst;
5437 * If the acquire record has more than one queued packet, we've
5438 * already sent an ACQUIRE, and don't need to repeat ourself.
5440 if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1) {
5441 /* I have an acquire outstanding already! */
5442 mutex_exit(&newbie->ipsacq_lock);
5443 return;
5446 if (need_esp) {
5447 ESP_BUMP_STAT(espstack, acquire_requests);
5448 q = espstack->esp_pfkey_q;
5449 } else {
5451 * Two cases get us here:
5452 * 1.) AH-only policy.
5454 * 2.) A continuation of an AH+ESP policy, and this is the
5455 * post-ESP, AH-needs-to-send-a-regular-ACQUIRE case.
5456 * (i.e. called from esp_do_outbound_ah().)
5458 AH_BUMP_STAT(ahstack, acquire_requests);
5459 q = ahstack->ah_pfkey_q;
5463 * Get selectors and other policy-expression bits needed for an
5464 * ACQUIRE.
5466 bzero(&sel, sizeof (sel));
5467 sel.ips_isv4 = (ixa->ixa_flags & IXAF_IS_IPV4) != 0;
5468 if (tunnel_mode) {
5469 sel.ips_protocol = (ixa->ixa_ipsec_inaf == AF_INET) ?
5470 IPPROTO_ENCAP : IPPROTO_IPV6;
5471 } else {
5472 sel.ips_protocol = ixa->ixa_ipsec_proto;
5473 sel.ips_local_port = ixa->ixa_ipsec_src_port;
5474 sel.ips_remote_port = ixa->ixa_ipsec_dst_port;
5476 sel.ips_icmp_type = ixa->ixa_ipsec_icmp_type;
5477 sel.ips_icmp_code = ixa->ixa_ipsec_icmp_code;
5478 sel.ips_is_icmp_inv_acq = 0;
5479 if (af == AF_INET) {
5480 sel.ips_local_addr_v4 = ipha->ipha_src;
5481 sel.ips_remote_addr_v4 = ipha->ipha_dst;
5482 } else {
5483 sel.ips_local_addr_v6 = ip6h->ip6_src;
5484 sel.ips_remote_addr_v6 = ip6h->ip6_dst;
5489 * 1. Generate addresses, kmc, and sensitivity. These are "common"
5490 * and should be an mblk pointed to by common. TBD -- eventually it
5491 * will include triggering packet contents as more address extensions.
5493 * 2. Generate ACQUIRE & KEYSOCK_OUT and single-protocol proposal.
5494 * These are "regular" and "prop". String regular->b_cont->b_cont =
5495 * common, common->b_cont = prop.
5497 * 3. If extended register got turned on, generate EXT_ACQUIRE &
5498 * KEYSOCK_OUT and multi-protocol eprop. These are "extended" and
5499 * "eprop". String extended->b_cont->b_cont = dupb(common) and
5500 * extended->b_cont->b_cont->b_cont = prop.
5502 * 4. Deliver: putnext(q, regular) and if there, putnext(q, extended).
5505 regular = extended = prop = eprop = NULL;
5507 common = sadb_acquire_msg_common(&sel, pp, ap, tunnel_mode);
5508 if (common == NULL)
5509 goto bail;
5511 regular = sadb_acquire_msg_base(0, (need_esp ?
5512 SADB_SATYPE_ESP : SADB_SATYPE_AH), newbie->ipsacq_seq, 0);
5513 if (regular == NULL)
5514 goto bail;
5517 * Pardon the boolean cleverness. At least one of need_* must be true.
5518 * If they are equal, it's an AH & ESP policy and ESP needs to go
5519 * first. If they aren't, just check the contents of need_esp.
5521 prop = sadb_acquire_prop(ap, ns, need_esp);
5522 if (prop == NULL)
5523 goto bail;
5525 /* Link the parts together. */
5526 regular->b_cont->b_cont = common;
5527 common->b_cont = prop;
5529 * Prop is now linked, so don't freemsg() it if the extended
5530 * construction goes off the rails.
5532 prop = NULL;
5534 ((sadb_msg_t *)(regular->b_cont->b_rptr))->sadb_msg_len =
5535 SADB_8TO64(msgsize(regular->b_cont));
5538 * If we need an extended ACQUIRE, build it here.
5540 if (keysock_extended_reg(ns)) {
5541 /* NOTE: "common" still points to what we need. */
5542 extended = sadb_acquire_msg_base(0, 0, newbie->ipsacq_seq, 0);
5543 if (extended == NULL) {
5544 common = NULL;
5545 goto bail;
5548 extended->b_cont->b_cont = dupb(common);
5549 common = NULL;
5550 if (extended->b_cont->b_cont == NULL)
5551 goto bail;
5553 eprop = sadb_acquire_extended_prop(ap, ns);
5554 if (eprop == NULL)
5555 goto bail;
5556 extended->b_cont->b_cont->b_cont = eprop;
5558 ((sadb_msg_t *)(extended->b_cont->b_rptr))->sadb_msg_len =
5559 SADB_8TO64(msgsize(extended->b_cont));
5562 /* So we don't hold a lock across putnext()... */
5563 mutex_exit(&newbie->ipsacq_lock);
5565 if (extended != NULL)
5566 putnext(q, extended);
5567 ASSERT(regular != NULL);
5568 putnext(q, regular);
5569 return;
5571 bail:
5572 /* Make this acquire record go away quickly... */
5573 newbie->ipsacq_expire = 0;
5574 /* Exploit freemsg(NULL) being legal for fun & profit. */
5575 freemsg(common);
5576 freemsg(prop);
5577 freemsg(extended);
5578 freemsg(regular);
5579 mutex_exit(&newbie->ipsacq_lock);
5583 * Unlink and free an acquire record.
5585 void
5586 sadb_destroy_acquire(ipsacq_t *acqrec, netstack_t *ns)
5588 mblk_t *mp;
5589 ipsec_stack_t *ipss = ns->netstack_ipsec;
5591 ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
5593 if (acqrec->ipsacq_policy != NULL) {
5594 IPPOL_REFRELE(acqrec->ipsacq_policy);
5596 if (acqrec->ipsacq_act != NULL) {
5597 IPACT_REFRELE(acqrec->ipsacq_act);
5600 /* Unlink */
5601 *(acqrec->ipsacq_ptpn) = acqrec->ipsacq_next;
5602 if (acqrec->ipsacq_next != NULL)
5603 acqrec->ipsacq_next->ipsacq_ptpn = acqrec->ipsacq_ptpn;
5606 * Free hanging mp's.
5608 * XXX Instead of freemsg(), perhaps use IPSEC_REQ_FAILED.
5611 mutex_enter(&acqrec->ipsacq_lock);
5612 while (acqrec->ipsacq_mp != NULL) {
5613 mp = acqrec->ipsacq_mp;
5614 acqrec->ipsacq_mp = mp->b_next;
5615 mp->b_next = NULL;
5616 /* Freeing the async message */
5617 mp = ip_xmit_attr_free_mblk(mp);
5618 ip_drop_packet(mp, B_FALSE, NULL,
5619 DROPPER(ipss, ipds_sadb_acquire_timeout),
5620 &ipss->ipsec_sadb_dropper);
5622 mutex_exit(&acqrec->ipsacq_lock);
5624 /* Free */
5625 mutex_destroy(&acqrec->ipsacq_lock);
5626 kmem_free(acqrec, sizeof (*acqrec));
5630 * Destroy an acquire list fanout.
5632 static void
5633 sadb_destroy_acqlist(iacqf_t **listp, uint_t numentries, boolean_t forever,
5634 netstack_t *ns)
5636 int i;
5637 iacqf_t *list = *listp;
5639 if (list == NULL)
5640 return;
5642 for (i = 0; i < numentries; i++) {
5643 mutex_enter(&(list[i].iacqf_lock));
5644 while (list[i].iacqf_ipsacq != NULL)
5645 sadb_destroy_acquire(list[i].iacqf_ipsacq, ns);
5646 mutex_exit(&(list[i].iacqf_lock));
5647 if (forever)
5648 mutex_destroy(&(list[i].iacqf_lock));
5651 if (forever) {
5652 *listp = NULL;
5653 kmem_free(list, numentries * sizeof (*list));
5658 * Create an algorithm descriptor for an extended ACQUIRE. Filter crypto
5659 * framework's view of reality vs. IPsec's. EF's wins, BTW.
5661 static uint8_t *
5662 sadb_new_algdesc(uint8_t *start, uint8_t *limit,
5663 sadb_x_ecomb_t *ecomb, uint8_t satype, uint8_t algtype,
5664 uint8_t alg, uint16_t minbits, uint16_t maxbits, ipsec_stack_t *ipss)
5666 uint8_t *cur = start;
5667 ipsec_alginfo_t *algp;
5668 sadb_x_algdesc_t *algdesc = (sadb_x_algdesc_t *)cur;
5670 cur += sizeof (*algdesc);
5671 if (cur >= limit)
5672 return (NULL);
5674 ecomb->sadb_x_ecomb_numalgs++;
5677 * Normalize vs. crypto framework's limits. This way, you can specify
5678 * a stronger policy, and when the framework loads a stronger version,
5679 * you can just keep plowing w/o rewhacking your SPD.
5681 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
5682 algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
5683 IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
5684 if (algp == NULL) {
5685 rw_exit(&ipss->ipsec_alg_lock);
5686 return (NULL); /* Algorithm doesn't exist. Fail gracefully. */
5688 if (minbits < algp->alg_ef_minbits)
5689 minbits = algp->alg_ef_minbits;
5690 if (maxbits > algp->alg_ef_maxbits)
5691 maxbits = algp->alg_ef_maxbits;
5692 rw_exit(&ipss->ipsec_alg_lock);
5694 algdesc->sadb_x_algdesc_saltbits = SADB_8TO1(algp->alg_saltlen);
5695 algdesc->sadb_x_algdesc_satype = satype;
5696 algdesc->sadb_x_algdesc_algtype = algtype;
5697 algdesc->sadb_x_algdesc_alg = alg;
5698 algdesc->sadb_x_algdesc_minbits = minbits;
5699 algdesc->sadb_x_algdesc_maxbits = maxbits;
5701 return (cur);
5705 * Convert the given ipsec_action_t into an ecomb starting at *ecomb
5706 * which must fit before *limit
5708 * return NULL if we ran out of room or a pointer to the end of the ecomb.
5710 static uint8_t *
5711 sadb_action_to_ecomb(uint8_t *start, uint8_t *limit, ipsec_action_t *act,
5712 netstack_t *ns)
5714 uint8_t *cur = start;
5715 sadb_x_ecomb_t *ecomb = (sadb_x_ecomb_t *)cur;
5716 ipsec_prot_t *ipp;
5717 ipsec_stack_t *ipss = ns->netstack_ipsec;
5719 cur += sizeof (*ecomb);
5720 if (cur >= limit)
5721 return (NULL);
5723 ASSERT(act->ipa_act.ipa_type == IPSEC_ACT_APPLY);
5725 ipp = &act->ipa_act.ipa_apply;
5727 ecomb->sadb_x_ecomb_numalgs = 0;
5728 ecomb->sadb_x_ecomb_reserved = 0;
5729 ecomb->sadb_x_ecomb_reserved2 = 0;
5731 * No limits on allocations, since we really don't support that
5732 * concept currently.
5734 ecomb->sadb_x_ecomb_soft_allocations = 0;
5735 ecomb->sadb_x_ecomb_hard_allocations = 0;
5738 * XXX TBD: Policy or global parameters will eventually be
5739 * able to fill in some of these.
5741 ecomb->sadb_x_ecomb_flags = 0;
5742 ecomb->sadb_x_ecomb_soft_bytes = 0;
5743 ecomb->sadb_x_ecomb_hard_bytes = 0;
5744 ecomb->sadb_x_ecomb_soft_addtime = 0;
5745 ecomb->sadb_x_ecomb_hard_addtime = 0;
5746 ecomb->sadb_x_ecomb_soft_usetime = 0;
5747 ecomb->sadb_x_ecomb_hard_usetime = 0;
5749 if (ipp->ipp_use_ah) {
5750 cur = sadb_new_algdesc(cur, limit, ecomb,
5751 SADB_SATYPE_AH, SADB_X_ALGTYPE_AUTH, ipp->ipp_auth_alg,
5752 ipp->ipp_ah_minbits, ipp->ipp_ah_maxbits, ipss);
5753 if (cur == NULL)
5754 return (NULL);
5755 ipsecah_fill_defs(ecomb, ns);
5758 if (ipp->ipp_use_esp) {
5759 if (ipp->ipp_use_espa) {
5760 cur = sadb_new_algdesc(cur, limit, ecomb,
5761 SADB_SATYPE_ESP, SADB_X_ALGTYPE_AUTH,
5762 ipp->ipp_esp_auth_alg,
5763 ipp->ipp_espa_minbits,
5764 ipp->ipp_espa_maxbits, ipss);
5765 if (cur == NULL)
5766 return (NULL);
5769 cur = sadb_new_algdesc(cur, limit, ecomb,
5770 SADB_SATYPE_ESP, SADB_X_ALGTYPE_CRYPT,
5771 ipp->ipp_encr_alg,
5772 ipp->ipp_espe_minbits,
5773 ipp->ipp_espe_maxbits, ipss);
5774 if (cur == NULL)
5775 return (NULL);
5776 /* Fill in lifetimes if and only if AH didn't already... */
5777 if (!ipp->ipp_use_ah)
5778 ipsecesp_fill_defs(ecomb, ns);
5781 return (cur);
5785 * Given an SADB_GETSPI message, find an appropriately ranged SA and
5786 * allocate an SA. If there are message improprieties, return (ipsa_t *)-1.
5787 * If there was a memory allocation error, return NULL. (Assume NULL !=
5788 * (ipsa_t *)-1).
5790 * master_spi is passed in host order.
5792 ipsa_t *
5793 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
5794 netstack_t *ns)
5796 sadb_address_t *src =
5797 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
5798 *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
5799 sadb_spirange_t *range =
5800 (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
5801 struct sockaddr_in *ssa, *dsa;
5802 struct sockaddr_in6 *ssa6, *dsa6;
5803 uint32_t *srcaddr, *dstaddr;
5804 sa_family_t af;
5805 uint32_t add, min, max;
5807 if (src == NULL) {
5808 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
5809 return ((ipsa_t *)-1);
5811 if (dst == NULL) {
5812 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
5813 return ((ipsa_t *)-1);
5815 if (range == NULL) {
5816 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_RANGE;
5817 return ((ipsa_t *)-1);
5820 min = ntohl(range->sadb_spirange_min);
5821 max = ntohl(range->sadb_spirange_max);
5822 dsa = (struct sockaddr_in *)(dst + 1);
5823 dsa6 = (struct sockaddr_in6 *)dsa;
5825 ssa = (struct sockaddr_in *)(src + 1);
5826 ssa6 = (struct sockaddr_in6 *)ssa;
5827 ASSERT(dsa->sin_family == ssa->sin_family);
5829 srcaddr = ALL_ZEROES_PTR;
5830 af = dsa->sin_family;
5831 switch (af) {
5832 case AF_INET:
5833 if (src != NULL)
5834 srcaddr = (uint32_t *)(&ssa->sin_addr);
5835 dstaddr = (uint32_t *)(&dsa->sin_addr);
5836 break;
5837 case AF_INET6:
5838 if (src != NULL)
5839 srcaddr = (uint32_t *)(&ssa6->sin6_addr);
5840 dstaddr = (uint32_t *)(&dsa6->sin6_addr);
5841 break;
5842 default:
5843 *diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
5844 return ((ipsa_t *)-1);
5847 if (master_spi < min || master_spi > max) {
5848 /* Return a random value in the range. */
5849 (void) random_get_pseudo_bytes((uint8_t *)&add, sizeof (add));
5850 master_spi = min + (add % (max - min + 1));
5854 * Since master_spi is passed in host order, we need to htonl() it
5855 * for the purposes of creating a new SA.
5857 return (sadb_makelarvalassoc(htonl(master_spi), srcaddr, dstaddr, af,
5858 ns));
5863 * Locate an ACQUIRE and nuke it. If I have an samsg that's larger than the
5864 * base header, just ignore it. Otherwise, lock down the whole ACQUIRE list
5865 * and scan for the sequence number in question. I may wish to accept an
5866 * address pair with it, for easier searching.
5868 * Caller frees the message, so we don't have to here.
5870 * NOTE: The pfkey_q parameter may be used in the future for ACQUIRE
5871 * failures.
5873 /* ARGSUSED */
5874 void
5875 sadb_in_acquire(sadb_msg_t *samsg, sadbp_t *sp, queue_t *pfkey_q,
5876 netstack_t *ns)
5878 int i;
5879 ipsacq_t *acqrec;
5880 iacqf_t *bucket;
5883 * I only accept the base header for this!
5884 * Though to be honest, requiring the dst address would help
5885 * immensely.
5887 * XXX There are already cases where I can get the dst address.
5889 if (samsg->sadb_msg_len > SADB_8TO64(sizeof (*samsg)))
5890 return;
5893 * Using the samsg->sadb_msg_seq, find the ACQUIRE record, delete it,
5894 * (and in the future send a message to IP with the appropriate error
5895 * number).
5897 * Q: Do I want to reject if pid != 0?
5900 for (i = 0; i < sp->s_v4.sdb_hashsize; i++) {
5901 bucket = &sp->s_v4.sdb_acq[i];
5902 mutex_enter(&bucket->iacqf_lock);
5903 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
5904 acqrec = acqrec->ipsacq_next) {
5905 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
5906 break; /* for acqrec... loop. */
5908 if (acqrec != NULL)
5909 break; /* for i = 0... loop. */
5911 mutex_exit(&bucket->iacqf_lock);
5914 if (acqrec == NULL) {
5915 for (i = 0; i < sp->s_v6.sdb_hashsize; i++) {
5916 bucket = &sp->s_v6.sdb_acq[i];
5917 mutex_enter(&bucket->iacqf_lock);
5918 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
5919 acqrec = acqrec->ipsacq_next) {
5920 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
5921 break; /* for acqrec... loop. */
5923 if (acqrec != NULL)
5924 break; /* for i = 0... loop. */
5926 mutex_exit(&bucket->iacqf_lock);
5931 if (acqrec == NULL)
5932 return;
5935 * What do I do with the errno and IP? I may need mp's services a
5936 * little more. See sadb_destroy_acquire() for future directions
5937 * beyond free the mblk chain on the acquire record.
5940 ASSERT(&bucket->iacqf_lock == acqrec->ipsacq_linklock);
5941 sadb_destroy_acquire(acqrec, ns);
5942 /* Have to exit mutex here, because of breaking out of for loop. */
5943 mutex_exit(&bucket->iacqf_lock);
5947 * The following functions work with the replay windows of an SA. They assume
5948 * the ipsa->ipsa_replay_arr is an array of uint64_t, and that the bit vector
5949 * represents the highest sequence number packet received, and back
5950 * (ipsa->ipsa_replay_wsize) packets.
5954 * Is the replay bit set?
5956 static boolean_t
5957 ipsa_is_replay_set(ipsa_t *ipsa, uint32_t offset)
5959 uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
5961 return ((bit & ipsa->ipsa_replay_arr[offset >> 6]) ? B_TRUE : B_FALSE);
5965 * Shift the bits of the replay window over.
5967 static void
5968 ipsa_shift_replay(ipsa_t *ipsa, uint32_t shift)
5970 int i;
5971 int jump = ((shift - 1) >> 6) + 1;
5973 if (shift == 0)
5974 return;
5976 for (i = (ipsa->ipsa_replay_wsize - 1) >> 6; i >= 0; i--) {
5977 if (i + jump <= (ipsa->ipsa_replay_wsize - 1) >> 6) {
5978 ipsa->ipsa_replay_arr[i + jump] |=
5979 ipsa->ipsa_replay_arr[i] >> (64 - (shift & 63));
5981 ipsa->ipsa_replay_arr[i] <<= shift;
5986 * Set a bit in the bit vector.
5988 static void
5989 ipsa_set_replay(ipsa_t *ipsa, uint32_t offset)
5991 uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
5993 ipsa->ipsa_replay_arr[offset >> 6] |= bit;
5996 #define SADB_MAX_REPLAY_VALUE 0xffffffff
5999 * Assume caller has NOT done ntohl() already on seq. Check to see
6000 * if replay sequence number "seq" has been seen already.
6002 boolean_t
6003 sadb_replay_check(ipsa_t *ipsa, uint32_t seq)
6005 boolean_t rc;
6006 uint32_t diff;
6008 if (ipsa->ipsa_replay_wsize == 0)
6009 return (B_TRUE);
6012 * NOTE: I've already checked for 0 on the wire in sadb_replay_peek().
6015 /* Convert sequence number into host order before holding the mutex. */
6016 seq = ntohl(seq);
6018 mutex_enter(&ipsa->ipsa_lock);
6020 /* Initialize inbound SA's ipsa_replay field to last one received. */
6021 if (ipsa->ipsa_replay == 0)
6022 ipsa->ipsa_replay = 1;
6024 if (seq > ipsa->ipsa_replay) {
6026 * I have received a new "highest value received". Shift
6027 * the replay window over.
6029 diff = seq - ipsa->ipsa_replay;
6030 if (diff < ipsa->ipsa_replay_wsize) {
6031 /* In replay window, shift bits over. */
6032 ipsa_shift_replay(ipsa, diff);
6033 } else {
6034 /* WAY FAR AHEAD, clear bits and start again. */
6035 bzero(ipsa->ipsa_replay_arr,
6036 sizeof (ipsa->ipsa_replay_arr));
6038 ipsa_set_replay(ipsa, 0);
6039 ipsa->ipsa_replay = seq;
6040 rc = B_TRUE;
6041 goto done;
6043 diff = ipsa->ipsa_replay - seq;
6044 if (diff >= ipsa->ipsa_replay_wsize || ipsa_is_replay_set(ipsa, diff)) {
6045 rc = B_FALSE;
6046 goto done;
6048 /* Set this packet as seen. */
6049 ipsa_set_replay(ipsa, diff);
6051 rc = B_TRUE;
6052 done:
6053 mutex_exit(&ipsa->ipsa_lock);
6054 return (rc);
6058 * "Peek" and see if we should even bother going through the effort of
6059 * running an authentication check on the sequence number passed in.
6060 * this takes into account packets that are below the replay window,
6061 * and collisions with already replayed packets. Return B_TRUE if it
6062 * is okay to proceed, B_FALSE if this packet should be dropped immediately.
6063 * Assume same byte-ordering as sadb_replay_check.
6065 boolean_t
6066 sadb_replay_peek(ipsa_t *ipsa, uint32_t seq)
6068 boolean_t rc = B_FALSE;
6069 uint32_t diff;
6071 if (ipsa->ipsa_replay_wsize == 0)
6072 return (B_TRUE);
6075 * 0 is 0, regardless of byte order... :)
6077 * If I get 0 on the wire (and there is a replay window) then the
6078 * sender most likely wrapped. This ipsa may need to be marked or
6079 * something.
6081 if (seq == 0)
6082 return (B_FALSE);
6084 seq = ntohl(seq);
6085 mutex_enter(&ipsa->ipsa_lock);
6086 if (seq < ipsa->ipsa_replay - ipsa->ipsa_replay_wsize &&
6087 ipsa->ipsa_replay >= ipsa->ipsa_replay_wsize)
6088 goto done;
6091 * If I've hit 0xffffffff, then quite honestly, I don't need to
6092 * bother with formalities. I'm not accepting any more packets
6093 * on this SA.
6095 if (ipsa->ipsa_replay == SADB_MAX_REPLAY_VALUE) {
6097 * Since we're already holding the lock, update the
6098 * expire time ala. sadb_replay_delete() and return.
6100 ipsa->ipsa_hardexpiretime = (time_t)1;
6101 goto done;
6104 if (seq <= ipsa->ipsa_replay) {
6106 * This seq is in the replay window. I'm not below it,
6107 * because I already checked for that above!
6109 diff = ipsa->ipsa_replay - seq;
6110 if (ipsa_is_replay_set(ipsa, diff))
6111 goto done;
6113 /* Else return B_TRUE, I'm going to advance the window. */
6115 rc = B_TRUE;
6116 done:
6117 mutex_exit(&ipsa->ipsa_lock);
6118 return (rc);
6122 * Delete a single SA.
6124 * For now, use the quick-and-dirty trick of making the association's
6125 * hard-expire lifetime (time_t)1, ensuring deletion by the *_ager().
6127 void
6128 sadb_replay_delete(ipsa_t *assoc)
6130 mutex_enter(&assoc->ipsa_lock);
6131 assoc->ipsa_hardexpiretime = (time_t)1;
6132 mutex_exit(&assoc->ipsa_lock);
6136 * Special front-end to ipsec_rl_strlog() dealing with SA failure.
6137 * this is designed to take only a format string with "* %x * %s *", so
6138 * that "spi" is printed first, then "addr" is converted using inet_pton().
6140 * This is abstracted out to save the stack space for only when inet_pton()
6141 * is called. Make sure "spi" is in network order; it usually is when this
6142 * would get called.
6144 void
6145 ipsec_assocfailure(short mid, short sid, char level, ushort_t sl, char *fmt,
6146 uint32_t spi, void *addr, int af, netstack_t *ns)
6148 char buf[INET6_ADDRSTRLEN];
6150 ASSERT(af == AF_INET6 || af == AF_INET);
6152 ipsec_rl_strlog(ns, mid, sid, level, sl, fmt, ntohl(spi),
6153 inet_ntop(af, addr, buf, sizeof (buf)));
6157 * Fills in a reference to the policy, if any, from the conn, in *ppp
6159 static void
6160 ipsec_conn_pol(ipsec_selector_t *sel, conn_t *connp, ipsec_policy_t **ppp)
6162 ipsec_policy_t *pp;
6163 ipsec_latch_t *ipl = connp->conn_latch;
6165 if ((ipl != NULL) && (connp->conn_ixa->ixa_ipsec_policy != NULL)) {
6166 pp = connp->conn_ixa->ixa_ipsec_policy;
6167 IPPOL_REFHOLD(pp);
6168 } else {
6169 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, connp, sel,
6170 connp->conn_netstack);
6172 *ppp = pp;
6176 * The following functions scan through active conn_t structures
6177 * and return a reference to the best-matching policy it can find.
6178 * Caller must release the reference.
6180 static void
6181 ipsec_udp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6183 connf_t *connfp;
6184 conn_t *connp = NULL;
6185 ipsec_selector_t portonly;
6187 bzero((void *)&portonly, sizeof (portonly));
6189 if (sel->ips_local_port == 0)
6190 return;
6192 connfp = &ipst->ips_ipcl_udp_fanout[IPCL_UDP_HASH(sel->ips_local_port,
6193 ipst)];
6194 mutex_enter(&connfp->connf_lock);
6196 if (sel->ips_isv4) {
6197 connp = connfp->connf_head;
6198 while (connp != NULL) {
6199 if (IPCL_UDP_MATCH(connp, sel->ips_local_port,
6200 sel->ips_local_addr_v4, sel->ips_remote_port,
6201 sel->ips_remote_addr_v4))
6202 break;
6203 connp = connp->conn_next;
6206 if (connp == NULL) {
6207 /* Try port-only match in IPv6. */
6208 portonly.ips_local_port = sel->ips_local_port;
6209 sel = &portonly;
6213 if (connp == NULL) {
6214 connp = connfp->connf_head;
6215 while (connp != NULL) {
6216 if (IPCL_UDP_MATCH_V6(connp, sel->ips_local_port,
6217 sel->ips_local_addr_v6, sel->ips_remote_port,
6218 sel->ips_remote_addr_v6))
6219 break;
6220 connp = connp->conn_next;
6223 if (connp == NULL) {
6224 mutex_exit(&connfp->connf_lock);
6225 return;
6229 CONN_INC_REF(connp);
6230 mutex_exit(&connfp->connf_lock);
6232 ipsec_conn_pol(sel, connp, ppp);
6233 CONN_DEC_REF(connp);
6236 static conn_t *
6237 ipsec_find_listen_conn(uint16_t *pptr, ipsec_selector_t *sel, ip_stack_t *ipst)
6239 connf_t *connfp;
6240 conn_t *connp = NULL;
6241 const in6_addr_t *v6addrmatch = &sel->ips_local_addr_v6;
6243 if (sel->ips_local_port == 0)
6244 return (NULL);
6246 connfp = &ipst->ips_ipcl_bind_fanout[
6247 IPCL_BIND_HASH(sel->ips_local_port, ipst)];
6248 mutex_enter(&connfp->connf_lock);
6250 if (sel->ips_isv4) {
6251 connp = connfp->connf_head;
6252 while (connp != NULL) {
6253 if (IPCL_BIND_MATCH(connp, IPPROTO_TCP,
6254 sel->ips_local_addr_v4, pptr[1]))
6255 break;
6256 connp = connp->conn_next;
6259 if (connp == NULL) {
6260 /* Match to all-zeroes. */
6261 v6addrmatch = &ipv6_all_zeros;
6265 if (connp == NULL) {
6266 connp = connfp->connf_head;
6267 while (connp != NULL) {
6268 if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP,
6269 *v6addrmatch, pptr[1]))
6270 break;
6271 connp = connp->conn_next;
6274 if (connp == NULL) {
6275 mutex_exit(&connfp->connf_lock);
6276 return (NULL);
6280 CONN_INC_REF(connp);
6281 mutex_exit(&connfp->connf_lock);
6282 return (connp);
6285 static void
6286 ipsec_tcp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6288 connf_t *connfp;
6289 conn_t *connp;
6290 uint32_t ports;
6291 uint16_t *pptr = (uint16_t *)&ports;
6294 * Find TCP state in the following order:
6295 * 1.) Connected conns.
6296 * 2.) Listeners.
6298 * Even though #2 will be the common case for inbound traffic, only
6299 * following this order insures correctness.
6302 if (sel->ips_local_port == 0)
6303 return;
6306 * 0 should be fport, 1 should be lport. SRC is the local one here.
6307 * See ipsec_construct_inverse_acquire() for details.
6309 pptr[0] = sel->ips_remote_port;
6310 pptr[1] = sel->ips_local_port;
6312 connfp = &ipst->ips_ipcl_conn_fanout[
6313 IPCL_CONN_HASH(sel->ips_remote_addr_v4, ports, ipst)];
6314 mutex_enter(&connfp->connf_lock);
6315 connp = connfp->connf_head;
6317 if (sel->ips_isv4) {
6318 while (connp != NULL) {
6319 if (IPCL_CONN_MATCH(connp, IPPROTO_TCP,
6320 sel->ips_remote_addr_v4, sel->ips_local_addr_v4,
6321 ports))
6322 break;
6323 connp = connp->conn_next;
6325 } else {
6326 while (connp != NULL) {
6327 if (IPCL_CONN_MATCH_V6(connp, IPPROTO_TCP,
6328 sel->ips_remote_addr_v6, sel->ips_local_addr_v6,
6329 ports))
6330 break;
6331 connp = connp->conn_next;
6335 if (connp != NULL) {
6336 CONN_INC_REF(connp);
6337 mutex_exit(&connfp->connf_lock);
6338 } else {
6339 mutex_exit(&connfp->connf_lock);
6341 /* Try the listen hash. */
6342 if ((connp = ipsec_find_listen_conn(pptr, sel, ipst)) == NULL)
6343 return;
6346 ipsec_conn_pol(sel, connp, ppp);
6347 CONN_DEC_REF(connp);
6350 static void
6351 ipsec_sctp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6352 ip_stack_t *ipst)
6354 conn_t *connp;
6355 uint32_t ports;
6356 uint16_t *pptr = (uint16_t *)&ports;
6359 * Find SCP state in the following order:
6360 * 1.) Connected conns.
6361 * 2.) Listeners.
6363 * Even though #2 will be the common case for inbound traffic, only
6364 * following this order insures correctness.
6367 if (sel->ips_local_port == 0)
6368 return;
6371 * 0 should be fport, 1 should be lport. SRC is the local one here.
6372 * See ipsec_construct_inverse_acquire() for details.
6374 pptr[0] = sel->ips_remote_port;
6375 pptr[1] = sel->ips_local_port;
6378 * For labeled systems, there's no need to check the
6379 * label here. It's known to be good as we checked
6380 * before allowing the connection to become bound.
6382 if (sel->ips_isv4) {
6383 in6_addr_t src, dst;
6385 IN6_IPADDR_TO_V4MAPPED(sel->ips_remote_addr_v4, &dst);
6386 IN6_IPADDR_TO_V4MAPPED(sel->ips_local_addr_v4, &src);
6387 connp = sctp_find_conn(&dst, &src, ports, ALL_ZONES,
6388 0, ipst->ips_netstack->netstack_sctp);
6389 } else {
6390 connp = sctp_find_conn(&sel->ips_remote_addr_v6,
6391 &sel->ips_local_addr_v6, ports, ALL_ZONES,
6392 0, ipst->ips_netstack->netstack_sctp);
6394 if (connp == NULL)
6395 return;
6396 ipsec_conn_pol(sel, connp, ppp);
6397 CONN_DEC_REF(connp);
6401 * Fill in a query for the SPD (in "sel") using two PF_KEY address extensions.
6402 * Returns 0 or errno, and always sets *diagnostic to something appropriate
6403 * to PF_KEY.
6405 * NOTE: For right now, this function (and ipsec_selector_t for that matter),
6406 * ignore prefix lengths in the address extension. Since we match on first-
6407 * entered policies, this shouldn't matter. Also, since we normalize prefix-
6408 * set addresses to mask out the lower bits, we should get a suitable search
6409 * key for the SPD anyway. This is the function to change if the assumption
6410 * about suitable search keys is wrong.
6412 static int
6413 ipsec_get_inverse_acquire_sel(ipsec_selector_t *sel, sadb_address_t *srcext,
6414 sadb_address_t *dstext, int *diagnostic)
6416 struct sockaddr_in *src, *dst;
6417 struct sockaddr_in6 *src6, *dst6;
6419 *diagnostic = 0;
6421 bzero(sel, sizeof (*sel));
6422 sel->ips_protocol = srcext->sadb_address_proto;
6423 dst = (struct sockaddr_in *)(dstext + 1);
6424 if (dst->sin_family == AF_INET6) {
6425 dst6 = (struct sockaddr_in6 *)dst;
6426 src6 = (struct sockaddr_in6 *)(srcext + 1);
6427 if (src6->sin6_family != AF_INET6) {
6428 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6429 return (EINVAL);
6431 sel->ips_remote_addr_v6 = dst6->sin6_addr;
6432 sel->ips_local_addr_v6 = src6->sin6_addr;
6433 if (sel->ips_protocol == IPPROTO_ICMPV6) {
6434 sel->ips_is_icmp_inv_acq = 1;
6435 } else {
6436 sel->ips_remote_port = dst6->sin6_port;
6437 sel->ips_local_port = src6->sin6_port;
6439 sel->ips_isv4 = B_FALSE;
6440 } else {
6441 src = (struct sockaddr_in *)(srcext + 1);
6442 if (src->sin_family != AF_INET) {
6443 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6444 return (EINVAL);
6446 sel->ips_remote_addr_v4 = dst->sin_addr.s_addr;
6447 sel->ips_local_addr_v4 = src->sin_addr.s_addr;
6448 if (sel->ips_protocol == IPPROTO_ICMP) {
6449 sel->ips_is_icmp_inv_acq = 1;
6450 } else {
6451 sel->ips_remote_port = dst->sin_port;
6452 sel->ips_local_port = src->sin_port;
6454 sel->ips_isv4 = B_TRUE;
6456 return (0);
6460 * We have encapsulation.
6461 * - Lookup tun_t by address and look for an associated
6462 * tunnel policy
6463 * - If there are inner selectors
6464 * - check ITPF_P_TUNNEL and ITPF_P_ACTIVE
6465 * - Look up tunnel policy based on selectors
6466 * - Else
6467 * - Sanity check the negotation
6468 * - If appropriate, fall through to global policy
6470 static int
6471 ipsec_tun_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6472 sadb_address_t *innsrcext, sadb_address_t *inndstext, ipsec_tun_pol_t *itp,
6473 int *diagnostic)
6475 int err;
6476 ipsec_policy_head_t *polhead;
6478 *diagnostic = 0;
6480 /* Check for inner selectors and act appropriately */
6482 if (innsrcext != NULL) {
6483 /* Inner selectors present */
6484 ASSERT(inndstext != NULL);
6485 if ((itp == NULL) ||
6486 (itp->itp_flags & (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) !=
6487 (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) {
6489 * If inner packet selectors, we must have negotiate
6490 * tunnel and active policy. If the tunnel has
6491 * transport-mode policy set on it, or has no policy,
6492 * fail.
6494 return (ENOENT);
6495 } else {
6497 * Reset "sel" to indicate inner selectors. Pass
6498 * inner PF_KEY address extensions for this to happen.
6500 if ((err = ipsec_get_inverse_acquire_sel(sel,
6501 innsrcext, inndstext, diagnostic)) != 0)
6502 return (err);
6504 * Now look for a tunnel policy based on those inner
6505 * selectors. (Common code is below.)
6508 } else {
6509 /* No inner selectors present */
6510 if ((itp == NULL) || !(itp->itp_flags & ITPF_P_ACTIVE)) {
6512 * Transport mode negotiation with no tunnel policy
6513 * configured - return to indicate a global policy
6514 * check is needed.
6516 return (0);
6517 } else if (itp->itp_flags & ITPF_P_TUNNEL) {
6518 /* Tunnel mode set with no inner selectors. */
6519 return (ENOENT);
6522 * Else, this is a tunnel policy configured with ifconfig(1m)
6523 * or "negotiate transport" with ipsecconf(1m). We have an
6524 * itp with policy set based on any match, so don't bother
6525 * changing fields in "sel".
6529 ASSERT(itp != NULL);
6530 polhead = itp->itp_policy;
6531 ASSERT(polhead != NULL);
6532 rw_enter(&polhead->iph_lock, RW_READER);
6533 *ppp = ipsec_find_policy_head(NULL, polhead, IPSEC_TYPE_INBOUND, sel);
6534 rw_exit(&polhead->iph_lock);
6537 * Don't default to global if we didn't find a matching policy entry.
6538 * Instead, send ENOENT, just like if we hit a transport-mode tunnel.
6540 if (*ppp == NULL)
6541 return (ENOENT);
6543 return (0);
6547 * For sctp conn_faddr is the primary address, hence this is of limited
6548 * use for sctp.
6550 static void
6551 ipsec_oth_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6552 ip_stack_t *ipst)
6554 boolean_t isv4 = sel->ips_isv4;
6555 connf_t *connfp;
6556 conn_t *connp;
6558 if (isv4) {
6559 connfp = &ipst->ips_ipcl_proto_fanout_v4[sel->ips_protocol];
6560 } else {
6561 connfp = &ipst->ips_ipcl_proto_fanout_v6[sel->ips_protocol];
6564 mutex_enter(&connfp->connf_lock);
6565 for (connp = connfp->connf_head; connp != NULL;
6566 connp = connp->conn_next) {
6567 if (isv4) {
6568 if ((connp->conn_laddr_v4 == INADDR_ANY ||
6569 connp->conn_laddr_v4 == sel->ips_local_addr_v4) &&
6570 (connp->conn_faddr_v4 == INADDR_ANY ||
6571 connp->conn_faddr_v4 == sel->ips_remote_addr_v4))
6572 break;
6573 } else {
6574 if ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
6575 IN6_ARE_ADDR_EQUAL(&connp->conn_laddr_v6,
6576 &sel->ips_local_addr_v6)) &&
6577 (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) ||
6578 IN6_ARE_ADDR_EQUAL(&connp->conn_faddr_v6,
6579 &sel->ips_remote_addr_v6)))
6580 break;
6583 if (connp == NULL) {
6584 mutex_exit(&connfp->connf_lock);
6585 return;
6588 CONN_INC_REF(connp);
6589 mutex_exit(&connfp->connf_lock);
6591 ipsec_conn_pol(sel, connp, ppp);
6592 CONN_DEC_REF(connp);
6596 * Construct an inverse ACQUIRE reply based on:
6598 * 1.) Current global policy.
6599 * 2.) An conn_t match depending on what all was passed in the extv[].
6600 * 3.) A tunnel's policy head.
6601 * ...
6602 * N.) Other stuff TBD (e.g. identities)
6604 * If there is an error, set sadb_msg_errno and sadb_x_msg_diagnostic
6605 * in this function so the caller can extract them where appropriately.
6607 * The SRC address is the local one - just like an outbound ACQUIRE message.
6609 * XXX MLS: key management supplies a label which we just reflect back up
6610 * again. clearly we need to involve the label in the rest of the checks.
6612 mblk_t *
6613 ipsec_construct_inverse_acquire(sadb_msg_t *samsg, sadb_ext_t *extv[],
6614 netstack_t *ns)
6616 int err;
6617 int diagnostic;
6618 sadb_address_t *srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC],
6619 *dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST],
6620 *innsrcext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC],
6621 *inndstext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST];
6622 struct sockaddr_in6 *src, *dst;
6623 struct sockaddr_in6 *isrc, *idst;
6624 ipsec_tun_pol_t *itp = NULL;
6625 ipsec_policy_t *pp = NULL;
6626 ipsec_selector_t sel, isel;
6627 mblk_t *retmp = NULL;
6628 ip_stack_t *ipst = ns->netstack_ip;
6631 /* Normalize addresses */
6632 if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)srcext, 0, ns)
6633 == KS_IN_ADDR_UNKNOWN) {
6634 err = EINVAL;
6635 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC;
6636 goto bail;
6638 src = (struct sockaddr_in6 *)(srcext + 1);
6639 if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)dstext, 0, ns)
6640 == KS_IN_ADDR_UNKNOWN) {
6641 err = EINVAL;
6642 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST;
6643 goto bail;
6645 dst = (struct sockaddr_in6 *)(dstext + 1);
6646 if (src->sin6_family != dst->sin6_family) {
6647 err = EINVAL;
6648 diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6649 goto bail;
6652 /* Check for tunnel mode and act appropriately */
6653 if (innsrcext != NULL) {
6654 if (inndstext == NULL) {
6655 err = EINVAL;
6656 diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_DST;
6657 goto bail;
6659 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
6660 (sadb_ext_t *)innsrcext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
6661 err = EINVAL;
6662 diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC;
6663 goto bail;
6665 isrc = (struct sockaddr_in6 *)(innsrcext + 1);
6666 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
6667 (sadb_ext_t *)inndstext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
6668 err = EINVAL;
6669 diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST;
6670 goto bail;
6672 idst = (struct sockaddr_in6 *)(inndstext + 1);
6673 if (isrc->sin6_family != idst->sin6_family) {
6674 err = EINVAL;
6675 diagnostic = SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
6676 goto bail;
6678 if (isrc->sin6_family != AF_INET &&
6679 isrc->sin6_family != AF_INET6) {
6680 err = EINVAL;
6681 diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_SRC_AF;
6682 goto bail;
6684 } else if (inndstext != NULL) {
6685 err = EINVAL;
6686 diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
6687 goto bail;
6690 /* Get selectors first, based on outer addresses */
6691 err = ipsec_get_inverse_acquire_sel(&sel, srcext, dstext, &diagnostic);
6692 if (err != 0)
6693 goto bail;
6695 /* Check for tunnel mode mismatches. */
6696 if (innsrcext != NULL &&
6697 ((isrc->sin6_family == AF_INET &&
6698 sel.ips_protocol != IPPROTO_ENCAP && sel.ips_protocol != 0) ||
6699 (isrc->sin6_family == AF_INET6 &&
6700 sel.ips_protocol != IPPROTO_IPV6 && sel.ips_protocol != 0))) {
6701 err = EPROTOTYPE;
6702 goto bail;
6706 * Okay, we have the addresses and other selector information.
6707 * Let's first find a conn...
6709 pp = NULL;
6710 switch (sel.ips_protocol) {
6711 case IPPROTO_TCP:
6712 ipsec_tcp_pol(&sel, &pp, ipst);
6713 break;
6714 case IPPROTO_UDP:
6715 ipsec_udp_pol(&sel, &pp, ipst);
6716 break;
6717 case IPPROTO_SCTP:
6718 ipsec_sctp_pol(&sel, &pp, ipst);
6719 break;
6720 case IPPROTO_ENCAP:
6721 case IPPROTO_IPV6:
6723 * Assume sel.ips_remote_addr_* has the right address at
6724 * that exact position.
6726 itp = itp_get_byaddr((uint32_t *)(&sel.ips_local_addr_v6),
6727 (uint32_t *)(&sel.ips_remote_addr_v6), src->sin6_family,
6728 ipst);
6730 if (innsrcext == NULL) {
6732 * Transport-mode tunnel, make sure we fake out isel
6733 * to contain something based on the outer protocol.
6735 bzero(&isel, sizeof (isel));
6736 isel.ips_isv4 = (sel.ips_protocol == IPPROTO_ENCAP);
6737 } /* Else isel is initialized by ipsec_tun_pol(). */
6738 err = ipsec_tun_pol(&isel, &pp, innsrcext, inndstext, itp,
6739 &diagnostic);
6741 * NOTE: isel isn't used for now, but in RFC 430x IPsec, it
6742 * may be.
6744 if (err != 0)
6745 goto bail;
6746 break;
6747 default:
6748 ipsec_oth_pol(&sel, &pp, ipst);
6749 break;
6753 * If we didn't find a matching conn_t or other policy head, take a
6754 * look in the global policy.
6756 if (pp == NULL) {
6757 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, &sel, ns);
6758 if (pp == NULL) {
6759 /* There's no global policy. */
6760 err = ENOENT;
6761 diagnostic = 0;
6762 goto bail;
6766 ASSERT(pp != NULL);
6767 retmp = sadb_acquire_msg_base(0, 0, samsg->sadb_msg_seq,
6768 samsg->sadb_msg_pid);
6769 if (retmp != NULL) {
6770 /* Remove KEYSOCK_OUT, because caller constructs it instead. */
6771 mblk_t *kso = retmp;
6773 retmp = retmp->b_cont;
6774 freeb(kso);
6775 /* Append addresses... */
6776 retmp->b_cont = sadb_acquire_msg_common(&sel, pp, NULL,
6777 (itp != NULL && (itp->itp_flags & ITPF_P_TUNNEL)));
6778 if (retmp->b_cont == NULL) {
6779 freemsg(retmp);
6780 retmp = NULL;
6782 /* And the policy result. */
6783 retmp->b_cont->b_cont =
6784 sadb_acquire_extended_prop(pp->ipsp_act, ns);
6785 if (retmp->b_cont->b_cont == NULL) {
6786 freemsg(retmp);
6787 retmp = NULL;
6789 ((sadb_msg_t *)retmp->b_rptr)->sadb_msg_len =
6790 SADB_8TO64(msgsize(retmp));
6793 if (pp != NULL) {
6794 IPPOL_REFRELE(pp);
6796 ASSERT(err == 0 && diagnostic == 0);
6797 if (retmp == NULL)
6798 err = ENOMEM;
6799 bail:
6800 if (itp != NULL) {
6801 ITP_REFRELE(itp, ns);
6803 samsg->sadb_msg_errno = (uint8_t)err;
6804 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
6805 return (retmp);
6809 * ipsa_lpkt is a one-element queue, only manipulated by the next two
6810 * functions. They have to hold the ipsa_lock because of potential races
6811 * between key management using SADB_UPDATE, and inbound packets that may
6812 * queue up on the larval SA (hence the 'l' in "lpkt").
6816 * sadb_set_lpkt:
6818 * Returns the passed-in packet if the SA is no longer larval.
6820 * Returns NULL if the SA is larval, and needs to be swapped into the SA for
6821 * processing after an SADB_UPDATE.
6823 mblk_t *
6824 sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt, ip_recv_attr_t *ira)
6826 mblk_t *opkt;
6828 mutex_enter(&ipsa->ipsa_lock);
6829 opkt = ipsa->ipsa_lpkt;
6830 if (ipsa->ipsa_state == IPSA_STATE_LARVAL) {
6832 * Consume npkt and place it in the LARVAL SA's inbound
6833 * packet slot.
6835 mblk_t *attrmp;
6837 attrmp = ip_recv_attr_to_mblk(ira);
6838 if (attrmp == NULL) {
6839 ill_t *ill = ira->ira_ill;
6841 BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
6842 ip_drop_input("ipIfStatsInDiscards", npkt, ill);
6843 freemsg(npkt);
6844 opkt = NULL;
6845 } else {
6846 ASSERT(attrmp->b_cont == NULL);
6847 attrmp->b_cont = npkt;
6848 ipsa->ipsa_lpkt = attrmp;
6850 npkt = NULL;
6851 } else {
6853 * If not larval, we lost the race. NOTE: ipsa_lpkt may still
6854 * have been non-NULL in the non-larval case, because of
6855 * inbound packets arriving prior to sadb_common_add()
6856 * transferring the SA completely out of larval state, but
6857 * after lpkt was grabbed by the AH/ESP-specific add routines.
6858 * We should clear the old ipsa_lpkt in this case to make sure
6859 * that it doesn't linger on the now-MATURE IPsec SA, or get
6860 * picked up as an out-of-order packet.
6862 ipsa->ipsa_lpkt = NULL;
6864 mutex_exit(&ipsa->ipsa_lock);
6866 if (opkt != NULL) {
6867 ipsec_stack_t *ipss;
6869 ipss = ira->ira_ill->ill_ipst->ips_netstack->netstack_ipsec;
6870 opkt = ip_recv_attr_free_mblk(opkt);
6871 ip_drop_packet(opkt, B_TRUE, ira->ira_ill,
6872 DROPPER(ipss, ipds_sadb_inlarval_replace),
6873 &ipss->ipsec_sadb_dropper);
6875 return (npkt);
6879 * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
6880 * previous value.
6882 mblk_t *
6883 sadb_clear_lpkt(ipsa_t *ipsa)
6885 mblk_t *opkt;
6887 mutex_enter(&ipsa->ipsa_lock);
6888 opkt = ipsa->ipsa_lpkt;
6889 ipsa->ipsa_lpkt = NULL;
6890 mutex_exit(&ipsa->ipsa_lock);
6891 return (opkt);
6895 * Buffer a packet that's in IDLE state as set by Solaris Clustering.
6897 void
6898 sadb_buf_pkt(ipsa_t *ipsa, mblk_t *bpkt, ip_recv_attr_t *ira)
6900 netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack;
6901 ipsec_stack_t *ipss = ns->netstack_ipsec;
6902 in6_addr_t *srcaddr = (in6_addr_t *)(&ipsa->ipsa_srcaddr);
6903 in6_addr_t *dstaddr = (in6_addr_t *)(&ipsa->ipsa_dstaddr);
6904 mblk_t *mp;
6906 ASSERT(ipsa->ipsa_state == IPSA_STATE_IDLE);
6908 ip_drop_packet(bpkt, B_TRUE, ira->ira_ill,
6909 DROPPER(ipss, ipds_sadb_inidle_overflow),
6910 &ipss->ipsec_sadb_dropper);
6911 return;
6915 * Stub function that taskq_dispatch() invokes to take the mblk (in arg)
6916 * and put into STREAMS again.
6918 void
6919 sadb_clear_buf_pkt(void *ipkt)
6921 mblk_t *tmp, *buf_pkt;
6922 ip_recv_attr_t iras;
6924 buf_pkt = (mblk_t *)ipkt;
6926 while (buf_pkt != NULL) {
6927 mblk_t *data_mp;
6929 tmp = buf_pkt->b_next;
6930 buf_pkt->b_next = NULL;
6932 data_mp = buf_pkt->b_cont;
6933 buf_pkt->b_cont = NULL;
6934 if (!ip_recv_attr_from_mblk(buf_pkt, &iras)) {
6935 /* The ill or ip_stack_t disappeared on us. */
6936 ip_drop_input("ip_recv_attr_from_mblk", data_mp, NULL);
6937 freemsg(data_mp);
6938 } else {
6939 ip_input_post_ipsec(data_mp, &iras);
6941 ira_cleanup(&iras, B_TRUE);
6942 buf_pkt = tmp;
6946 * Walker callback used by sadb_alg_update() to free/create crypto
6947 * context template when a crypto software provider is removed or
6948 * added.
6951 struct sadb_update_alg_state {
6952 ipsec_algtype_t alg_type;
6953 uint8_t alg_id;
6954 boolean_t is_added;
6955 boolean_t async_auth;
6956 boolean_t async_encr;
6959 static void
6960 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
6962 struct sadb_update_alg_state *update_state =
6963 (struct sadb_update_alg_state *)cookie;
6964 crypto_ctx_template_t *ctx_tmpl = NULL;
6966 ASSERT(MUTEX_HELD(&head->isaf_lock));
6968 if (entry->ipsa_state == IPSA_STATE_LARVAL)
6969 return;
6971 mutex_enter(&entry->ipsa_lock);
6973 if ((entry->ipsa_encr_alg != SADB_EALG_NONE && entry->ipsa_encr_alg !=
6974 SADB_EALG_NULL && update_state->async_encr) ||
6975 (entry->ipsa_auth_alg != SADB_AALG_NONE &&
6976 update_state->async_auth)) {
6977 entry->ipsa_flags |= IPSA_F_ASYNC;
6978 } else {
6979 entry->ipsa_flags &= ~IPSA_F_ASYNC;
6982 switch (update_state->alg_type) {
6983 case IPSEC_ALG_AUTH:
6984 if (entry->ipsa_auth_alg == update_state->alg_id)
6985 ctx_tmpl = &entry->ipsa_authtmpl;
6986 break;
6987 case IPSEC_ALG_ENCR:
6988 if (entry->ipsa_encr_alg == update_state->alg_id)
6989 ctx_tmpl = &entry->ipsa_encrtmpl;
6990 break;
6991 default:
6992 ctx_tmpl = NULL;
6995 if (ctx_tmpl == NULL) {
6996 mutex_exit(&entry->ipsa_lock);
6997 return;
7001 * The context template of the SA may be affected by the change
7002 * of crypto provider.
7004 if (update_state->is_added) {
7005 /* create the context template if not already done */
7006 if (*ctx_tmpl == NULL) {
7007 (void) ipsec_create_ctx_tmpl(entry,
7008 update_state->alg_type);
7010 } else {
7012 * The crypto provider was removed. If the context template
7013 * exists but it is no longer valid, free it.
7015 if (*ctx_tmpl != NULL)
7016 ipsec_destroy_ctx_tmpl(entry, update_state->alg_type);
7019 mutex_exit(&entry->ipsa_lock);
7023 * Invoked by IP when an software crypto provider has been updated, or if
7024 * the crypto synchrony changes. The type and id of the corresponding
7025 * algorithm is passed as argument. The type is set to ALL in the case of
7026 * a synchrony change.
7028 * is_added is B_TRUE if the provider was added, B_FALSE if it was
7029 * removed. The function updates the SADB and free/creates the
7030 * context templates associated with SAs if needed.
7033 #define SADB_ALG_UPDATE_WALK(sadb, table) \
7034 sadb_walker((sadb).table, (sadb).sdb_hashsize, sadb_alg_update_cb, \
7035 &update_state)
7037 void
7038 sadb_alg_update(ipsec_algtype_t alg_type, uint8_t alg_id, boolean_t is_added,
7039 netstack_t *ns)
7041 struct sadb_update_alg_state update_state;
7042 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
7043 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
7044 ipsec_stack_t *ipss = ns->netstack_ipsec;
7046 update_state.alg_type = alg_type;
7047 update_state.alg_id = alg_id;
7048 update_state.is_added = is_added;
7049 update_state.async_auth = ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
7050 IPSEC_ALGS_EXEC_ASYNC;
7051 update_state.async_encr = ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
7052 IPSEC_ALGS_EXEC_ASYNC;
7054 if (alg_type == IPSEC_ALG_AUTH || alg_type == IPSEC_ALG_ALL) {
7055 /* walk the AH tables only for auth. algorithm changes */
7056 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_of);
7057 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_if);
7058 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_of);
7059 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_if);
7062 /* walk the ESP tables */
7063 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_of);
7064 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_if);
7065 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_of);
7066 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_if);
7070 * Creates a context template for the specified SA. This function
7071 * is called when an SA is created and when a context template needs
7072 * to be created due to a change of software provider.
7075 ipsec_create_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7077 ipsec_alginfo_t *alg;
7078 crypto_mechanism_t mech;
7079 crypto_key_t *key;
7080 crypto_ctx_template_t *sa_tmpl;
7081 int rv;
7082 ipsec_stack_t *ipss = sa->ipsa_netstack->netstack_ipsec;
7084 ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
7085 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7087 /* get pointers to the algorithm info, context template, and key */
7088 switch (alg_type) {
7089 case IPSEC_ALG_AUTH:
7090 key = &sa->ipsa_kcfauthkey;
7091 sa_tmpl = &sa->ipsa_authtmpl;
7092 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_auth_alg];
7093 break;
7094 case IPSEC_ALG_ENCR:
7095 key = &sa->ipsa_kcfencrkey;
7096 sa_tmpl = &sa->ipsa_encrtmpl;
7097 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_encr_alg];
7098 break;
7099 default:
7100 alg = NULL;
7103 if (alg == NULL || !ALG_VALID(alg))
7104 return (EINVAL);
7106 /* initialize the mech info structure for the framework */
7107 ASSERT(alg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
7108 mech.cm_type = alg->alg_mech_type;
7109 mech.cm_param = NULL;
7110 mech.cm_param_len = 0;
7112 /* create a new context template */
7113 rv = crypto_create_ctx_template(&mech, key, sa_tmpl, KM_NOSLEEP);
7116 * CRYPTO_MECH_NOT_SUPPORTED can be returned if only hardware
7117 * providers are available for that mechanism. In that case
7118 * we don't fail, and will generate the context template from
7119 * the framework callback when a software provider for that
7120 * mechanism registers.
7122 * The context template is assigned the special value
7123 * IPSEC_CTX_TMPL_ALLOC if the allocation failed due to a
7124 * lack of memory. No attempt will be made to use
7125 * the context template if it is set to this value.
7127 if (rv == CRYPTO_HOST_MEMORY) {
7128 *sa_tmpl = IPSEC_CTX_TMPL_ALLOC;
7129 } else if (rv != CRYPTO_SUCCESS) {
7130 *sa_tmpl = NULL;
7131 if (rv != CRYPTO_MECH_NOT_SUPPORTED)
7132 return (EINVAL);
7135 return (0);
7139 * Destroy the context template of the specified algorithm type
7140 * of the specified SA. Must be called while holding the SA lock.
7142 void
7143 ipsec_destroy_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7145 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7147 if (alg_type == IPSEC_ALG_AUTH) {
7148 if (sa->ipsa_authtmpl == IPSEC_CTX_TMPL_ALLOC)
7149 sa->ipsa_authtmpl = NULL;
7150 else if (sa->ipsa_authtmpl != NULL) {
7151 crypto_destroy_ctx_template(sa->ipsa_authtmpl);
7152 sa->ipsa_authtmpl = NULL;
7154 } else {
7155 ASSERT(alg_type == IPSEC_ALG_ENCR);
7156 if (sa->ipsa_encrtmpl == IPSEC_CTX_TMPL_ALLOC)
7157 sa->ipsa_encrtmpl = NULL;
7158 else if (sa->ipsa_encrtmpl != NULL) {
7159 crypto_destroy_ctx_template(sa->ipsa_encrtmpl);
7160 sa->ipsa_encrtmpl = NULL;
7166 * Use the kernel crypto framework to check the validity of a key received
7167 * via keysock. Returns 0 if the key is OK, -1 otherwise.
7170 ipsec_check_key(crypto_mech_type_t mech_type, sadb_key_t *sadb_key,
7171 boolean_t is_auth, int *diag)
7173 crypto_mechanism_t mech;
7174 crypto_key_t crypto_key;
7175 int crypto_rc;
7177 mech.cm_type = mech_type;
7178 mech.cm_param = NULL;
7179 mech.cm_param_len = 0;
7181 crypto_key.ck_format = CRYPTO_KEY_RAW;
7182 crypto_key.ck_data = sadb_key + 1;
7183 crypto_key.ck_length = sadb_key->sadb_key_bits;
7185 crypto_rc = crypto_key_check(&mech, &crypto_key);
7187 switch (crypto_rc) {
7188 case CRYPTO_SUCCESS:
7189 return (0);
7190 case CRYPTO_MECHANISM_INVALID:
7191 case CRYPTO_MECH_NOT_SUPPORTED:
7192 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AALG :
7193 SADB_X_DIAGNOSTIC_BAD_EALG;
7194 break;
7195 case CRYPTO_KEY_SIZE_RANGE:
7196 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AKEYBITS :
7197 SADB_X_DIAGNOSTIC_BAD_EKEYBITS;
7198 break;
7199 case CRYPTO_WEAK_KEY:
7200 *diag = is_auth ? SADB_X_DIAGNOSTIC_WEAK_AKEY :
7201 SADB_X_DIAGNOSTIC_WEAK_EKEY;
7202 break;
7205 return (-1);
7209 * If this is an outgoing SA then add some fuzz to the
7210 * SOFT EXPIRE time. The reason for this is to stop
7211 * peers trying to renegotiate SOFT expiring SA's at
7212 * the same time. The amount of fuzz needs to be at
7213 * least 8 seconds which is the typical interval
7214 * sadb_ager(), although this is only a guide as it
7215 * selftunes.
7217 static void
7218 lifetime_fuzz(ipsa_t *assoc)
7220 uint8_t rnd;
7222 if (assoc->ipsa_softaddlt == 0)
7223 return;
7225 (void) random_get_pseudo_bytes(&rnd, sizeof (rnd));
7226 rnd = (rnd & 0xF) + 8;
7227 assoc->ipsa_softexpiretime -= rnd;
7228 assoc->ipsa_softaddlt -= rnd;
7231 static void
7232 destroy_ipsa_pair(ipsap_t *ipsapp)
7235 * Because of the multi-line macro nature of IPSA_REFRELE, keep
7236 * them in { }.
7238 if (ipsapp->ipsap_sa_ptr != NULL) {
7239 IPSA_REFRELE(ipsapp->ipsap_sa_ptr);
7241 if (ipsapp->ipsap_psa_ptr != NULL) {
7242 IPSA_REFRELE(ipsapp->ipsap_psa_ptr);
7244 init_ipsa_pair(ipsapp);
7247 static void
7248 init_ipsa_pair(ipsap_t *ipsapp)
7250 ipsapp->ipsap_bucket = NULL;
7251 ipsapp->ipsap_sa_ptr = NULL;
7252 ipsapp->ipsap_pbucket = NULL;
7253 ipsapp->ipsap_psa_ptr = NULL;
7257 * The sadb_ager() function walks through the hash tables of SA's and ages
7258 * them, if the SA expires as a result, its marked as DEAD and will be reaped
7259 * the next time sadb_ager() runs. SA's which are paired or have a peer (same
7260 * SA appears in both the inbound and outbound tables because its not possible
7261 * to determine its direction) are placed on a list when they expire. This is
7262 * to ensure that pair/peer SA's are reaped at the same time, even if they
7263 * expire at different times.
7265 * This function is called twice by sadb_ager(), one after processing the
7266 * inbound table, then again after processing the outbound table.
7268 void
7269 age_pair_peer_list(templist_t *haspeerlist, sadb_t *sp, boolean_t outbound)
7271 templist_t *listptr;
7272 int outhash;
7273 isaf_t *bucket;
7274 boolean_t haspeer;
7275 ipsa_t *peer_assoc, *dying;
7277 * Haspeer cases will contain both IPv4 and IPv6. This code
7278 * is address independent.
7280 while (haspeerlist != NULL) {
7281 /* "dying" contains the SA that has a peer. */
7282 dying = haspeerlist->ipsa;
7283 haspeer = (dying->ipsa_haspeer);
7284 listptr = haspeerlist;
7285 haspeerlist = listptr->next;
7286 kmem_free(listptr, sizeof (*listptr));
7288 * Pick peer bucket based on addrfam.
7290 if (outbound) {
7291 if (haspeer)
7292 bucket = INBOUND_BUCKET(sp, dying->ipsa_spi);
7293 else
7294 bucket = INBOUND_BUCKET(sp,
7295 dying->ipsa_otherspi);
7296 } else { /* inbound */
7297 if (haspeer) {
7298 if (dying->ipsa_addrfam == AF_INET6) {
7299 outhash = OUTBOUND_HASH_V6(sp,
7300 *((in6_addr_t *)&dying->
7301 ipsa_dstaddr));
7302 } else {
7303 outhash = OUTBOUND_HASH_V4(sp,
7304 *((ipaddr_t *)&dying->
7305 ipsa_dstaddr));
7307 } else if (dying->ipsa_addrfam == AF_INET6) {
7308 outhash = OUTBOUND_HASH_V6(sp,
7309 *((in6_addr_t *)&dying->
7310 ipsa_srcaddr));
7311 } else {
7312 outhash = OUTBOUND_HASH_V4(sp,
7313 *((ipaddr_t *)&dying->
7314 ipsa_srcaddr));
7316 bucket = &(sp->sdb_of[outhash]);
7319 mutex_enter(&bucket->isaf_lock);
7321 * "haspeer" SA's have the same src/dst address ordering,
7322 * "paired" SA's have the src/dst addresses reversed.
7324 if (haspeer) {
7325 peer_assoc = ipsec_getassocbyspi(bucket,
7326 dying->ipsa_spi, dying->ipsa_srcaddr,
7327 dying->ipsa_dstaddr, dying->ipsa_addrfam);
7328 } else {
7329 peer_assoc = ipsec_getassocbyspi(bucket,
7330 dying->ipsa_otherspi, dying->ipsa_dstaddr,
7331 dying->ipsa_srcaddr, dying->ipsa_addrfam);
7334 mutex_exit(&bucket->isaf_lock);
7335 if (peer_assoc != NULL) {
7336 mutex_enter(&peer_assoc->ipsa_lock);
7337 mutex_enter(&dying->ipsa_lock);
7338 if (!haspeer) {
7340 * Only SA's which have a "peer" or are
7341 * "paired" end up on this list, so this
7342 * must be a "paired" SA, update the flags
7343 * to break the pair.
7345 peer_assoc->ipsa_otherspi = 0;
7346 peer_assoc->ipsa_flags &= ~IPSA_F_PAIRED;
7347 dying->ipsa_otherspi = 0;
7348 dying->ipsa_flags &= ~IPSA_F_PAIRED;
7350 if (haspeer || outbound) {
7352 * Update the state of the "inbound" SA when
7353 * the "outbound" SA has expired. Don't update
7354 * the "outbound" SA when the "inbound" SA
7355 * SA expires because setting the hard_addtime
7356 * below will cause this to happen.
7358 peer_assoc->ipsa_state = dying->ipsa_state;
7360 if (dying->ipsa_state == IPSA_STATE_DEAD)
7361 peer_assoc->ipsa_hardexpiretime = 1;
7363 mutex_exit(&dying->ipsa_lock);
7364 mutex_exit(&peer_assoc->ipsa_lock);
7365 IPSA_REFRELE(peer_assoc);
7367 IPSA_REFRELE(dying);
7372 * Ensure that the IV used for CCM mode never repeats. The IV should
7373 * only be updated by this function. Also check to see if the IV
7374 * is about to wrap and generate a SOFT Expire. This function is only
7375 * called for outgoing packets, the IV for incomming packets is taken
7376 * from the wire. If the outgoing SA needs to be expired, update
7377 * the matching incomming SA.
7379 boolean_t
7380 update_iv(uint8_t *iv_ptr, queue_t *pfkey_q, ipsa_t *assoc,
7381 ipsecesp_stack_t *espstack)
7383 boolean_t rc = B_TRUE;
7384 isaf_t *inbound_bucket;
7385 sadb_t *sp;
7386 ipsa_t *pair_sa = NULL;
7387 int sa_new_state = 0;
7389 /* For non counter modes, the IV is random data. */
7390 if (!(assoc->ipsa_flags & IPSA_F_COUNTERMODE)) {
7391 (void) random_get_pseudo_bytes(iv_ptr, assoc->ipsa_iv_len);
7392 return (rc);
7395 mutex_enter(&assoc->ipsa_lock);
7397 (*assoc->ipsa_iv)++;
7399 if (*assoc->ipsa_iv == assoc->ipsa_iv_hardexpire) {
7400 sa_new_state = IPSA_STATE_DEAD;
7401 rc = B_FALSE;
7402 } else if (*assoc->ipsa_iv == assoc->ipsa_iv_softexpire) {
7403 if (assoc->ipsa_state != IPSA_STATE_DYING) {
7405 * This SA may have already been expired when its
7406 * PAIR_SA expired.
7408 sa_new_state = IPSA_STATE_DYING;
7411 if (sa_new_state) {
7413 * If there is a state change, we need to update this SA
7414 * and its "pair", we can find the bucket for the "pair" SA
7415 * while holding the ipsa_t mutex, but we won't actually
7416 * update anything untill the ipsa_t mutex has been released
7417 * for _this_ SA.
7419 assoc->ipsa_state = sa_new_state;
7420 if (assoc->ipsa_addrfam == AF_INET6) {
7421 sp = &espstack->esp_sadb.s_v6;
7422 } else {
7423 sp = &espstack->esp_sadb.s_v4;
7425 inbound_bucket = INBOUND_BUCKET(sp, assoc->ipsa_otherspi);
7426 sadb_expire_assoc(pfkey_q, assoc);
7428 if (rc == B_TRUE)
7429 bcopy(assoc->ipsa_iv, iv_ptr, assoc->ipsa_iv_len);
7431 mutex_exit(&assoc->ipsa_lock);
7433 if (sa_new_state) {
7434 /* Find the inbound SA, need to lock hash bucket. */
7435 mutex_enter(&inbound_bucket->isaf_lock);
7436 pair_sa = ipsec_getassocbyspi(inbound_bucket,
7437 assoc->ipsa_otherspi, assoc->ipsa_dstaddr,
7438 assoc->ipsa_srcaddr, assoc->ipsa_addrfam);
7439 mutex_exit(&inbound_bucket->isaf_lock);
7440 if (pair_sa != NULL) {
7441 mutex_enter(&pair_sa->ipsa_lock);
7442 pair_sa->ipsa_state = sa_new_state;
7443 mutex_exit(&pair_sa->ipsa_lock);
7444 IPSA_REFRELE(pair_sa);
7448 return (rc);
7451 void
7452 ccm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7453 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7455 uchar_t *nonce;
7456 crypto_mechanism_t *combined_mech;
7457 CK_AES_CCM_PARAMS *params;
7459 combined_mech = (crypto_mechanism_t *)cm_mech;
7460 params = (CK_AES_CCM_PARAMS *)(combined_mech + 1);
7461 nonce = (uchar_t *)(params + 1);
7462 params->ulMACSize = assoc->ipsa_mac_len;
7463 params->ulNonceSize = assoc->ipsa_nonce_len;
7464 params->ulAuthDataSize = sizeof (esph_t);
7465 params->ulDataSize = data_len;
7466 params->nonce = nonce;
7467 params->authData = esph;
7469 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7470 cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_CCM_PARAMS);
7471 cm_mech->combined_mech.cm_param = (caddr_t)params;
7472 /* See gcm_params_init() for comments. */
7473 bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
7474 nonce += assoc->ipsa_saltlen;
7475 bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
7476 crypto_data->cd_miscdata = NULL;
7479 /* ARGSUSED */
7480 void
7481 cbc_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7482 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7484 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7485 cm_mech->combined_mech.cm_param_len = 0;
7486 cm_mech->combined_mech.cm_param = NULL;
7487 crypto_data->cd_miscdata = (char *)iv_ptr;
7490 /* ARGSUSED */
7491 void
7492 gcm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7493 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7495 uchar_t *nonce;
7496 crypto_mechanism_t *combined_mech;
7497 CK_AES_GCM_PARAMS *params;
7499 combined_mech = (crypto_mechanism_t *)cm_mech;
7500 params = (CK_AES_GCM_PARAMS *)(combined_mech + 1);
7501 nonce = (uchar_t *)(params + 1);
7503 params->pIv = nonce;
7504 params->ulIvLen = assoc->ipsa_nonce_len;
7505 params->ulIvBits = SADB_8TO1(assoc->ipsa_nonce_len);
7506 params->pAAD = esph;
7507 params->ulAADLen = sizeof (esph_t);
7508 params->ulTagBits = SADB_8TO1(assoc->ipsa_mac_len);
7510 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7511 cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
7512 cm_mech->combined_mech.cm_param = (caddr_t)params;
7514 * Create the nonce, which is made up of the salt and the IV.
7515 * Copy the salt from the SA and the IV from the packet.
7516 * For inbound packets we copy the IV from the packet because it
7517 * was set by the sending system, for outbound packets we copy the IV
7518 * from the packet because the IV in the SA may be changed by another
7519 * thread, the IV in the packet was created while holding a mutex.
7521 bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
7522 nonce += assoc->ipsa_saltlen;
7523 bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
7524 crypto_data->cd_miscdata = NULL;