1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
26 */
27
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>
70 #include <sys/tsol/tnet.h>
71
72 /*
73 * This source file contains Security Association Database (SADB) common
74 * routines. They are linked in with the AH module. Since AH has no chance
75 * of falling under export control, it was safe to link it in there.
76 */
77
78 static mblk_t *sadb_extended_acquire(ipsec_selector_t *, ipsec_policy_t *,
79 ipsec_action_t *, boolean_t, uint32_t, uint32_t, sadb_sens_t *,
80 netstack_t *);
81 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *);
82 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t,
83 netstack_t *);
84 static void sadb_destroy(sadb_t *, netstack_t *);
85 static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *);
86 static ts_label_t *sadb_label_from_sens(sadb_sens_t *, uint64_t *);
87 static sadb_sens_t *sadb_make_sens_ext(ts_label_t *tsl, int *len);
88
89 static time_t sadb_add_time(time_t, uint64_t);
90 static void lifetime_fuzz(ipsa_t *);
91 static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t);
92 static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *);
93 static void init_ipsa_pair(ipsap_t *);
94 static void destroy_ipsa_pair(ipsap_t *);
95 static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *);
96 static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset);
97
98 /*
99 * ipsacq_maxpackets is defined here to make it tunable
100 * from /etc/system.
101 */
102 extern uint64_t ipsacq_maxpackets;
103
104 #define SET_EXPIRE(sa, delta, exp) { \
105 if (((sa)->ipsa_ ## delta) != 0) { \
106 (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime, \
107 (sa)->ipsa_ ## delta); \
108 } \
109 }
110
111 #define UPDATE_EXPIRE(sa, delta, exp) { \
112 if (((sa)->ipsa_ ## delta) != 0) { \
113 time_t tmp = sadb_add_time((sa)->ipsa_usetime, \
114 (sa)->ipsa_ ## delta); \
115 if (((sa)->ipsa_ ## exp) == 0) \
116 (sa)->ipsa_ ## exp = tmp; \
117 else \
118 (sa)->ipsa_ ## exp = \
119 MIN((sa)->ipsa_ ## exp, tmp); \
120 } \
121 }
122
123
124 /* wrap the macro so we can pass it as a function pointer */
125 void
126 sadb_sa_refrele(void *target)
127 {
128 IPSA_REFRELE(((ipsa_t *)target));
129 }
130
131 /*
132 * We presume that sizeof (long) == sizeof (time_t) and that time_t is
133 * a signed type.
134 */
135 #define TIME_MAX LONG_MAX
136
137 /*
138 * PF_KEY gives us lifetimes in uint64_t seconds. We presume that
139 * time_t is defined to be a signed type with the same range as
140 * "long". On ILP32 systems, we thus run the risk of wrapping around
141 * at end of time, as well as "overwrapping" the clock back around
142 * into a seemingly valid but incorrect future date earlier than the
143 * desired expiration.
144 *
145 * In order to avoid odd behavior (either negative lifetimes or loss
146 * of high order bits) when someone asks for bizarrely long SA
147 * lifetimes, we do a saturating add for expire times.
148 *
149 * We presume that ILP32 systems will be past end of support life when
150 * the 32-bit time_t overflows (a dangerous assumption, mind you..).
151 *
152 * On LP64, 2^64 seconds are about 5.8e11 years, at which point we
153 * will hopefully have figured out clever ways to avoid the use of
154 * fixed-sized integers in computation.
155 */
156 static time_t
157 sadb_add_time(time_t base, uint64_t delta)
158 {
159 time_t sum;
160
161 /*
162 * Clip delta to the maximum possible time_t value to
163 * prevent "overwrapping" back into a shorter-than-desired
164 * future time.
165 */
166 if (delta > TIME_MAX)
167 delta = TIME_MAX;
168 /*
169 * This sum may still overflow.
170 */
171 sum = base + delta;
172
173 /*
174 * .. so if the result is less than the base, we overflowed.
175 */
176 if (sum < base)
177 sum = TIME_MAX;
178
179 return (sum);
180 }
181
182 /*
183 * Callers of this function have already created a working security
184 * association, and have found the appropriate table & hash chain. All this
185 * function does is check duplicates, and insert the SA. The caller needs to
186 * hold the hash bucket lock and increment the refcnt before insertion.
187 *
188 * Return 0 if success, EEXIST if collision.
189 */
190 #define SA_UNIQUE_MATCH(sa1, sa2) \
191 (((sa1)->ipsa_unique_id & (sa1)->ipsa_unique_mask) == \
192 ((sa2)->ipsa_unique_id & (sa2)->ipsa_unique_mask))
193
194 int
195 sadb_insertassoc(ipsa_t *ipsa, isaf_t *bucket)
196 {
197 ipsa_t **ptpn = NULL;
198 ipsa_t *walker;
199 boolean_t unspecsrc;
200
201 ASSERT(MUTEX_HELD(&bucket->isaf_lock));
202
203 unspecsrc = IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_srcaddr, ipsa->ipsa_addrfam);
204
205 walker = bucket->isaf_ipsa;
206 ASSERT(walker == NULL || ipsa->ipsa_addrfam == walker->ipsa_addrfam);
207
208 /*
209 * Find insertion point (pointed to with **ptpn). Insert at the head
210 * of the list unless there's an unspecified source address, then
211 * insert it after the last SA with a specified source address.
212 *
213 * BTW, you'll have to walk the whole chain, matching on {DST, SPI}
214 * checking for collisions.
215 */
216
217 while (walker != NULL) {
218 if (IPSA_ARE_ADDR_EQUAL(walker->ipsa_dstaddr,
219 ipsa->ipsa_dstaddr, ipsa->ipsa_addrfam)) {
220 if (walker->ipsa_spi == ipsa->ipsa_spi)
221 return (EEXIST);
222
223 mutex_enter(&walker->ipsa_lock);
224 if (ipsa->ipsa_state == IPSA_STATE_MATURE &&
225 (walker->ipsa_flags & IPSA_F_USED) &&
226 SA_UNIQUE_MATCH(walker, ipsa)) {
227 walker->ipsa_flags |= IPSA_F_CINVALID;
228 }
229 mutex_exit(&walker->ipsa_lock);
230 }
231
232 if (ptpn == NULL && unspecsrc) {
233 if (IPSA_IS_ADDR_UNSPEC(walker->ipsa_srcaddr,
234 walker->ipsa_addrfam))
235 ptpn = walker->ipsa_ptpn;
236 else if (walker->ipsa_next == NULL)
237 ptpn = &walker->ipsa_next;
238 }
239
240 walker = walker->ipsa_next;
241 }
242
243 if (ptpn == NULL)
244 ptpn = &bucket->isaf_ipsa;
245 ipsa->ipsa_next = *ptpn;
246 ipsa->ipsa_ptpn = ptpn;
247 if (ipsa->ipsa_next != NULL)
248 ipsa->ipsa_next->ipsa_ptpn = &ipsa->ipsa_next;
249 *ptpn = ipsa;
250 ipsa->ipsa_linklock = &bucket->isaf_lock;
251
252 return (0);
253 }
254 #undef SA_UNIQUE_MATCH
255
256 /*
257 * Free a security association. Its reference count is 0, which means
258 * I must free it. The SA must be unlocked and must not be linked into
259 * any fanout list.
260 */
261 static void
262 sadb_freeassoc(ipsa_t *ipsa)
263 {
264 ipsec_stack_t *ipss = ipsa->ipsa_netstack->netstack_ipsec;
265 mblk_t *asyncmp, *mp;
266
267 ASSERT(ipss != NULL);
268 ASSERT(MUTEX_NOT_HELD(&ipsa->ipsa_lock));
269 ASSERT(ipsa->ipsa_refcnt == 0);
270 ASSERT(ipsa->ipsa_next == NULL);
271 ASSERT(ipsa->ipsa_ptpn == NULL);
272
273
274 asyncmp = sadb_clear_lpkt(ipsa);
275 if (asyncmp != NULL) {
276 mp = ip_recv_attr_free_mblk(asyncmp);
277 ip_drop_packet(mp, B_TRUE, NULL,
278 DROPPER(ipss, ipds_sadb_inlarval_timeout),
279 &ipss->ipsec_sadb_dropper);
280 }
281 mutex_enter(&ipsa->ipsa_lock);
282
283 if (ipsa->ipsa_tsl != NULL) {
284 label_rele(ipsa->ipsa_tsl);
285 ipsa->ipsa_tsl = NULL;
286 }
287
288 if (ipsa->ipsa_otsl != NULL) {
289 label_rele(ipsa->ipsa_otsl);
290 ipsa->ipsa_otsl = NULL;
291 }
292
293 ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_AUTH);
294 ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_ENCR);
295 mutex_exit(&ipsa->ipsa_lock);
296
297 /* bzero() these fields for paranoia's sake. */
298 if (ipsa->ipsa_authkey != NULL) {
299 bzero(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
300 kmem_free(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
301 }
302 if (ipsa->ipsa_encrkey != NULL) {
303 bzero(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
304 kmem_free(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
305 }
306 if (ipsa->ipsa_nonce_buf != NULL) {
307 bzero(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
308 kmem_free(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
309 }
310 if (ipsa->ipsa_src_cid != NULL) {
311 IPSID_REFRELE(ipsa->ipsa_src_cid);
312 }
313 if (ipsa->ipsa_dst_cid != NULL) {
314 IPSID_REFRELE(ipsa->ipsa_dst_cid);
315 }
316 if (ipsa->ipsa_emech.cm_param != NULL)
317 kmem_free(ipsa->ipsa_emech.cm_param,
318 ipsa->ipsa_emech.cm_param_len);
319
320 mutex_destroy(&ipsa->ipsa_lock);
321 kmem_free(ipsa, sizeof (*ipsa));
322 }
323
324 /*
325 * Unlink a security association from a hash bucket. Assume the hash bucket
326 * lock is held, but the association's lock is not.
327 *
328 * Note that we do not bump the bucket's generation number here because
329 * we might not be making a visible change to the set of visible SA's.
330 * All callers MUST bump the bucket's generation number before they unlock
331 * the bucket if they use sadb_unlinkassoc to permanetly remove an SA which
332 * was present in the bucket at the time it was locked.
333 */
334 void
335 sadb_unlinkassoc(ipsa_t *ipsa)
336 {
337 ASSERT(ipsa->ipsa_linklock != NULL);
338 ASSERT(MUTEX_HELD(ipsa->ipsa_linklock));
339
340 /* These fields are protected by the link lock. */
341 *(ipsa->ipsa_ptpn) = ipsa->ipsa_next;
342 if (ipsa->ipsa_next != NULL) {
343 ipsa->ipsa_next->ipsa_ptpn = ipsa->ipsa_ptpn;
344 ipsa->ipsa_next = NULL;
345 }
346
347 ipsa->ipsa_ptpn = NULL;
348
349 /* This may destroy the SA. */
350 IPSA_REFRELE(ipsa);
351 }
352
353 /*
354 * Create a larval security association with the specified SPI. All other
355 * fields are zeroed.
356 */
357 static ipsa_t *
358 sadb_makelarvalassoc(uint32_t spi, uint32_t *src, uint32_t *dst, int addrfam,
359 netstack_t *ns)
360 {
361 ipsa_t *newbie;
362
363 /*
364 * Allocate...
365 */
366
367 newbie = (ipsa_t *)kmem_zalloc(sizeof (ipsa_t), KM_NOSLEEP);
368 if (newbie == NULL) {
369 /* Can't make new larval SA. */
370 return (NULL);
371 }
372
373 /* Assigned requested SPI, assume caller does SPI allocation magic. */
374 newbie->ipsa_spi = spi;
375 newbie->ipsa_netstack = ns; /* No netstack_hold */
376
377 /*
378 * Copy addresses...
379 */
380
381 IPSA_COPY_ADDR(newbie->ipsa_srcaddr, src, addrfam);
382 IPSA_COPY_ADDR(newbie->ipsa_dstaddr, dst, addrfam);
383
384 newbie->ipsa_addrfam = addrfam;
385
386 /*
387 * Set common initialization values, including refcnt.
388 */
389 mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
390 newbie->ipsa_state = IPSA_STATE_LARVAL;
391 newbie->ipsa_refcnt = 1;
392 newbie->ipsa_freefunc = sadb_freeassoc;
393
394 /*
395 * There aren't a lot of other common initialization values, as
396 * they are copied in from the PF_KEY message.
397 */
398
399 return (newbie);
400 }
401
402 /*
403 * Call me to initialize a security association fanout.
404 */
405 static int
406 sadb_init_fanout(isaf_t **tablep, uint_t size, int kmflag)
407 {
408 isaf_t *table;
409 int i;
410
411 table = (isaf_t *)kmem_alloc(size * sizeof (*table), kmflag);
412 *tablep = table;
413
414 if (table == NULL)
415 return (ENOMEM);
416
417 for (i = 0; i < size; i++) {
418 mutex_init(&(table[i].isaf_lock), NULL, MUTEX_DEFAULT, NULL);
419 table[i].isaf_ipsa = NULL;
420 table[i].isaf_gen = 0;
421 }
422
423 return (0);
424 }
425
426 /*
427 * Call me to initialize an acquire fanout
428 */
429 static int
430 sadb_init_acfanout(iacqf_t **tablep, uint_t size, int kmflag)
431 {
432 iacqf_t *table;
433 int i;
434
435 table = (iacqf_t *)kmem_alloc(size * sizeof (*table), kmflag);
436 *tablep = table;
437
438 if (table == NULL)
439 return (ENOMEM);
440
441 for (i = 0; i < size; i++) {
442 mutex_init(&(table[i].iacqf_lock), NULL, MUTEX_DEFAULT, NULL);
443 table[i].iacqf_ipsacq = NULL;
444 }
445
446 return (0);
447 }
448
449 /*
450 * Attempt to initialize an SADB instance. On failure, return ENOMEM;
451 * caller must clean up partial allocations.
452 */
453 static int
454 sadb_init_trial(sadb_t *sp, uint_t size, int kmflag)
455 {
456 ASSERT(sp->sdb_of == NULL);
457 ASSERT(sp->sdb_if == NULL);
458 ASSERT(sp->sdb_acq == NULL);
459
460 sp->sdb_hashsize = size;
461 if (sadb_init_fanout(&sp->sdb_of, size, kmflag) != 0)
462 return (ENOMEM);
463 if (sadb_init_fanout(&sp->sdb_if, size, kmflag) != 0)
464 return (ENOMEM);
465 if (sadb_init_acfanout(&sp->sdb_acq, size, kmflag) != 0)
466 return (ENOMEM);
467
468 return (0);
469 }
470
471 /*
472 * Call me to initialize an SADB instance; fall back to default size on failure.
473 */
474 static void
475 sadb_init(const char *name, sadb_t *sp, uint_t size, uint_t ver,
476 netstack_t *ns)
477 {
478 ASSERT(sp->sdb_of == NULL);
479 ASSERT(sp->sdb_if == NULL);
480 ASSERT(sp->sdb_acq == NULL);
481
482 if (size < IPSEC_DEFAULT_HASH_SIZE)
483 size = IPSEC_DEFAULT_HASH_SIZE;
484
485 if (sadb_init_trial(sp, size, KM_NOSLEEP) != 0) {
486
487 cmn_err(CE_WARN,
488 "Unable to allocate %u entry IPv%u %s SADB hash table",
489 size, ver, name);
490
491 sadb_destroy(sp, ns);
492 size = IPSEC_DEFAULT_HASH_SIZE;
493 cmn_err(CE_WARN, "Falling back to %d entries", size);
494 (void) sadb_init_trial(sp, size, KM_SLEEP);
495 }
496 }
497
498
499 /*
500 * Initialize an SADB-pair.
501 */
502 void
503 sadbp_init(const char *name, sadbp_t *sp, int type, int size, netstack_t *ns)
504 {
505 sadb_init(name, &sp->s_v4, size, 4, ns);
506 sadb_init(name, &sp->s_v6, size, 6, ns);
507
508 sp->s_satype = type;
509
510 ASSERT((type == SADB_SATYPE_AH) || (type == SADB_SATYPE_ESP));
511 if (type == SADB_SATYPE_AH) {
512 ipsec_stack_t *ipss = ns->netstack_ipsec;
513
514 ip_drop_register(&ipss->ipsec_sadb_dropper, "IPsec SADB");
515 sp->s_addflags = AH_ADD_SETTABLE_FLAGS;
516 sp->s_updateflags = AH_UPDATE_SETTABLE_FLAGS;
517 } else {
518 sp->s_addflags = ESP_ADD_SETTABLE_FLAGS;
519 sp->s_updateflags = ESP_UPDATE_SETTABLE_FLAGS;
520 }
521 }
522
523 /*
524 * Deliver a single SADB_DUMP message representing a single SA. This is
525 * called many times by sadb_dump().
526 *
527 * If the return value of this is ENOBUFS (not the same as ENOMEM), then
528 * the caller should take that as a hint that dupb() on the "original answer"
529 * failed, and that perhaps the caller should try again with a copyb()ed
530 * "original answer".
531 */
532 static int
533 sadb_dump_deliver(queue_t *pfkey_q, mblk_t *original_answer, ipsa_t *ipsa,
534 sadb_msg_t *samsg)
535 {
536 mblk_t *answer;
537
538 answer = dupb(original_answer);
539 if (answer == NULL)
540 return (ENOBUFS);
541 answer->b_cont = sadb_sa2msg(ipsa, samsg);
542 if (answer->b_cont == NULL) {
543 freeb(answer);
544 return (ENOMEM);
545 }
546
547 /* Just do a putnext, and let keysock deal with flow control. */
548 putnext(pfkey_q, answer);
549 return (0);
550 }
551
552 /*
553 * Common function to allocate and prepare a keysock_out_t M_CTL message.
554 */
555 mblk_t *
556 sadb_keysock_out(minor_t serial)
557 {
558 mblk_t *mp;
559 keysock_out_t *kso;
560
561 mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
562 if (mp != NULL) {
563 mp->b_datap->db_type = M_CTL;
564 mp->b_wptr += sizeof (ipsec_info_t);
565 kso = (keysock_out_t *)mp->b_rptr;
566 kso->ks_out_type = KEYSOCK_OUT;
567 kso->ks_out_len = sizeof (*kso);
568 kso->ks_out_serial = serial;
569 }
570
571 return (mp);
572 }
573
574 /*
575 * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
576 * to keysock.
577 */
578 static int
579 sadb_dump_fanout(queue_t *pfkey_q, mblk_t *mp, minor_t serial, isaf_t *fanout,
580 int num_entries, boolean_t do_peers, time_t active_time)
581 {
582 int i, error = 0;
583 mblk_t *original_answer;
584 ipsa_t *walker;
585 sadb_msg_t *samsg;
586 time_t current;
587
588 /*
589 * For each IPSA hash bucket do:
590 * - Hold the mutex
591 * - Walk each entry, doing an sadb_dump_deliver() on it.
592 */
593 ASSERT(mp->b_cont != NULL);
594 samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
595
596 original_answer = sadb_keysock_out(serial);
597 if (original_answer == NULL)
598 return (ENOMEM);
599
600 current = gethrestime_sec();
601 for (i = 0; i < num_entries; i++) {
602 mutex_enter(&fanout[i].isaf_lock);
603 for (walker = fanout[i].isaf_ipsa; walker != NULL;
604 walker = walker->ipsa_next) {
605 if (!do_peers && walker->ipsa_haspeer)
606 continue;
607 if ((active_time != 0) &&
608 ((current - walker->ipsa_lastuse) > active_time))
609 continue;
610 error = sadb_dump_deliver(pfkey_q, original_answer,
611 walker, samsg);
612 if (error == ENOBUFS) {
613 mblk_t *new_original_answer;
614
615 /* Ran out of dupb's. Try a copyb. */
616 new_original_answer = copyb(original_answer);
617 if (new_original_answer == NULL) {
618 error = ENOMEM;
619 } else {
620 freeb(original_answer);
621 original_answer = new_original_answer;
622 error = sadb_dump_deliver(pfkey_q,
623 original_answer, walker, samsg);
624 }
625 }
626 if (error != 0)
627 break; /* out of for loop. */
628 }
629 mutex_exit(&fanout[i].isaf_lock);
630 if (error != 0)
631 break; /* out of for loop. */
632 }
633
634 freeb(original_answer);
635 return (error);
636 }
637
638 /*
639 * Dump an entire SADB; outbound first, then inbound.
640 */
641
642 int
643 sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp)
644 {
645 int error;
646 time_t active_time = 0;
647 sadb_x_edump_t *edump =
648 (sadb_x_edump_t *)ksi->ks_in_extv[SADB_X_EXT_EDUMP];
649
650 if (edump != NULL) {
651 active_time = edump->sadb_x_edump_timeout;
652 }
653
654 /* Dump outbound */
655 error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of,
656 sp->sdb_hashsize, B_TRUE, active_time);
657 if (error)
658 return (error);
659
660 /* Dump inbound */
661 return sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if,
662 sp->sdb_hashsize, B_FALSE, active_time);
663 }
664
665 /*
666 * Generic sadb table walker.
667 *
668 * Call "walkfn" for each SA in each bucket in "table"; pass the
669 * bucket, the entry and "cookie" to the callback function.
670 * Take care to ensure that walkfn can delete the SA without screwing
671 * up our traverse.
672 *
673 * The bucket is locked for the duration of the callback, both so that the
674 * callback can just call sadb_unlinkassoc() when it wants to delete something,
675 * and so that no new entries are added while we're walking the list.
676 */
677 static void
678 sadb_walker(isaf_t *table, uint_t numentries,
679 void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
680 void *cookie)
681 {
682 int i;
683 for (i = 0; i < numentries; i++) {
684 ipsa_t *entry, *next;
685
686 mutex_enter(&table[i].isaf_lock);
687
688 for (entry = table[i].isaf_ipsa; entry != NULL;
689 entry = next) {
690 next = entry->ipsa_next;
691 (*walkfn)(&table[i], entry, cookie);
692 }
693 mutex_exit(&table[i].isaf_lock);
694 }
695 }
696
697 /*
698 * Call me to free up a security association fanout. Use the forever
699 * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
700 * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
701 * when a module is unloaded).
702 */
703 static void
704 sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever,
705 boolean_t inbound)
706 {
707 int i;
708 isaf_t *table = *tablep;
709 ipsa_t *sa;
710
711 if (table == NULL)
712 return;
713
714 for (i = 0; i < numentries; i++) {
715 mutex_enter(&table[i].isaf_lock);
716 while ((sa = table[i].isaf_ipsa) != NULL) {
717 sadb_unlinkassoc(sa);
718 }
719 table[i].isaf_gen++;
720 mutex_exit(&table[i].isaf_lock);
721 if (forever)
722 mutex_destroy(&(table[i].isaf_lock));
723 }
724
725 if (forever) {
726 *tablep = NULL;
727 kmem_free(table, numentries * sizeof (*table));
728 }
729 }
730
731 /*
732 * Entry points to sadb_destroyer().
733 */
734 static void
735 sadb_flush(sadb_t *sp, netstack_t *ns)
736 {
737 /*
738 * Flush out each bucket, one at a time. Were it not for keysock's
739 * enforcement, there would be a subtlety where I could add on the
740 * heels of a flush. With keysock's enforcement, however, this
741 * makes ESP's job easy.
742 */
743 sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE, B_FALSE);
744 sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE, B_TRUE);
745
746 /* For each acquire, destroy it; leave the bucket mutex alone. */
747 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns);
748 }
749
750 static void
751 sadb_destroy(sadb_t *sp, netstack_t *ns)
752 {
753 sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE, B_FALSE);
754 sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE, B_TRUE);
755
756 /* For each acquire, destroy it, including the bucket mutex. */
757 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns);
758
759 ASSERT(sp->sdb_of == NULL);
760 ASSERT(sp->sdb_if == NULL);
761 ASSERT(sp->sdb_acq == NULL);
762 }
763
764 void
765 sadbp_flush(sadbp_t *spp, netstack_t *ns)
766 {
767 sadb_flush(&spp->s_v4, ns);
768 sadb_flush(&spp->s_v6, ns);
769 }
770
771 void
772 sadbp_destroy(sadbp_t *spp, netstack_t *ns)
773 {
774 sadb_destroy(&spp->s_v4, ns);
775 sadb_destroy(&spp->s_v6, ns);
776
777 if (spp->s_satype == SADB_SATYPE_AH) {
778 ipsec_stack_t *ipss = ns->netstack_ipsec;
779
780 ip_drop_unregister(&ipss->ipsec_sadb_dropper);
781 }
782 }
783
784
785 /*
786 * Check hard vs. soft lifetimes. If there's a reality mismatch (e.g.
787 * soft lifetimes > hard lifetimes) return an appropriate diagnostic for
788 * EINVAL.
789 */
790 int
791 sadb_hardsoftchk(sadb_lifetime_t *hard, sadb_lifetime_t *soft,
792 sadb_lifetime_t *idle)
793 {
794 if (hard == NULL || soft == NULL)
795 return (0);
796
797 if (hard->sadb_lifetime_allocations != 0 &&
798 soft->sadb_lifetime_allocations != 0 &&
799 hard->sadb_lifetime_allocations < soft->sadb_lifetime_allocations)
800 return (SADB_X_DIAGNOSTIC_ALLOC_HSERR);
801
802 if (hard->sadb_lifetime_bytes != 0 &&
803 soft->sadb_lifetime_bytes != 0 &&
804 hard->sadb_lifetime_bytes < soft->sadb_lifetime_bytes)
805 return (SADB_X_DIAGNOSTIC_BYTES_HSERR);
806
807 if (hard->sadb_lifetime_addtime != 0 &&
808 soft->sadb_lifetime_addtime != 0 &&
809 hard->sadb_lifetime_addtime < soft->sadb_lifetime_addtime)
810 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
811
812 if (hard->sadb_lifetime_usetime != 0 &&
813 soft->sadb_lifetime_usetime != 0 &&
814 hard->sadb_lifetime_usetime < soft->sadb_lifetime_usetime)
815 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
816
817 if (idle != NULL) {
818 if (hard->sadb_lifetime_addtime != 0 &&
819 idle->sadb_lifetime_addtime != 0 &&
820 hard->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
821 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
822
823 if (soft->sadb_lifetime_addtime != 0 &&
824 idle->sadb_lifetime_addtime != 0 &&
825 soft->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
826 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
827
828 if (hard->sadb_lifetime_usetime != 0 &&
829 idle->sadb_lifetime_usetime != 0 &&
830 hard->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
831 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
832
833 if (soft->sadb_lifetime_usetime != 0 &&
834 idle->sadb_lifetime_usetime != 0 &&
835 soft->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
836 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
837 }
838
839 return (0);
840 }
841
842 /*
843 * Sanity check sensitivity labels.
844 *
845 * For now, just reject labels on unlabeled systems.
846 */
847 int
848 sadb_labelchk(keysock_in_t *ksi)
849 {
850 if (!is_system_labeled()) {
851 if (ksi->ks_in_extv[SADB_EXT_SENSITIVITY] != NULL)
852 return (SADB_X_DIAGNOSTIC_BAD_LABEL);
853
854 if (ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS] != NULL)
855 return (SADB_X_DIAGNOSTIC_BAD_LABEL);
856 }
857
858 return (0);
859 }
860
861 /*
862 * Clone a security association for the purposes of inserting a single SA
863 * into inbound and outbound tables respectively. This function should only
864 * be called from sadb_common_add().
865 */
866 static ipsa_t *
867 sadb_cloneassoc(ipsa_t *ipsa)
868 {
869 ipsa_t *newbie;
870 boolean_t error = B_FALSE;
871
872 ASSERT(MUTEX_NOT_HELD(&(ipsa->ipsa_lock)));
873
874 newbie = kmem_alloc(sizeof (ipsa_t), KM_NOSLEEP);
875 if (newbie == NULL)
876 return (NULL);
877
878 /* Copy over what we can. */
879 *newbie = *ipsa;
880
881 /* bzero and initialize locks, in case *_init() allocates... */
882 mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
883
884 if (newbie->ipsa_tsl != NULL)
885 label_hold(newbie->ipsa_tsl);
886
887 if (newbie->ipsa_otsl != NULL)
888 label_hold(newbie->ipsa_otsl);
889
890 /*
891 * While somewhat dain-bramaged, the most graceful way to
892 * recover from errors is to keep plowing through the
893 * allocations, and getting what I can. It's easier to call
894 * sadb_freeassoc() on the stillborn clone when all the
895 * pointers aren't pointing to the parent's data.
896 */
897
898 if (ipsa->ipsa_authkey != NULL) {
899 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
900 KM_NOSLEEP);
901 if (newbie->ipsa_authkey == NULL) {
902 error = B_TRUE;
903 } else {
904 bcopy(ipsa->ipsa_authkey, newbie->ipsa_authkey,
905 newbie->ipsa_authkeylen);
906
907 newbie->ipsa_kcfauthkey.ck_data =
908 newbie->ipsa_authkey;
909 }
910
911 if (newbie->ipsa_amech.cm_param != NULL) {
912 newbie->ipsa_amech.cm_param =
913 (char *)&newbie->ipsa_mac_len;
914 }
915 }
916
917 if (ipsa->ipsa_encrkey != NULL) {
918 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
919 KM_NOSLEEP);
920 if (newbie->ipsa_encrkey == NULL) {
921 error = B_TRUE;
922 } else {
923 bcopy(ipsa->ipsa_encrkey, newbie->ipsa_encrkey,
924 newbie->ipsa_encrkeylen);
925
926 newbie->ipsa_kcfencrkey.ck_data =
927 newbie->ipsa_encrkey;
928 }
929 }
930
931 newbie->ipsa_authtmpl = NULL;
932 newbie->ipsa_encrtmpl = NULL;
933 newbie->ipsa_haspeer = B_TRUE;
934
935 if (ipsa->ipsa_src_cid != NULL) {
936 newbie->ipsa_src_cid = ipsa->ipsa_src_cid;
937 IPSID_REFHOLD(ipsa->ipsa_src_cid);
938 }
939
940 if (ipsa->ipsa_dst_cid != NULL) {
941 newbie->ipsa_dst_cid = ipsa->ipsa_dst_cid;
942 IPSID_REFHOLD(ipsa->ipsa_dst_cid);
943 }
944
945 if (error) {
946 sadb_freeassoc(newbie);
947 return (NULL);
948 }
949
950 return (newbie);
951 }
952
953 /*
954 * Initialize a SADB address extension at the address specified by addrext.
955 * Return a pointer to the end of the new address extension.
956 */
957 static uint8_t *
958 sadb_make_addr_ext(uint8_t *start, uint8_t *end, uint16_t exttype,
959 sa_family_t af, uint32_t *addr, uint16_t port, uint8_t proto, int prefix)
960 {
961 struct sockaddr_in *sin;
962 struct sockaddr_in6 *sin6;
963 uint8_t *cur = start;
964 int addrext_len;
965 int sin_len;
966 sadb_address_t *addrext = (sadb_address_t *)cur;
967
968 if (cur == NULL)
969 return (NULL);
970
971 cur += sizeof (*addrext);
972 if (cur > end)
973 return (NULL);
974
975 addrext->sadb_address_proto = proto;
976 addrext->sadb_address_prefixlen = prefix;
977 addrext->sadb_address_reserved = 0;
978 addrext->sadb_address_exttype = exttype;
979
980 switch (af) {
981 case AF_INET:
982 sin = (struct sockaddr_in *)cur;
983 sin_len = sizeof (*sin);
984 cur += sin_len;
985 if (cur > end)
986 return (NULL);
987
988 sin->sin_family = af;
989 bzero(sin->sin_zero, sizeof (sin->sin_zero));
990 sin->sin_port = port;
991 IPSA_COPY_ADDR(&sin->sin_addr, addr, af);
992 break;
993 case AF_INET6:
994 sin6 = (struct sockaddr_in6 *)cur;
995 sin_len = sizeof (*sin6);
996 cur += sin_len;
997 if (cur > end)
998 return (NULL);
999
1000 bzero(sin6, sizeof (*sin6));
1001 sin6->sin6_family = af;
1002 sin6->sin6_port = port;
1003 IPSA_COPY_ADDR(&sin6->sin6_addr, addr, af);
1004 break;
1005 }
1006
1007 addrext_len = roundup(cur - start, sizeof (uint64_t));
1008 addrext->sadb_address_len = SADB_8TO64(addrext_len);
1009
1010 cur = start + addrext_len;
1011 if (cur > end)
1012 cur = NULL;
1013
1014 return (cur);
1015 }
1016
1017 /*
1018 * Construct a key management cookie extension.
1019 */
1020
1021 static uint8_t *
1022 sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint32_t kmc)
1023 {
1024 sadb_x_kmc_t *kmcext = (sadb_x_kmc_t *)cur;
1025
1026 if (cur == NULL)
1027 return (NULL);
1028
1029 cur += sizeof (*kmcext);
1030
1031 if (cur > end)
1032 return (NULL);
1033
1034 kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
1035 kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
1036 kmcext->sadb_x_kmc_proto = kmp;
1037 kmcext->sadb_x_kmc_cookie = kmc;
1038 kmcext->sadb_x_kmc_reserved = 0;
1039
1040 return (cur);
1041 }
1042
1043 /*
1044 * Given an original message header with sufficient space following it, and an
1045 * SA, construct a full PF_KEY message with all of the relevant extensions.
1046 * This is mostly used for SADB_GET, and SADB_DUMP.
1047 */
1048 static mblk_t *
1049 sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg)
1050 {
1051 int alloclen, addrsize, paddrsize, authsize, encrsize;
1052 int srcidsize, dstidsize, senslen, osenslen;
1053 sa_family_t fam, pfam; /* Address family for SADB_EXT_ADDRESS */
1054 /* src/dst and proxy sockaddrs. */
1055 /*
1056 * The following are pointers into the PF_KEY message this PF_KEY
1057 * message creates.
1058 */
1059 sadb_msg_t *newsamsg;
1060 sadb_sa_t *assoc;
1061 sadb_lifetime_t *lt;
1062 sadb_key_t *key;
1063 sadb_ident_t *ident;
1064 sadb_sens_t *sens;
1065 sadb_ext_t *walker; /* For when we need a generic ext. pointer. */
1066 sadb_x_replay_ctr_t *repl_ctr;
1067 sadb_x_pair_t *pair_ext;
1068
1069 mblk_t *mp;
1070 uint8_t *cur, *end;
1071 /* These indicate the presence of the above extension fields. */
1072 boolean_t soft = B_FALSE, hard = B_FALSE;
1073 boolean_t isrc = B_FALSE, idst = B_FALSE;
1074 boolean_t auth = B_FALSE, encr = B_FALSE;
1075 boolean_t sensinteg = B_FALSE, osensinteg = B_FALSE;
1076 boolean_t srcid = B_FALSE, dstid = B_FALSE;
1077 boolean_t idle;
1078 boolean_t paired;
1079 uint32_t otherspi;
1080
1081 /* First off, figure out the allocation length for this message. */
1082 /*
1083 * Constant stuff. This includes base, SA, address (src, dst),
1084 * and lifetime (current).
1085 */
1086 alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) +
1087 sizeof (sadb_lifetime_t);
1088
1089 fam = ipsa->ipsa_addrfam;
1090 switch (fam) {
1091 case AF_INET:
1092 addrsize = roundup(sizeof (struct sockaddr_in) +
1093 sizeof (sadb_address_t), sizeof (uint64_t));
1094 break;
1095 case AF_INET6:
1096 addrsize = roundup(sizeof (struct sockaddr_in6) +
1097 sizeof (sadb_address_t), sizeof (uint64_t));
1098 break;
1099 default:
1100 return (NULL);
1101 }
1102 /*
1103 * Allocate TWO address extensions, for source and destination.
1104 * (Thus, the * 2.)
1105 */
1106 alloclen += addrsize * 2;
1107 if (ipsa->ipsa_flags & IPSA_F_NATT_REM)
1108 alloclen += addrsize;
1109 if (ipsa->ipsa_flags & IPSA_F_NATT_LOC)
1110 alloclen += addrsize;
1111
1112 if (ipsa->ipsa_flags & IPSA_F_PAIRED) {
1113 paired = B_TRUE;
1114 alloclen += sizeof (sadb_x_pair_t);
1115 otherspi = ipsa->ipsa_otherspi;
1116 } else {
1117 paired = B_FALSE;
1118 }
1119
1120 /* How 'bout other lifetimes? */
1121 if (ipsa->ipsa_softaddlt != 0 || ipsa->ipsa_softuselt != 0 ||
1122 ipsa->ipsa_softbyteslt != 0 || ipsa->ipsa_softalloc != 0) {
1123 alloclen += sizeof (sadb_lifetime_t);
1124 soft = B_TRUE;
1125 }
1126
1127 if (ipsa->ipsa_hardaddlt != 0 || ipsa->ipsa_harduselt != 0 ||
1128 ipsa->ipsa_hardbyteslt != 0 || ipsa->ipsa_hardalloc != 0) {
1129 alloclen += sizeof (sadb_lifetime_t);
1130 hard = B_TRUE;
1131 }
1132
1133 if (ipsa->ipsa_idleaddlt != 0 || ipsa->ipsa_idleuselt != 0) {
1134 alloclen += sizeof (sadb_lifetime_t);
1135 idle = B_TRUE;
1136 } else {
1137 idle = B_FALSE;
1138 }
1139
1140 /* Inner addresses. */
1141 if (ipsa->ipsa_innerfam != 0) {
1142 pfam = ipsa->ipsa_innerfam;
1143 switch (pfam) {
1144 case AF_INET6:
1145 paddrsize = roundup(sizeof (struct sockaddr_in6) +
1146 sizeof (sadb_address_t), sizeof (uint64_t));
1147 break;
1148 case AF_INET:
1149 paddrsize = roundup(sizeof (struct sockaddr_in) +
1150 sizeof (sadb_address_t), sizeof (uint64_t));
1151 break;
1152 default:
1153 cmn_err(CE_PANIC,
1154 "IPsec SADB: Proxy length failure.\n");
1155 break;
1156 }
1157 isrc = B_TRUE;
1158 idst = B_TRUE;
1159 alloclen += 2 * paddrsize;
1160 }
1161
1162 /* For the following fields, assume that length != 0 ==> stuff */
1163 if (ipsa->ipsa_authkeylen != 0) {
1164 authsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_authkeylen,
1165 sizeof (uint64_t));
1166 alloclen += authsize;
1167 auth = B_TRUE;
1168 }
1169
1170 if (ipsa->ipsa_encrkeylen != 0) {
1171 encrsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_encrkeylen +
1172 ipsa->ipsa_nonce_len, sizeof (uint64_t));
1173 alloclen += encrsize;
1174 encr = B_TRUE;
1175 } else {
1176 encr = B_FALSE;
1177 }
1178
1179 if (ipsa->ipsa_tsl != NULL) {
1180 senslen = sadb_sens_len_from_label(ipsa->ipsa_tsl);
1181 alloclen += senslen;
1182 sensinteg = B_TRUE;
1183 }
1184
1185 if (ipsa->ipsa_otsl != NULL) {
1186 osenslen = sadb_sens_len_from_label(ipsa->ipsa_otsl);
1187 alloclen += osenslen;
1188 osensinteg = B_TRUE;
1189 }
1190
1191 /*
1192 * Must use strlen() here for lengths. Identities use NULL
1193 * pointers to indicate their nonexistence.
1194 */
1195 if (ipsa->ipsa_src_cid != NULL) {
1196 srcidsize = roundup(sizeof (sadb_ident_t) +
1197 strlen(ipsa->ipsa_src_cid->ipsid_cid) + 1,
1198 sizeof (uint64_t));
1199 alloclen += srcidsize;
1200 srcid = B_TRUE;
1201 }
1202
1203 if (ipsa->ipsa_dst_cid != NULL) {
1204 dstidsize = roundup(sizeof (sadb_ident_t) +
1205 strlen(ipsa->ipsa_dst_cid->ipsid_cid) + 1,
1206 sizeof (uint64_t));
1207 alloclen += dstidsize;
1208 dstid = B_TRUE;
1209 }
1210
1211 if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0))
1212 alloclen += sizeof (sadb_x_kmc_t);
1213
1214 if (ipsa->ipsa_replay != 0) {
1215 alloclen += sizeof (sadb_x_replay_ctr_t);
1216 }
1217
1218 /* Make sure the allocation length is a multiple of 8 bytes. */
1219 ASSERT((alloclen & 0x7) == 0);
1220
1221 /* XXX Possibly make it esballoc, with a bzero-ing free_ftn. */
1222 mp = allocb(alloclen, BPRI_HI);
1223 if (mp == NULL)
1224 return (NULL);
1225 bzero(mp->b_rptr, alloclen);
1226
1227 mp->b_wptr += alloclen;
1228 end = mp->b_wptr;
1229 newsamsg = (sadb_msg_t *)mp->b_rptr;
1230 *newsamsg = *samsg;
1231 newsamsg->sadb_msg_len = (uint16_t)SADB_8TO64(alloclen);
1232
1233 mutex_enter(&ipsa->ipsa_lock); /* Since I'm grabbing SA fields... */
1234
1235 newsamsg->sadb_msg_satype = ipsa->ipsa_type;
1236
1237 assoc = (sadb_sa_t *)(newsamsg + 1);
1238 assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc));
1239 assoc->sadb_sa_exttype = SADB_EXT_SA;
1240 assoc->sadb_sa_spi = ipsa->ipsa_spi;
1241 assoc->sadb_sa_replay = ipsa->ipsa_replay_wsize;
1242 assoc->sadb_sa_state = ipsa->ipsa_state;
1243 assoc->sadb_sa_auth = ipsa->ipsa_auth_alg;
1244 assoc->sadb_sa_encrypt = ipsa->ipsa_encr_alg;
1245 assoc->sadb_sa_flags = ipsa->ipsa_flags;
1246
1247 lt = (sadb_lifetime_t *)(assoc + 1);
1248 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1249 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
1250 /* We do not support the concept. */
1251 lt->sadb_lifetime_allocations = 0;
1252 lt->sadb_lifetime_bytes = ipsa->ipsa_bytes;
1253 lt->sadb_lifetime_addtime = ipsa->ipsa_addtime;
1254 lt->sadb_lifetime_usetime = ipsa->ipsa_usetime;
1255
1256 if (hard) {
1257 lt++;
1258 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1259 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1260 lt->sadb_lifetime_allocations = ipsa->ipsa_hardalloc;
1261 lt->sadb_lifetime_bytes = ipsa->ipsa_hardbyteslt;
1262 lt->sadb_lifetime_addtime = ipsa->ipsa_hardaddlt;
1263 lt->sadb_lifetime_usetime = ipsa->ipsa_harduselt;
1264 }
1265
1266 if (soft) {
1267 lt++;
1268 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1269 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1270 lt->sadb_lifetime_allocations = ipsa->ipsa_softalloc;
1271 lt->sadb_lifetime_bytes = ipsa->ipsa_softbyteslt;
1272 lt->sadb_lifetime_addtime = ipsa->ipsa_softaddlt;
1273 lt->sadb_lifetime_usetime = ipsa->ipsa_softuselt;
1274 }
1275
1276 if (idle) {
1277 lt++;
1278 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1279 lt->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
1280 lt->sadb_lifetime_addtime = ipsa->ipsa_idleaddlt;
1281 lt->sadb_lifetime_usetime = ipsa->ipsa_idleuselt;
1282 }
1283
1284 cur = (uint8_t *)(lt + 1);
1285
1286 /* NOTE: Don't fill in ports here if we are a tunnel-mode SA. */
1287 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, fam,
1288 ipsa->ipsa_srcaddr, (!isrc && !idst) ? SA_SRCPORT(ipsa) : 0,
1289 SA_PROTO(ipsa), 0);
1290 if (cur == NULL) {
1291 freemsg(mp);
1292 mp = NULL;
1293 goto bail;
1294 }
1295
1296 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, fam,
1297 ipsa->ipsa_dstaddr, (!isrc && !idst) ? SA_DSTPORT(ipsa) : 0,
1298 SA_PROTO(ipsa), 0);
1299 if (cur == NULL) {
1300 freemsg(mp);
1301 mp = NULL;
1302 goto bail;
1303 }
1304
1305 if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) {
1306 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_LOC,
1307 fam, &ipsa->ipsa_natt_addr_loc, ipsa->ipsa_local_nat_port,
1308 IPPROTO_UDP, 0);
1309 if (cur == NULL) {
1310 freemsg(mp);
1311 mp = NULL;
1312 goto bail;
1313 }
1314 }
1315
1316 if (ipsa->ipsa_flags & IPSA_F_NATT_REM) {
1317 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_REM,
1318 fam, &ipsa->ipsa_natt_addr_rem, ipsa->ipsa_remote_nat_port,
1319 IPPROTO_UDP, 0);
1320 if (cur == NULL) {
1321 freemsg(mp);
1322 mp = NULL;
1323 goto bail;
1324 }
1325 }
1326
1327 /* If we are a tunnel-mode SA, fill in the inner-selectors. */
1328 if (isrc) {
1329 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
1330 pfam, ipsa->ipsa_innersrc, SA_SRCPORT(ipsa),
1331 SA_IPROTO(ipsa), ipsa->ipsa_innersrcpfx);
1332 if (cur == NULL) {
1333 freemsg(mp);
1334 mp = NULL;
1335 goto bail;
1336 }
1337 }
1338
1339 if (idst) {
1340 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
1341 pfam, ipsa->ipsa_innerdst, SA_DSTPORT(ipsa),
1342 SA_IPROTO(ipsa), ipsa->ipsa_innerdstpfx);
1343 if (cur == NULL) {
1344 freemsg(mp);
1345 mp = NULL;
1346 goto bail;
1347 }
1348 }
1349
1350 if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) {
1351 cur = sadb_make_kmc_ext(cur, end,
1352 ipsa->ipsa_kmp, ipsa->ipsa_kmc);
1353 if (cur == NULL) {
1354 freemsg(mp);
1355 mp = NULL;
1356 goto bail;
1357 }
1358 }
1359
1360 walker = (sadb_ext_t *)cur;
1361 if (auth) {
1362 key = (sadb_key_t *)walker;
1363 key->sadb_key_len = SADB_8TO64(authsize);
1364 key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
1365 key->sadb_key_bits = ipsa->ipsa_authkeybits;
1366 key->sadb_key_reserved = 0;
1367 bcopy(ipsa->ipsa_authkey, key + 1, ipsa->ipsa_authkeylen);
1368 walker = (sadb_ext_t *)((uint64_t *)walker +
1369 walker->sadb_ext_len);
1370 }
1371
1372 if (encr) {
1373 uint8_t *buf_ptr;
1374 key = (sadb_key_t *)walker;
1375 key->sadb_key_len = SADB_8TO64(encrsize);
1376 key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1377 key->sadb_key_bits = ipsa->ipsa_encrkeybits;
1378 key->sadb_key_reserved = ipsa->ipsa_saltbits;
1379 buf_ptr = (uint8_t *)(key + 1);
1380 bcopy(ipsa->ipsa_encrkey, buf_ptr, ipsa->ipsa_encrkeylen);
1381 if (ipsa->ipsa_salt != NULL) {
1382 buf_ptr += ipsa->ipsa_encrkeylen;
1383 bcopy(ipsa->ipsa_salt, buf_ptr, ipsa->ipsa_saltlen);
1384 }
1385 walker = (sadb_ext_t *)((uint64_t *)walker +
1386 walker->sadb_ext_len);
1387 }
1388
1389 if (srcid) {
1390 ident = (sadb_ident_t *)walker;
1391 ident->sadb_ident_len = SADB_8TO64(srcidsize);
1392 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
1393 ident->sadb_ident_type = ipsa->ipsa_src_cid->ipsid_type;
1394 ident->sadb_ident_id = 0;
1395 ident->sadb_ident_reserved = 0;
1396 (void) strcpy((char *)(ident + 1),
1397 ipsa->ipsa_src_cid->ipsid_cid);
1398 walker = (sadb_ext_t *)((uint64_t *)walker +
1399 walker->sadb_ext_len);
1400 }
1401
1402 if (dstid) {
1403 ident = (sadb_ident_t *)walker;
1404 ident->sadb_ident_len = SADB_8TO64(dstidsize);
1405 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
1406 ident->sadb_ident_type = ipsa->ipsa_dst_cid->ipsid_type;
1407 ident->sadb_ident_id = 0;
1408 ident->sadb_ident_reserved = 0;
1409 (void) strcpy((char *)(ident + 1),
1410 ipsa->ipsa_dst_cid->ipsid_cid);
1411 walker = (sadb_ext_t *)((uint64_t *)walker +
1412 walker->sadb_ext_len);
1413 }
1414
1415 if (sensinteg) {
1416 sens = (sadb_sens_t *)walker;
1417 sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
1418 ipsa->ipsa_tsl, senslen);
1419
1420 walker = (sadb_ext_t *)((uint64_t *)walker +
1421 walker->sadb_ext_len);
1422 }
1423
1424 if (osensinteg) {
1425 sens = (sadb_sens_t *)walker;
1426
1427 sadb_sens_from_label(sens, SADB_X_EXT_OUTER_SENS,
1428 ipsa->ipsa_otsl, osenslen);
1429 if (ipsa->ipsa_mac_exempt)
1430 sens->sadb_x_sens_flags = SADB_X_SENS_IMPLICIT;
1431
1432 walker = (sadb_ext_t *)((uint64_t *)walker +
1433 walker->sadb_ext_len);
1434 }
1435
1436 if (paired) {
1437 pair_ext = (sadb_x_pair_t *)walker;
1438
1439 pair_ext->sadb_x_pair_len = SADB_8TO64(sizeof (sadb_x_pair_t));
1440 pair_ext->sadb_x_pair_exttype = SADB_X_EXT_PAIR;
1441 pair_ext->sadb_x_pair_spi = otherspi;
1442
1443 walker = (sadb_ext_t *)((uint64_t *)walker +
1444 walker->sadb_ext_len);
1445 }
1446
1447 if (ipsa->ipsa_replay != 0) {
1448 repl_ctr = (sadb_x_replay_ctr_t *)walker;
1449 repl_ctr->sadb_x_rc_len = SADB_8TO64(sizeof (*repl_ctr));
1450 repl_ctr->sadb_x_rc_exttype = SADB_X_EXT_REPLAY_VALUE;
1451 repl_ctr->sadb_x_rc_replay32 = ipsa->ipsa_replay;
1452 repl_ctr->sadb_x_rc_replay64 = 0;
1453 walker = (sadb_ext_t *)(repl_ctr + 1);
1454 }
1455
1456 bail:
1457 /* Pardon any delays... */
1458 mutex_exit(&ipsa->ipsa_lock);
1459
1460 return (mp);
1461 }
1462
1463 /*
1464 * Strip out key headers or unmarked headers (SADB_EXT_KEY_*, SADB_EXT_UNKNOWN)
1465 * and adjust base message accordingly.
1466 *
1467 * Assume message is pulled up in one piece of contiguous memory.
1468 *
1469 * Say if we start off with:
1470 *
1471 * +------+----+-------------+-----------+---------------+---------------+
1472 * | base | SA | source addr | dest addr | rsrvd. or key | soft lifetime |
1473 * +------+----+-------------+-----------+---------------+---------------+
1474 *
1475 * we will end up with
1476 *
1477 * +------+----+-------------+-----------+---------------+
1478 * | base | SA | source addr | dest addr | soft lifetime |
1479 * +------+----+-------------+-----------+---------------+
1480 */
1481 static void
1482 sadb_strip(sadb_msg_t *samsg)
1483 {
1484 sadb_ext_t *ext;
1485 uint8_t *target = NULL;
1486 uint8_t *msgend;
1487 int sofar = SADB_8TO64(sizeof (*samsg));
1488 int copylen;
1489
1490 ext = (sadb_ext_t *)(samsg + 1);
1491 msgend = (uint8_t *)samsg;
1492 msgend += SADB_64TO8(samsg->sadb_msg_len);
1493 while ((uint8_t *)ext < msgend) {
1494 if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1495 ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1496 ext->sadb_ext_type == SADB_X_EXT_EDUMP ||
1497 ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1498 /*
1499 * Aha! I found a header to be erased.
1500 */
1501
1502 if (target != NULL) {
1503 /*
1504 * If I had a previous header to be erased,
1505 * copy over it. I can get away with just
1506 * copying backwards because the target will
1507 * always be 8 bytes behind the source.
1508 */
1509 copylen = ((uint8_t *)ext) - (target +
1510 SADB_64TO8(
1511 ((sadb_ext_t *)target)->sadb_ext_len));
1512 ovbcopy(((uint8_t *)ext - copylen), target,
1513 copylen);
1514 target += copylen;
1515 ((sadb_ext_t *)target)->sadb_ext_len =
1516 SADB_8TO64(((uint8_t *)ext) - target +
1517 SADB_64TO8(ext->sadb_ext_len));
1518 } else {
1519 target = (uint8_t *)ext;
1520 }
1521 } else {
1522 sofar += ext->sadb_ext_len;
1523 }
1524
1525 ext = (sadb_ext_t *)(((uint64_t *)ext) + ext->sadb_ext_len);
1526 }
1527
1528 ASSERT((uint8_t *)ext == msgend);
1529
1530 if (target != NULL) {
1531 copylen = ((uint8_t *)ext) - (target +
1532 SADB_64TO8(((sadb_ext_t *)target)->sadb_ext_len));
1533 if (copylen != 0)
1534 ovbcopy(((uint8_t *)ext - copylen), target, copylen);
1535 }
1536
1537 /* Adjust samsg. */
1538 samsg->sadb_msg_len = (uint16_t)sofar;
1539
1540 /* Assume all of the rest is cleared by caller in sadb_pfkey_echo(). */
1541 }
1542
1543 /*
1544 * AH needs to send an error to PF_KEY. Assume mp points to an M_CTL
1545 * followed by an M_DATA with a PF_KEY message in it. The serial of
1546 * the sending keysock instance is included.
1547 */
1548 void
1549 sadb_pfkey_error(queue_t *pfkey_q, mblk_t *mp, int error, int diagnostic,
1550 uint_t serial)
1551 {
1552 mblk_t *msg = mp->b_cont;
1553 sadb_msg_t *samsg;
1554 keysock_out_t *kso;
1555
1556 /*
1557 * Enough functions call this to merit a NULL queue check.
1558 */
1559 if (pfkey_q == NULL) {
1560 freemsg(mp);
1561 return;
1562 }
1563
1564 ASSERT(msg != NULL);
1565 ASSERT((mp->b_wptr - mp->b_rptr) == sizeof (ipsec_info_t));
1566 ASSERT((msg->b_wptr - msg->b_rptr) >= sizeof (sadb_msg_t));
1567 samsg = (sadb_msg_t *)msg->b_rptr;
1568 kso = (keysock_out_t *)mp->b_rptr;
1569
1570 kso->ks_out_type = KEYSOCK_OUT;
1571 kso->ks_out_len = sizeof (*kso);
1572 kso->ks_out_serial = serial;
1573
1574 /*
1575 * Only send the base message up in the event of an error.
1576 * Don't worry about bzero()-ing, because it was probably bogus
1577 * anyway.
1578 */
1579 msg->b_wptr = msg->b_rptr + sizeof (*samsg);
1580 samsg = (sadb_msg_t *)msg->b_rptr;
1581 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
1582 samsg->sadb_msg_errno = (uint8_t)error;
1583 if (diagnostic != SADB_X_DIAGNOSTIC_PRESET)
1584 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
1585
1586 putnext(pfkey_q, mp);
1587 }
1588
1589 /*
1590 * Send a successful return packet back to keysock via the queue in pfkey_q.
1591 *
1592 * Often, an SA is associated with the reply message, it's passed in if needed,
1593 * and NULL if not. BTW, that ipsa will have its refcnt appropriately held,
1594 * and the caller will release said refcnt.
1595 */
1596 void
1597 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1598 keysock_in_t *ksi, ipsa_t *ipsa)
1599 {
1600 keysock_out_t *kso;
1601 mblk_t *mp1;
1602 sadb_msg_t *newsamsg;
1603 uint8_t *oldend;
1604
1605 ASSERT((mp->b_cont != NULL) &&
1606 ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1607 ((void *)mp->b_rptr == (void *)ksi));
1608
1609 switch (samsg->sadb_msg_type) {
1610 case SADB_ADD:
1611 case SADB_UPDATE:
1612 case SADB_X_UPDATEPAIR:
1613 case SADB_X_DELPAIR_STATE:
1614 case SADB_FLUSH:
1615 case SADB_DUMP:
1616 /*
1617 * I have all of the message already. I just need to strip
1618 * out the keying material and echo the message back.
1619 *
1620 * NOTE: for SADB_DUMP, the function sadb_dump() did the
1621 * work. When DUMP reaches here, it should only be a base
1622 * message.
1623 */
1624 justecho:
1625 if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL ||
1626 ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL ||
1627 ksi->ks_in_extv[SADB_X_EXT_EDUMP] != NULL) {
1628 sadb_strip(samsg);
1629 /* Assume PF_KEY message is contiguous. */
1630 ASSERT(mp->b_cont->b_cont == NULL);
1631 oldend = mp->b_cont->b_wptr;
1632 mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1633 SADB_64TO8(samsg->sadb_msg_len);
1634 bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1635 }
1636 break;
1637 case SADB_GET:
1638 /*
1639 * Do a lot of work here, because of the ipsa I just found.
1640 * First construct the new PF_KEY message, then abandon
1641 * the old one.
1642 */
1643 mp1 = sadb_sa2msg(ipsa, samsg);
1644 if (mp1 == NULL) {
1645 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1646 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1647 return;
1648 }
1649 freemsg(mp->b_cont);
1650 mp->b_cont = mp1;
1651 break;
1652 case SADB_DELETE:
1653 case SADB_X_DELPAIR:
1654 if (ipsa == NULL)
1655 goto justecho;
1656 /*
1657 * Because listening KMds may require more info, treat
1658 * DELETE like a special case of GET.
1659 */
1660 mp1 = sadb_sa2msg(ipsa, samsg);
1661 if (mp1 == NULL) {
1662 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1663 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1664 return;
1665 }
1666 newsamsg = (sadb_msg_t *)mp1->b_rptr;
1667 sadb_strip(newsamsg);
1668 oldend = mp1->b_wptr;
1669 mp1->b_wptr = mp1->b_rptr + SADB_64TO8(newsamsg->sadb_msg_len);
1670 bzero(mp1->b_wptr, oldend - mp1->b_wptr);
1671 freemsg(mp->b_cont);
1672 mp->b_cont = mp1;
1673 break;
1674 default:
1675 if (mp != NULL)
1676 freemsg(mp);
1677 return;
1678 }
1679
1680 /* ksi is now null and void. */
1681 kso = (keysock_out_t *)ksi;
1682 kso->ks_out_type = KEYSOCK_OUT;
1683 kso->ks_out_len = sizeof (*kso);
1684 kso->ks_out_serial = ksi->ks_in_serial;
1685 /* We're ready to send... */
1686 putnext(pfkey_q, mp);
1687 }
1688
1689 /*
1690 * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1691 */
1692 void
1693 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1694 void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype)
1695 {
1696 keysock_hello_ack_t *kha;
1697 queue_t *oldq;
1698
1699 ASSERT(OTHERQ(q) != NULL);
1700
1701 /*
1702 * First, check atomically that I'm the first and only keysock
1703 * instance.
1704 *
1705 * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1706 * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1707 * messages.
1708 */
1709
1710 oldq = atomic_cas_ptr((void **)pfkey_qp, NULL, OTHERQ(q));
1711 if (oldq != NULL) {
1712 ASSERT(oldq != q);
1713 cmn_err(CE_WARN, "Danger! Multiple keysocks on top of %s.\n",
1714 (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1715 freemsg(mp);
1716 return;
1717 }
1718
1719 kha = (keysock_hello_ack_t *)mp->b_rptr;
1720 kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1721 kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1722 kha->ks_hello_satype = (uint8_t)satype;
1723
1724 /*
1725 * If we made it past the atomic_cas_ptr, then we have "exclusive"
1726 * access to the timeout handle. Fire it off after the default ager
1727 * interval.
1728 */
1729 *top = qtimeout(*pfkey_qp, ager, agerarg,
1730 drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000));
1731
1732 putnext(*pfkey_qp, mp);
1733 }
1734
1735 /*
1736 * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate.
1737 *
1738 * Check addresses themselves for wildcard or multicast.
1739 * Check ire table for local/non-local/broadcast.
1740 */
1741 int
1742 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial,
1743 netstack_t *ns)
1744 {
1745 sadb_address_t *addr = (sadb_address_t *)ext;
1746 struct sockaddr_in *sin;
1747 struct sockaddr_in6 *sin6;
1748 int diagnostic, type;
1749 boolean_t normalized = B_FALSE;
1750
1751 ASSERT(ext != NULL);
1752 ASSERT((ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC) ||
1753 (ext->sadb_ext_type == SADB_EXT_ADDRESS_DST) ||
1754 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ||
1755 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) ||
1756 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_LOC) ||
1757 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_REM));
1758
1759 /* Assign both sockaddrs, the compiler will do the right thing. */
1760 sin = (struct sockaddr_in *)(addr + 1);
1761 sin6 = (struct sockaddr_in6 *)(addr + 1);
1762
1763 if (sin6->sin6_family == AF_INET6) {
1764 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1765 /*
1766 * Convert to an AF_INET sockaddr. This means the
1767 * return messages will have the extra space, but have
1768 * AF_INET sockaddrs instead of AF_INET6.
1769 *
1770 * Yes, RFC 2367 isn't clear on what to do here w.r.t.
1771 * mapped addresses, but since AF_INET6 ::ffff:<v4> is
1772 * equal to AF_INET <v4>, it shouldnt be a huge
1773 * problem.
1774 */
1775 sin->sin_family = AF_INET;
1776 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
1777 &sin->sin_addr);
1778 bzero(&sin->sin_zero, sizeof (sin->sin_zero));
1779 normalized = B_TRUE;
1780 }
1781 } else if (sin->sin_family != AF_INET) {
1782 switch (ext->sadb_ext_type) {
1783 case SADB_EXT_ADDRESS_SRC:
1784 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC_AF;
1785 break;
1786 case SADB_EXT_ADDRESS_DST:
1787 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
1788 break;
1789 case SADB_X_EXT_ADDRESS_INNER_SRC:
1790 diagnostic = SADB_X_DIAGNOSTIC_BAD_PROXY_AF;
1791 break;
1792 case SADB_X_EXT_ADDRESS_INNER_DST:
1793 diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF;
1794 break;
1795 case SADB_X_EXT_ADDRESS_NATT_LOC:
1796 diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF;
1797 break;
1798 case SADB_X_EXT_ADDRESS_NATT_REM:
1799 diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF;
1800 break;
1801 /* There is no default, see above ASSERT. */
1802 }
1803 bail:
1804 if (pfkey_q != NULL) {
1805 sadb_pfkey_error(pfkey_q, mp, EINVAL, diagnostic,
1806 serial);
1807 } else {
1808 /*
1809 * Scribble in sadb_msg that we got passed in.
1810 * Overload "mp" to be an sadb_msg pointer.
1811 */
1812 sadb_msg_t *samsg = (sadb_msg_t *)mp;
1813
1814 samsg->sadb_msg_errno = EINVAL;
1815 samsg->sadb_x_msg_diagnostic = diagnostic;
1816 }
1817 return (KS_IN_ADDR_UNKNOWN);
1818 }
1819
1820 if (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC ||
1821 ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) {
1822 /*
1823 * We need only check for prefix issues.
1824 */
1825
1826 /* Set diagnostic now, in case we need it later. */
1827 diagnostic =
1828 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ?
1829 SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC :
1830 SADB_X_DIAGNOSTIC_PREFIX_INNER_DST;
1831
1832 if (normalized)
1833 addr->sadb_address_prefixlen -= 96;
1834
1835 /*
1836 * Verify and mask out inner-addresses based on prefix length.
1837 */
1838 if (sin->sin_family == AF_INET) {
1839 if (addr->sadb_address_prefixlen > 32)
1840 goto bail;
1841 sin->sin_addr.s_addr &=
1842 ip_plen_to_mask(addr->sadb_address_prefixlen);
1843 } else {
1844 in6_addr_t mask;
1845
1846 ASSERT(sin->sin_family == AF_INET6);
1847 /*
1848 * ip_plen_to_mask_v6() returns NULL if the value in
1849 * question is out of range.
1850 */
1851 if (ip_plen_to_mask_v6(addr->sadb_address_prefixlen,
1852 &mask) == NULL)
1853 goto bail;
1854 sin6->sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
1855 sin6->sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
1856 sin6->sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
1857 sin6->sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
1858 }
1859
1860 /* We don't care in these cases. */
1861 return (KS_IN_ADDR_DONTCARE);
1862 }
1863
1864 if (sin->sin_family == AF_INET6) {
1865 /* Check the easy ones now. */
1866 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
1867 return (KS_IN_ADDR_MBCAST);
1868 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
1869 return (KS_IN_ADDR_UNSPEC);
1870 /*
1871 * At this point, we're a unicast IPv6 address.
1872 *
1873 * XXX Zones alert -> me/notme decision needs to be tempered
1874 * by what zone we're in when we go to zone-aware IPsec.
1875 */
1876 if (ip_type_v6(&sin6->sin6_addr, ns->netstack_ip) ==
1877 IRE_LOCAL) {
1878 /* Hey hey, it's local. */
1879 return (KS_IN_ADDR_ME);
1880 }
1881 } else {
1882 ASSERT(sin->sin_family == AF_INET);
1883 if (sin->sin_addr.s_addr == INADDR_ANY)
1884 return (KS_IN_ADDR_UNSPEC);
1885 if (CLASSD(sin->sin_addr.s_addr))
1886 return (KS_IN_ADDR_MBCAST);
1887 /*
1888 * At this point we're a unicast or broadcast IPv4 address.
1889 *
1890 * Check if the address is IRE_BROADCAST or IRE_LOCAL.
1891 *
1892 * XXX Zones alert -> me/notme decision needs to be tempered
1893 * by what zone we're in when we go to zone-aware IPsec.
1894 */
1895 type = ip_type_v4(sin->sin_addr.s_addr, ns->netstack_ip);
1896 switch (type) {
1897 case IRE_LOCAL:
1898 return (KS_IN_ADDR_ME);
1899 case IRE_BROADCAST:
1900 return (KS_IN_ADDR_MBCAST);
1901 }
1902 }
1903
1904 return (KS_IN_ADDR_NOTME);
1905 }
1906
1907 /*
1908 * Address normalizations and reality checks for inbound PF_KEY messages.
1909 *
1910 * For the case of src == unspecified AF_INET6, and dst == AF_INET, convert
1911 * the source to AF_INET. Do the same for the inner sources.
1912 */
1913 boolean_t
1914 sadb_addrfix(keysock_in_t *ksi, queue_t *pfkey_q, mblk_t *mp, netstack_t *ns)
1915 {
1916 struct sockaddr_in *src, *isrc;
1917 struct sockaddr_in6 *dst, *idst;
1918 sadb_address_t *srcext, *dstext;
1919 uint16_t sport;
1920 sadb_ext_t **extv = ksi->ks_in_extv;
1921 int rc;
1922
1923 if (extv[SADB_EXT_ADDRESS_SRC] != NULL) {
1924 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_SRC],
1925 ksi->ks_in_serial, ns);
1926 if (rc == KS_IN_ADDR_UNKNOWN)
1927 return (B_FALSE);
1928 if (rc == KS_IN_ADDR_MBCAST) {
1929 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1930 SADB_X_DIAGNOSTIC_BAD_SRC, ksi->ks_in_serial);
1931 return (B_FALSE);
1932 }
1933 ksi->ks_in_srctype = rc;
1934 }
1935
1936 if (extv[SADB_EXT_ADDRESS_DST] != NULL) {
1937 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_DST],
1938 ksi->ks_in_serial, ns);
1939 if (rc == KS_IN_ADDR_UNKNOWN)
1940 return (B_FALSE);
1941 if (rc == KS_IN_ADDR_UNSPEC) {
1942 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1943 SADB_X_DIAGNOSTIC_BAD_DST, ksi->ks_in_serial);
1944 return (B_FALSE);
1945 }
1946 ksi->ks_in_dsttype = rc;
1947 }
1948
1949 /*
1950 * NAT-Traversal addrs are simple enough to not require all of
1951 * the checks in sadb_addrcheck(). Just normalize or reject if not
1952 * AF_INET.
1953 */
1954 if (extv[SADB_X_EXT_ADDRESS_NATT_LOC] != NULL) {
1955 rc = sadb_addrcheck(pfkey_q, mp,
1956 extv[SADB_X_EXT_ADDRESS_NATT_LOC], ksi->ks_in_serial, ns);
1957
1958 /*
1959 * Local NAT-T addresses never use an IRE_LOCAL, so it should
1960 * always be NOTME, or UNSPEC (to handle both tunnel mode
1961 * AND local-port flexibility).
1962 */
1963 if (rc != KS_IN_ADDR_NOTME && rc != KS_IN_ADDR_UNSPEC) {
1964 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1965 SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC,
1966 ksi->ks_in_serial);
1967 return (B_FALSE);
1968 }
1969 src = (struct sockaddr_in *)
1970 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_LOC]) + 1);
1971 if (src->sin_family != AF_INET) {
1972 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1973 SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF,
1974 ksi->ks_in_serial);
1975 return (B_FALSE);
1976 }
1977 }
1978
1979 if (extv[SADB_X_EXT_ADDRESS_NATT_REM] != NULL) {
1980 rc = sadb_addrcheck(pfkey_q, mp,
1981 extv[SADB_X_EXT_ADDRESS_NATT_REM], ksi->ks_in_serial, ns);
1982
1983 /*
1984 * Remote NAT-T addresses never use an IRE_LOCAL, so it should
1985 * always be NOTME, or UNSPEC if it's a tunnel-mode SA.
1986 */
1987 if (rc != KS_IN_ADDR_NOTME &&
1988 !(extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL &&
1989 rc == KS_IN_ADDR_UNSPEC)) {
1990 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1991 SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM,
1992 ksi->ks_in_serial);
1993 return (B_FALSE);
1994 }
1995 src = (struct sockaddr_in *)
1996 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_REM]) + 1);
1997 if (src->sin_family != AF_INET) {
1998 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1999 SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF,
2000 ksi->ks_in_serial);
2001 return (B_FALSE);
2002 }
2003 }
2004
2005 if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL) {
2006 if (extv[SADB_X_EXT_ADDRESS_INNER_DST] == NULL) {
2007 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2008 SADB_X_DIAGNOSTIC_MISSING_INNER_DST,
2009 ksi->ks_in_serial);
2010 return (B_FALSE);
2011 }
2012
2013 if (sadb_addrcheck(pfkey_q, mp,
2014 extv[SADB_X_EXT_ADDRESS_INNER_DST], ksi->ks_in_serial, ns)
2015 == KS_IN_ADDR_UNKNOWN ||
2016 sadb_addrcheck(pfkey_q, mp,
2017 extv[SADB_X_EXT_ADDRESS_INNER_SRC], ksi->ks_in_serial, ns)
2018 == KS_IN_ADDR_UNKNOWN)
2019 return (B_FALSE);
2020
2021 isrc = (struct sockaddr_in *)
2022 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC]) +
2023 1);
2024 idst = (struct sockaddr_in6 *)
2025 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST]) +
2026 1);
2027 if (isrc->sin_family != idst->sin6_family) {
2028 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2029 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH,
2030 ksi->ks_in_serial);
2031 return (B_FALSE);
2032 }
2033 } else if (extv[SADB_X_EXT_ADDRESS_INNER_DST] != NULL) {
2034 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2035 SADB_X_DIAGNOSTIC_MISSING_INNER_SRC,
2036 ksi->ks_in_serial);
2037 return (B_FALSE);
2038 } else {
2039 isrc = NULL; /* For inner/outer port check below. */
2040 }
2041
2042 dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST];
2043 srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC];
2044
2045 if (dstext == NULL || srcext == NULL)
2046 return (B_TRUE);
2047
2048 dst = (struct sockaddr_in6 *)(dstext + 1);
2049 src = (struct sockaddr_in *)(srcext + 1);
2050
2051 if (isrc != NULL &&
2052 (isrc->sin_port != 0 || idst->sin6_port != 0) &&
2053 (src->sin_port != 0 || dst->sin6_port != 0)) {
2054 /* Can't set inner and outer ports in one SA. */
2055 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2056 SADB_X_DIAGNOSTIC_DUAL_PORT_SETS,
2057 ksi->ks_in_serial);
2058 return (B_FALSE);
2059 }
2060
2061 if (dst->sin6_family == src->sin_family)
2062 return (B_TRUE);
2063
2064 if (srcext->sadb_address_proto != dstext->sadb_address_proto) {
2065 if (srcext->sadb_address_proto == 0) {
2066 srcext->sadb_address_proto = dstext->sadb_address_proto;
2067 } else if (dstext->sadb_address_proto == 0) {
2068 dstext->sadb_address_proto = srcext->sadb_address_proto;
2069 } else {
2070 /* Inequal protocols, neither were 0. Report error. */
2071 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2072 SADB_X_DIAGNOSTIC_PROTO_MISMATCH,
2073 ksi->ks_in_serial);
2074 return (B_FALSE);
2075 }
2076 }
2077
2078 /*
2079 * With the exception of an unspec IPv6 source and an IPv4
2080 * destination, address families MUST me matched.
2081 */
2082 if (src->sin_family == AF_INET ||
2083 ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC) {
2084 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2085 SADB_X_DIAGNOSTIC_AF_MISMATCH, ksi->ks_in_serial);
2086 return (B_FALSE);
2087 }
2088
2089 /*
2090 * Convert "src" to AF_INET INADDR_ANY. We rely on sin_port being
2091 * in the same place for sockaddr_in and sockaddr_in6.
2092 */
2093 sport = src->sin_port;
2094 bzero(src, sizeof (*src));
2095 src->sin_family = AF_INET;
2096 src->sin_port = sport;
2097
2098 return (B_TRUE);
2099 }
2100
2101 /*
2102 * Set the results in "addrtype", given an IRE as requested by
2103 * sadb_addrcheck().
2104 */
2105 int
2106 sadb_addrset(ire_t *ire)
2107 {
2108 if ((ire->ire_type & IRE_BROADCAST) ||
2109 (ire->ire_ipversion == IPV4_VERSION && CLASSD(ire->ire_addr)) ||
2110 (ire->ire_ipversion == IPV6_VERSION &&
2111 IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6))))
2112 return (KS_IN_ADDR_MBCAST);
2113 if (ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK))
2114 return (KS_IN_ADDR_ME);
2115 return (KS_IN_ADDR_NOTME);
2116 }
2117
2118 /*
2119 * Match primitives..
2120 * !!! TODO: short term: inner selectors
2121 * ipv6 scope id (ifindex)
2122 * longer term: zone id. sensitivity label. uid.
2123 */
2124 boolean_t
2125 sadb_match_spi(ipsa_query_t *sq, ipsa_t *sa)
2126 {
2127 return (sq->spi == sa->ipsa_spi);
2128 }
2129
2130 boolean_t
2131 sadb_match_dst_v6(ipsa_query_t *sq, ipsa_t *sa)
2132 {
2133 return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_dstaddr, sq->dstaddr, AF_INET6));
2134 }
2135
2136 boolean_t
2137 sadb_match_src_v6(ipsa_query_t *sq, ipsa_t *sa)
2138 {
2139 return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_srcaddr, sq->srcaddr, AF_INET6));
2140 }
2141
2142 boolean_t
2143 sadb_match_dst_v4(ipsa_query_t *sq, ipsa_t *sa)
2144 {
2145 return (sq->dstaddr[0] == sa->ipsa_dstaddr[0]);
2146 }
2147
2148 boolean_t
2149 sadb_match_src_v4(ipsa_query_t *sq, ipsa_t *sa)
2150 {
2151 return (sq->srcaddr[0] == sa->ipsa_srcaddr[0]);
2152 }
2153
2154 boolean_t
2155 sadb_match_dstid(ipsa_query_t *sq, ipsa_t *sa)
2156 {
2157 return ((sa->ipsa_dst_cid != NULL) &&
2158 (sq->didtype == sa->ipsa_dst_cid->ipsid_type) &&
2159 (strcmp(sq->didstr, sa->ipsa_dst_cid->ipsid_cid) == 0));
2160
2161 }
2162 boolean_t
2163 sadb_match_srcid(ipsa_query_t *sq, ipsa_t *sa)
2164 {
2165 return ((sa->ipsa_src_cid != NULL) &&
2166 (sq->sidtype == sa->ipsa_src_cid->ipsid_type) &&
2167 (strcmp(sq->sidstr, sa->ipsa_src_cid->ipsid_cid) == 0));
2168 }
2169
2170 boolean_t
2171 sadb_match_kmc(ipsa_query_t *sq, ipsa_t *sa)
2172 {
2173 #define M(a, b) (((a) == 0) || ((b) == 0) || ((a) == (b)))
2174
2175 return (M(sq->kmc, sa->ipsa_kmc) && M(sq->kmp, sa->ipsa_kmp));
2176
2177 #undef M
2178 }
2179
2180 /*
2181 * Common function which extracts several PF_KEY extensions for ease of
2182 * SADB matching.
2183 *
2184 * XXX TODO: weed out ipsa_query_t fields not used during matching
2185 * or afterwards?
2186 */
2187 int
2188 sadb_form_query(keysock_in_t *ksi, uint32_t req, uint32_t match,
2189 ipsa_query_t *sq, int *diagnostic)
2190 {
2191 int i;
2192 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2193
2194 for (i = 0; i < IPSA_NMATCH; i++)
2195 sq->matchers[i] = NULL;
2196
2197 ASSERT((req & ~match) == 0);
2198
2199 sq->req = req;
2200 sq->dstext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2201 sq->srcext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2202 sq->assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2203
2204 if ((req & IPSA_Q_DST) && (sq->dstext == NULL)) {
2205 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2206 return (EINVAL);
2207 }
2208 if ((req & IPSA_Q_SRC) && (sq->srcext == NULL)) {
2209 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2210 return (EINVAL);
2211 }
2212 if ((req & IPSA_Q_SA) && (sq->assoc == NULL)) {
2213 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2214 return (EINVAL);
2215 }
2216
2217 if (match & IPSA_Q_SA) {
2218 *mfpp++ = sadb_match_spi;
2219 sq->spi = sq->assoc->sadb_sa_spi;
2220 }
2221
2222 if (sq->dstext != NULL)
2223 sq->dst = (struct sockaddr_in *)(sq->dstext + 1);
2224 else {
2225 sq->dst = NULL;
2226 sq->dst6 = NULL;
2227 sq->dstaddr = NULL;
2228 }
2229
2230 if (sq->srcext != NULL)
2231 sq->src = (struct sockaddr_in *)(sq->srcext + 1);
2232 else {
2233 sq->src = NULL;
2234 sq->src6 = NULL;
2235 sq->srcaddr = NULL;
2236 }
2237
2238 if (sq->dst != NULL)
2239 sq->af = sq->dst->sin_family;
2240 else if (sq->src != NULL)
2241 sq->af = sq->src->sin_family;
2242 else
2243 sq->af = AF_INET;
2244
2245 if (sq->af == AF_INET6) {
2246 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2247 *mfpp++ = sadb_match_dst_v6;
2248 sq->dst6 = (struct sockaddr_in6 *)sq->dst;
2249 sq->dstaddr = (uint32_t *)&(sq->dst6->sin6_addr);
2250 } else {
2251 match &= ~IPSA_Q_DST;
2252 sq->dstaddr = ALL_ZEROES_PTR;
2253 }
2254
2255 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2256 sq->src6 = (struct sockaddr_in6 *)(sq->srcext + 1);
2257 sq->srcaddr = (uint32_t *)&sq->src6->sin6_addr;
2258 if (sq->src6->sin6_family != AF_INET6) {
2259 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2260 return (EINVAL);
2261 }
2262 *mfpp++ = sadb_match_src_v6;
2263 } else {
2264 match &= ~IPSA_Q_SRC;
2265 sq->srcaddr = ALL_ZEROES_PTR;
2266 }
2267 } else {
2268 sq->src6 = sq->dst6 = NULL;
2269 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2270 *mfpp++ = sadb_match_dst_v4;
2271 sq->dstaddr = (uint32_t *)&sq->dst->sin_addr;
2272 } else {
2273 match &= ~IPSA_Q_DST;
2274 sq->dstaddr = ALL_ZEROES_PTR;
2275 }
2276 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2277 sq->srcaddr = (uint32_t *)&sq->src->sin_addr;
2278 if (sq->src->sin_family != AF_INET) {
2279 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2280 return (EINVAL);
2281 }
2282 *mfpp++ = sadb_match_src_v4;
2283 } else {
2284 match &= ~IPSA_Q_SRC;
2285 sq->srcaddr = ALL_ZEROES_PTR;
2286 }
2287 }
2288
2289 sq->dstid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
2290 if ((match & IPSA_Q_DSTID) && (sq->dstid != NULL)) {
2291 sq->didstr = (char *)(sq->dstid + 1);
2292 sq->didtype = sq->dstid->sadb_ident_type;
2293 *mfpp++ = sadb_match_dstid;
2294 }
2295
2296 sq->srcid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
2297
2298 if ((match & IPSA_Q_SRCID) && (sq->srcid != NULL)) {
2299 sq->sidstr = (char *)(sq->srcid + 1);
2300 sq->sidtype = sq->srcid->sadb_ident_type;
2301 *mfpp++ = sadb_match_srcid;
2302 }
2303
2304 sq->kmcext = (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2305 sq->kmc = 0;
2306 sq->kmp = 0;
2307
2308 if ((match & IPSA_Q_KMC) && (sq->kmcext)) {
2309 sq->kmc = sq->kmcext->sadb_x_kmc_cookie;
2310 sq->kmp = sq->kmcext->sadb_x_kmc_proto;
2311 *mfpp++ = sadb_match_kmc;
2312 }
2313
2314 if (match & (IPSA_Q_INBOUND|IPSA_Q_OUTBOUND)) {
2315 if (sq->af == AF_INET6)
2316 sq->sp = &sq->spp->s_v6;
2317 else
2318 sq->sp = &sq->spp->s_v4;
2319 } else {
2320 sq->sp = NULL;
2321 }
2322
2323 if (match & IPSA_Q_INBOUND) {
2324 sq->inhash = INBOUND_HASH(sq->sp, sq->assoc->sadb_sa_spi);
2325 sq->inbound = &sq->sp->sdb_if[sq->inhash];
2326 } else {
2327 sq->inhash = 0;
2328 sq->inbound = NULL;
2329 }
2330
2331 if (match & IPSA_Q_OUTBOUND) {
2332 if (sq->af == AF_INET6) {
2333 sq->outhash = OUTBOUND_HASH_V6(sq->sp, *(sq->dstaddr));
2334 } else {
2335 sq->outhash = OUTBOUND_HASH_V4(sq->sp, *(sq->dstaddr));
2336 }
2337 sq->outbound = &sq->sp->sdb_of[sq->outhash];
2338 } else {
2339 sq->outhash = 0;
2340 sq->outbound = NULL;
2341 }
2342 sq->match = match;
2343 return (0);
2344 }
2345
2346 /*
2347 * Match an initialized query structure with a security association;
2348 * return B_TRUE on a match, B_FALSE on a miss.
2349 * Applies match functions set up by sadb_form_query() until one returns false.
2350 */
2351 boolean_t
2352 sadb_match_query(ipsa_query_t *sq, ipsa_t *sa)
2353 {
2354 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2355 ipsa_match_fn_t mfp;
2356
2357 for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) {
2358 if (!mfp(sq, sa))
2359 return (B_FALSE);
2360 }
2361 return (B_TRUE);
2362 }
2363
2364 /*
2365 * Walker callback function to delete sa's based on src/dst address.
2366 * Assumes that we're called with *head locked, no other locks held;
2367 * Conveniently, and not coincidentally, this is both what sadb_walker
2368 * gives us and also what sadb_unlinkassoc expects.
2369 */
2370 struct sadb_purge_state
2371 {
2372 ipsa_query_t sq;
2373 boolean_t inbnd;
2374 uint8_t sadb_sa_state;
2375 };
2376
2377 static void
2378 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2379 {
2380 struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2381
2382 ASSERT(MUTEX_HELD(&head->isaf_lock));
2383
2384 mutex_enter(&entry->ipsa_lock);
2385
2386 if (entry->ipsa_state == IPSA_STATE_LARVAL ||
2387 !sadb_match_query(&ps->sq, entry)) {
2388 mutex_exit(&entry->ipsa_lock);
2389 return;
2390 }
2391
2392 entry->ipsa_state = IPSA_STATE_DEAD;
2393 (void) sadb_torch_assoc(head, entry);
2394 }
2395
2396 /*
2397 * Common code to purge an SA with a matching src or dst address.
2398 * Don't kill larval SA's in such a purge.
2399 */
2400 int
2401 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2402 int *diagnostic, queue_t *pfkey_q)
2403 {
2404 struct sadb_purge_state ps;
2405 int error = sadb_form_query(ksi, 0,
2406 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2407 &ps.sq, diagnostic);
2408
2409 if (error != 0)
2410 return (error);
2411
2412 /*
2413 * This is simple, crude, and effective.
2414 * Unimplemented optimizations (TBD):
2415 * - we can limit how many places we search based on where we
2416 * think the SA is filed.
2417 * - if we get a dst address, we can hash based on dst addr to find
2418 * the correct bucket in the outbound table.
2419 */
2420 ps.inbnd = B_TRUE;
2421 sadb_walker(sp->sdb_if, sp->sdb_hashsize, sadb_purge_cb, &ps);
2422 ps.inbnd = B_FALSE;
2423 sadb_walker(sp->sdb_of, sp->sdb_hashsize, sadb_purge_cb, &ps);
2424
2425 ASSERT(mp->b_cont != NULL);
2426 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2427 NULL);
2428 return (0);
2429 }
2430
2431 static void
2432 sadb_delpair_state_one(isaf_t *head, ipsa_t *entry, void *cookie)
2433 {
2434 struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2435 isaf_t *inbound_bucket;
2436 ipsa_t *peer_assoc;
2437 ipsa_query_t *sq = &ps->sq;
2438
2439 ASSERT(MUTEX_HELD(&head->isaf_lock));
2440
2441 mutex_enter(&entry->ipsa_lock);
2442
2443 if ((entry->ipsa_state != ps->sadb_sa_state) ||
2444 ((sq->srcaddr != NULL) &&
2445 !IPSA_ARE_ADDR_EQUAL(entry->ipsa_srcaddr, sq->srcaddr, sq->af))) {
2446 mutex_exit(&entry->ipsa_lock);
2447 return;
2448 }
2449
2450 /*
2451 * The isaf_t *, which is passed in , is always an outbound bucket,
2452 * and we are preserving the outbound-then-inbound hash-bucket lock
2453 * ordering. The sadb_walker() which triggers this function is called
2454 * only on the outbound fanout, and the corresponding inbound bucket
2455 * lock is safe to acquire here.
2456 */
2457
2458 if (entry->ipsa_haspeer) {
2459 inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_spi);
2460 mutex_enter(&inbound_bucket->isaf_lock);
2461 peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2462 entry->ipsa_spi, entry->ipsa_srcaddr,
2463 entry->ipsa_dstaddr, entry->ipsa_addrfam);
2464 } else {
2465 inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_otherspi);
2466 mutex_enter(&inbound_bucket->isaf_lock);
2467 peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2468 entry->ipsa_otherspi, entry->ipsa_dstaddr,
2469 entry->ipsa_srcaddr, entry->ipsa_addrfam);
2470 }
2471
2472 entry->ipsa_state = IPSA_STATE_DEAD;
2473 (void) sadb_torch_assoc(head, entry);
2474 if (peer_assoc != NULL) {
2475 mutex_enter(&peer_assoc->ipsa_lock);
2476 peer_assoc->ipsa_state = IPSA_STATE_DEAD;
2477 (void) sadb_torch_assoc(inbound_bucket, peer_assoc);
2478 }
2479 mutex_exit(&inbound_bucket->isaf_lock);
2480 }
2481
2482 static int
2483 sadb_delpair_state(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2484 int *diagnostic, queue_t *pfkey_q)
2485 {
2486 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2487 struct sadb_purge_state ps;
2488 int error;
2489
2490 ps.sq.spp = spp; /* XXX param */
2491
2492 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SRC,
2493 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2494 &ps.sq, diagnostic);
2495 if (error != 0)
2496 return (error);
2497
2498 ps.inbnd = B_FALSE;
2499 ps.sadb_sa_state = assoc->sadb_sa_state;
2500 sadb_walker(ps.sq.sp->sdb_of, ps.sq.sp->sdb_hashsize,
2501 sadb_delpair_state_one, &ps);
2502
2503 ASSERT(mp->b_cont != NULL);
2504 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
2505 ksi, NULL);
2506 return (0);
2507 }
2508
2509 /*
2510 * Common code to delete/get an SA.
2511 */
2512 int
2513 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2514 int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type)
2515 {
2516 ipsa_query_t sq;
2517 ipsa_t *echo_target = NULL;
2518 ipsap_t ipsapp;
2519 uint_t error = 0;
2520
2521 if (sadb_msg_type == SADB_X_DELPAIR_STATE)
2522 return (sadb_delpair_state(mp, ksi, spp, diagnostic, pfkey_q));
2523
2524 sq.spp = spp; /* XXX param */
2525 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA,
2526 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
2527 &sq, diagnostic);
2528 if (error != 0)
2529 return (error);
2530
2531 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
2532 if (error != 0) {
2533 return (error);
2534 }
2535
2536 echo_target = ipsapp.ipsap_sa_ptr;
2537 if (echo_target == NULL)
2538 echo_target = ipsapp.ipsap_psa_ptr;
2539
2540 if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) {
2541 /*
2542 * Bucket locks will be required if SA is actually unlinked.
2543 * get_ipsa_pair() returns valid hash bucket pointers even
2544 * if it can't find a pair SA pointer. To prevent a potential
2545 * deadlock, always lock the outbound bucket before the inbound.
2546 */
2547 if (ipsapp.in_inbound_table) {
2548 mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2549 mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2550 } else {
2551 mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2552 mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2553 }
2554
2555 if (ipsapp.ipsap_sa_ptr != NULL) {
2556 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
2557 ipsapp.ipsap_sa_ptr->ipsa_state = IPSA_STATE_DEAD;
2558 (void) sadb_torch_assoc(ipsapp.ipsap_bucket,
2559 ipsapp.ipsap_sa_ptr);
2560 /*
2561 * sadb_torch_assoc() releases the ipsa_lock
2562 * and calls sadb_unlinkassoc() which does a
2563 * IPSA_REFRELE.
2564 */
2565 }
2566 if (ipsapp.ipsap_psa_ptr != NULL) {
2567 mutex_enter(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2568 if (sadb_msg_type == SADB_X_DELPAIR ||
2569 ipsapp.ipsap_psa_ptr->ipsa_haspeer) {
2570 ipsapp.ipsap_psa_ptr->ipsa_state =
2571 IPSA_STATE_DEAD;
2572 (void) sadb_torch_assoc(ipsapp.ipsap_pbucket,
2573 ipsapp.ipsap_psa_ptr);
2574 } else {
2575 /*
2576 * Only half of the "pair" has been deleted.
2577 * Update the remaining SA and remove references
2578 * to its pair SA, which is now gone.
2579 */
2580 ipsapp.ipsap_psa_ptr->ipsa_otherspi = 0;
2581 ipsapp.ipsap_psa_ptr->ipsa_flags &=
2582 ~IPSA_F_PAIRED;
2583 mutex_exit(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2584 }
2585 } else if (sadb_msg_type == SADB_X_DELPAIR) {
2586 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
2587 error = ESRCH;
2588 }
2589 mutex_exit(&ipsapp.ipsap_bucket->isaf_lock);
2590 mutex_exit(&ipsapp.ipsap_pbucket->isaf_lock);
2591 }
2592
2593 ASSERT(mp->b_cont != NULL);
2594
2595 if (error == 0)
2596 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)
2597 mp->b_cont->b_rptr, ksi, echo_target);
2598
2599 destroy_ipsa_pair(&ipsapp);
2600
2601 return (error);
2602 }
2603
2604 /*
2605 * This function takes a sadb_sa_t and finds the ipsa_t structure
2606 * and the isaf_t (hash bucket) that its stored under. If the security
2607 * association has a peer, the ipsa_t structure and bucket for that security
2608 * association are also searched for. The "pair" of ipsa_t's and isaf_t's
2609 * are returned as a ipsap_t.
2610 *
2611 * The hash buckets are returned for convenience, if the calling function
2612 * needs to use the hash bucket locks, say to remove the SA's, it should
2613 * take care to observe the convention of locking outbound bucket then
2614 * inbound bucket. The flag in_inbound_table provides direction.
2615 *
2616 * Note that a "pair" is defined as one (but not both) of the following:
2617 *
2618 * A security association which has a soft reference to another security
2619 * association via its SPI.
2620 *
2621 * A security association that is not obviously "inbound" or "outbound" so
2622 * it appears in both hash tables, the "peer" being the same security
2623 * association in the other hash table.
2624 *
2625 * This function will return NULL if the ipsa_t can't be found in the
2626 * inbound or outbound hash tables (not found). If only one ipsa_t is
2627 * found, the pair ipsa_t will be NULL. Both isaf_t values are valid
2628 * provided at least one ipsa_t is found.
2629 */
2630 static int
2631 get_ipsa_pair(ipsa_query_t *sq, ipsap_t *ipsapp, int *diagnostic)
2632 {
2633 uint32_t pair_srcaddr[IPSA_MAX_ADDRLEN];
2634 uint32_t pair_dstaddr[IPSA_MAX_ADDRLEN];
2635 uint32_t pair_spi;
2636
2637 init_ipsa_pair(ipsapp);
2638
2639 ipsapp->in_inbound_table = B_FALSE;
2640
2641 /* Lock down both buckets. */
2642 mutex_enter(&sq->outbound->isaf_lock);
2643 mutex_enter(&sq->inbound->isaf_lock);
2644
2645 if (sq->assoc->sadb_sa_flags & IPSA_F_INBOUND) {
2646 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2647 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2648 if (ipsapp->ipsap_sa_ptr != NULL) {
2649 ipsapp->ipsap_bucket = sq->inbound;
2650 ipsapp->ipsap_pbucket = sq->outbound;
2651 ipsapp->in_inbound_table = B_TRUE;
2652 } else {
2653 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->outbound,
2654 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2655 sq->af);
2656 ipsapp->ipsap_bucket = sq->outbound;
2657 ipsapp->ipsap_pbucket = sq->inbound;
2658 }
2659 } else {
2660 /* IPSA_F_OUTBOUND is set *or* no directions flags set. */
2661 ipsapp->ipsap_sa_ptr =
2662 ipsec_getassocbyspi(sq->outbound,
2663 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2664 if (ipsapp->ipsap_sa_ptr != NULL) {
2665 ipsapp->ipsap_bucket = sq->outbound;
2666 ipsapp->ipsap_pbucket = sq->inbound;
2667 } else {
2668 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2669 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2670 sq->af);
2671 ipsapp->ipsap_bucket = sq->inbound;
2672 ipsapp->ipsap_pbucket = sq->outbound;
2673 if (ipsapp->ipsap_sa_ptr != NULL)
2674 ipsapp->in_inbound_table = B_TRUE;
2675 }
2676 }
2677
2678 if (ipsapp->ipsap_sa_ptr == NULL) {
2679 mutex_exit(&sq->outbound->isaf_lock);
2680 mutex_exit(&sq->inbound->isaf_lock);
2681 *diagnostic = SADB_X_DIAGNOSTIC_SA_NOTFOUND;
2682 return (ESRCH);
2683 }
2684
2685 if ((ipsapp->ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) &&
2686 ipsapp->in_inbound_table) {
2687 mutex_exit(&sq->outbound->isaf_lock);
2688 mutex_exit(&sq->inbound->isaf_lock);
2689 return (0);
2690 }
2691
2692 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2693 if (ipsapp->ipsap_sa_ptr->ipsa_haspeer) {
2694 /*
2695 * haspeer implies no sa_pairing, look for same spi
2696 * in other hashtable.
2697 */
2698 ipsapp->ipsap_psa_ptr =
2699 ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2700 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2701 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2702 mutex_exit(&sq->outbound->isaf_lock);
2703 mutex_exit(&sq->inbound->isaf_lock);
2704 return (0);
2705 }
2706 pair_spi = ipsapp->ipsap_sa_ptr->ipsa_otherspi;
2707 IPSA_COPY_ADDR(&pair_srcaddr,
2708 ipsapp->ipsap_sa_ptr->ipsa_srcaddr, sq->af);
2709 IPSA_COPY_ADDR(&pair_dstaddr,
2710 ipsapp->ipsap_sa_ptr->ipsa_dstaddr, sq->af);
2711 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2712 mutex_exit(&sq->inbound->isaf_lock);
2713 mutex_exit(&sq->outbound->isaf_lock);
2714
2715 if (pair_spi == 0) {
2716 ASSERT(ipsapp->ipsap_bucket != NULL);
2717 ASSERT(ipsapp->ipsap_pbucket != NULL);
2718 return (0);
2719 }
2720
2721 /* found sa in outbound sadb, peer should be inbound */
2722
2723 if (ipsapp->in_inbound_table) {
2724 /* Found SA in inbound table, pair will be in outbound. */
2725 if (sq->af == AF_INET6) {
2726 ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V6(sq->sp,
2727 *(uint32_t *)pair_srcaddr);
2728 } else {
2729 ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V4(sq->sp,
2730 *(uint32_t *)pair_srcaddr);
2731 }
2732 } else {
2733 ipsapp->ipsap_pbucket = INBOUND_BUCKET(sq->sp, pair_spi);
2734 }
2735 mutex_enter(&ipsapp->ipsap_pbucket->isaf_lock);
2736 ipsapp->ipsap_psa_ptr = ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2737 pair_spi, pair_dstaddr, pair_srcaddr, sq->af);
2738 mutex_exit(&ipsapp->ipsap_pbucket->isaf_lock);
2739 ASSERT(ipsapp->ipsap_bucket != NULL);
2740 ASSERT(ipsapp->ipsap_pbucket != NULL);
2741 return (0);
2742 }
2743
2744 /*
2745 * Perform NAT-traversal cached checksum offset calculations here.
2746 */
2747 static void
2748 sadb_nat_calculations(ipsa_t *newbie, sadb_address_t *natt_loc_ext,
2749 sadb_address_t *natt_rem_ext, uint32_t *src_addr_ptr,
2750 uint32_t *dst_addr_ptr)
2751 {
2752 struct sockaddr_in *natt_loc, *natt_rem;
2753 uint32_t *natt_loc_ptr = NULL, *natt_rem_ptr = NULL;
2754 uint32_t running_sum = 0;
2755
2756 #define DOWN_SUM(x) (x) = ((x) & 0xFFFF) + ((x) >> 16)
2757
2758 if (natt_rem_ext != NULL) {
2759 uint32_t l_src;
2760 uint32_t l_rem;
2761
2762 natt_rem = (struct sockaddr_in *)(natt_rem_ext + 1);
2763
2764 /* Ensured by sadb_addrfix(). */
2765 ASSERT(natt_rem->sin_family == AF_INET);
2766
2767 natt_rem_ptr = (uint32_t *)(&natt_rem->sin_addr);
2768 newbie->ipsa_remote_nat_port = natt_rem->sin_port;
2769 l_src = *src_addr_ptr;
2770 l_rem = *natt_rem_ptr;
2771
2772 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2773 newbie->ipsa_natt_addr_rem = *natt_rem_ptr;
2774
2775 l_src = ntohl(l_src);
2776 DOWN_SUM(l_src);
2777 DOWN_SUM(l_src);
2778 l_rem = ntohl(l_rem);
2779 DOWN_SUM(l_rem);
2780 DOWN_SUM(l_rem);
2781
2782 /*
2783 * We're 1's complement for checksums, so check for wraparound
2784 * here.
2785 */
2786 if (l_rem > l_src)
2787 l_src--;
2788
2789 running_sum += l_src - l_rem;
2790
2791 DOWN_SUM(running_sum);
2792 DOWN_SUM(running_sum);
2793 }
2794
2795 if (natt_loc_ext != NULL) {
2796 natt_loc = (struct sockaddr_in *)(natt_loc_ext + 1);
2797
2798 /* Ensured by sadb_addrfix(). */
2799 ASSERT(natt_loc->sin_family == AF_INET);
2800
2801 natt_loc_ptr = (uint32_t *)(&natt_loc->sin_addr);
2802 newbie->ipsa_local_nat_port = natt_loc->sin_port;
2803
2804 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2805 newbie->ipsa_natt_addr_loc = *natt_loc_ptr;
2806
2807 /*
2808 * NAT-T port agility means we may have natt_loc_ext, but
2809 * only for a local-port change.
2810 */
2811 if (natt_loc->sin_addr.s_addr != INADDR_ANY) {
2812 uint32_t l_dst = ntohl(*dst_addr_ptr);
2813 uint32_t l_loc = ntohl(*natt_loc_ptr);
2814
2815 DOWN_SUM(l_loc);
2816 DOWN_SUM(l_loc);
2817 DOWN_SUM(l_dst);
2818 DOWN_SUM(l_dst);
2819
2820 /*
2821 * We're 1's complement for checksums, so check for
2822 * wraparound here.
2823 */
2824 if (l_loc > l_dst)
2825 l_dst--;
2826
2827 running_sum += l_dst - l_loc;
2828 DOWN_SUM(running_sum);
2829 DOWN_SUM(running_sum);
2830 }
2831 }
2832
2833 newbie->ipsa_inbound_cksum = running_sum;
2834 #undef DOWN_SUM
2835 }
2836
2837 /*
2838 * This function is called from consumers that need to insert a fully-grown
2839 * security association into its tables. This function takes into account that
2840 * SAs can be "inbound", "outbound", or "both". The "primary" and "secondary"
2841 * hash bucket parameters are set in order of what the SA will be most of the
2842 * time. (For example, an SA with an unspecified source, and a multicast
2843 * destination will primarily be an outbound SA. OTOH, if that destination
2844 * is unicast for this node, then the SA will primarily be inbound.)
2845 *
2846 * It takes a lot of parameters because even if clone is B_FALSE, this needs
2847 * to check both buckets for purposes of collision.
2848 *
2849 * Return 0 upon success. Return various errnos (ENOMEM, EEXIST) for
2850 * various error conditions. We may need to set samsg->sadb_x_msg_diagnostic
2851 * with additional diagnostic information because there is at least one EINVAL
2852 * case here.
2853 */
2854 int
2855 sadb_common_add(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
2856 keysock_in_t *ksi, isaf_t *primary, isaf_t *secondary,
2857 ipsa_t *newbie, boolean_t clone, boolean_t is_inbound, int *diagnostic,
2858 netstack_t *ns, sadbp_t *spp)
2859 {
2860 ipsa_t *newbie_clone = NULL, *scratch;
2861 ipsap_t ipsapp;
2862 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2863 sadb_address_t *srcext =
2864 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2865 sadb_address_t *dstext =
2866 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2867 sadb_address_t *isrcext =
2868 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC];
2869 sadb_address_t *idstext =
2870 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_DST];
2871 sadb_x_kmc_t *kmcext =
2872 (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2873 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
2874 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
2875 sadb_sens_t *sens =
2876 (sadb_sens_t *)ksi->ks_in_extv[SADB_EXT_SENSITIVITY];
2877 sadb_sens_t *osens =
2878 (sadb_sens_t *)ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS];
2879 sadb_x_pair_t *pair_ext =
2880 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
2881 sadb_x_replay_ctr_t *replayext =
2882 (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
2883 int salt_offset;
2884 uint8_t *buf_ptr;
2885 struct sockaddr_in *src, *dst, *isrc, *idst;
2886 struct sockaddr_in6 *src6, *dst6, *isrc6, *idst6;
2887 sadb_lifetime_t *soft =
2888 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
2889 sadb_lifetime_t *hard =
2890 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
2891 sadb_lifetime_t *idle =
2892 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
2893 sa_family_t af;
2894 int error = 0;
2895 boolean_t isupdate = (newbie != NULL);
2896 uint32_t *src_addr_ptr, *dst_addr_ptr, *isrc_addr_ptr, *idst_addr_ptr;
2897 ipsec_stack_t *ipss = ns->netstack_ipsec;
2898 ip_stack_t *ipst = ns->netstack_ip;
2899 ipsec_alginfo_t *alg;
2900 boolean_t async = B_FALSE;
2901
2902 init_ipsa_pair(&ipsapp);
2903
2904 if (srcext == NULL) {
2905 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2906 return (EINVAL);
2907 }
2908 if (dstext == NULL) {
2909 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2910 return (EINVAL);
2911 }
2912 if (assoc == NULL) {
2913 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2914 return (EINVAL);
2915 }
2916
2917 src = (struct sockaddr_in *)(srcext + 1);
2918 src6 = (struct sockaddr_in6 *)(srcext + 1);
2919 dst = (struct sockaddr_in *)(dstext + 1);
2920 dst6 = (struct sockaddr_in6 *)(dstext + 1);
2921 if (isrcext != NULL) {
2922 isrc = (struct sockaddr_in *)(isrcext + 1);
2923 isrc6 = (struct sockaddr_in6 *)(isrcext + 1);
2924 ASSERT(idstext != NULL);
2925 idst = (struct sockaddr_in *)(idstext + 1);
2926 idst6 = (struct sockaddr_in6 *)(idstext + 1);
2927 } else {
2928 isrc = NULL;
2929 isrc6 = NULL;
2930 }
2931
2932 af = src->sin_family;
2933
2934 if (af == AF_INET) {
2935 src_addr_ptr = (uint32_t *)&src->sin_addr;
2936 dst_addr_ptr = (uint32_t *)&dst->sin_addr;
2937 } else {
2938 ASSERT(af == AF_INET6);
2939 src_addr_ptr = (uint32_t *)&src6->sin6_addr;
2940 dst_addr_ptr = (uint32_t *)&dst6->sin6_addr;
2941 }
2942
2943 /*
2944 * Check to see if the new SA will be cloned AND paired. The
2945 * reason a SA will be cloned is the source or destination addresses
2946 * are not specific enough to determine if the SA goes in the outbound
2947 * or the inbound hash table, so its cloned and put in both. If
2948 * the SA is paired, it's soft linked to another SA for the other
2949 * direction. Keeping track and looking up SA's that are direction
2950 * unspecific and linked is too hard.
2951 */
2952 if (clone && (pair_ext != NULL)) {
2953 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
2954 return (EINVAL);
2955 }
2956
2957 if (!isupdate) {
2958 newbie = sadb_makelarvalassoc(assoc->sadb_sa_spi,
2959 src_addr_ptr, dst_addr_ptr, af, ns);
2960 if (newbie == NULL)
2961 return (ENOMEM);
2962 }
2963
2964 mutex_enter(&newbie->ipsa_lock);
2965
2966 if (isrc != NULL) {
2967 if (isrc->sin_family == AF_INET) {
2968 if (srcext->sadb_address_proto != IPPROTO_ENCAP) {
2969 if (srcext->sadb_address_proto != 0) {
2970 /*
2971 * Mismatched outer-packet protocol
2972 * and inner-packet address family.
2973 */
2974 mutex_exit(&newbie->ipsa_lock);
2975 error = EPROTOTYPE;
2976 *diagnostic =
2977 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
2978 goto error;
2979 } else {
2980 /* Fill in with explicit protocol. */
2981 srcext->sadb_address_proto =
2982 IPPROTO_ENCAP;
2983 dstext->sadb_address_proto =
2984 IPPROTO_ENCAP;
2985 }
2986 }
2987 isrc_addr_ptr = (uint32_t *)&isrc->sin_addr;
2988 idst_addr_ptr = (uint32_t *)&idst->sin_addr;
2989 } else {
2990 ASSERT(isrc->sin_family == AF_INET6);
2991 if (srcext->sadb_address_proto != IPPROTO_IPV6) {
2992 if (srcext->sadb_address_proto != 0) {
2993 /*
2994 * Mismatched outer-packet protocol
2995 * and inner-packet address family.
2996 */
2997 mutex_exit(&newbie->ipsa_lock);
2998 error = EPROTOTYPE;
2999 *diagnostic =
3000 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
3001 goto error;
3002 } else {
3003 /* Fill in with explicit protocol. */
3004 srcext->sadb_address_proto =
3005 IPPROTO_IPV6;
3006 dstext->sadb_address_proto =
3007 IPPROTO_IPV6;
3008 }
3009 }
3010 isrc_addr_ptr = (uint32_t *)&isrc6->sin6_addr;
3011 idst_addr_ptr = (uint32_t *)&idst6->sin6_addr;
3012 }
3013 newbie->ipsa_innerfam = isrc->sin_family;
3014
3015 IPSA_COPY_ADDR(newbie->ipsa_innersrc, isrc_addr_ptr,
3016 newbie->ipsa_innerfam);
3017 IPSA_COPY_ADDR(newbie->ipsa_innerdst, idst_addr_ptr,
3018 newbie->ipsa_innerfam);
3019 newbie->ipsa_innersrcpfx = isrcext->sadb_address_prefixlen;
3020 newbie->ipsa_innerdstpfx = idstext->sadb_address_prefixlen;
3021
3022 /* Unique value uses inner-ports for Tunnel Mode... */
3023 newbie->ipsa_unique_id = SA_UNIQUE_ID(isrc->sin_port,
3024 idst->sin_port, dstext->sadb_address_proto,
3025 idstext->sadb_address_proto);
3026 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(isrc->sin_port,
3027 idst->sin_port, dstext->sadb_address_proto,
3028 idstext->sadb_address_proto);
3029 } else {
3030 /* ... and outer-ports for Transport Mode. */
3031 newbie->ipsa_unique_id = SA_UNIQUE_ID(src->sin_port,
3032 dst->sin_port, dstext->sadb_address_proto, 0);
3033 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(src->sin_port,
3034 dst->sin_port, dstext->sadb_address_proto, 0);
3035 }
3036 if (newbie->ipsa_unique_mask != (uint64_t)0)
3037 newbie->ipsa_flags |= IPSA_F_UNIQUE;
3038
3039 sadb_nat_calculations(newbie,
3040 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC],
3041 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM],
3042 src_addr_ptr, dst_addr_ptr);
3043
3044 newbie->ipsa_type = samsg->sadb_msg_satype;
3045
3046 ASSERT((assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
3047 (assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE));
3048 newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
3049 newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
3050
3051 newbie->ipsa_flags |= assoc->sadb_sa_flags;
3052 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_LOC &&
3053 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC] == NULL) {
3054 mutex_exit(&newbie->ipsa_lock);
3055 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_LOC;
3056 error = EINVAL;
3057 goto error;
3058 }
3059 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_REM &&
3060 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM] == NULL) {
3061 mutex_exit(&newbie->ipsa_lock);
3062 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_REM;
3063 error = EINVAL;
3064 goto error;
3065 }
3066 if (newbie->ipsa_flags & SADB_X_SAFLAGS_TUNNEL &&
3067 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL) {
3068 mutex_exit(&newbie->ipsa_lock);
3069 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
3070 error = EINVAL;
3071 goto error;
3072 }
3073 /*
3074 * If unspecified source address, force replay_wsize to 0.
3075 * This is because an SA that has multiple sources of secure
3076 * traffic cannot enforce a replay counter w/o synchronizing the
3077 * senders.
3078 */
3079 if (ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC)
3080 newbie->ipsa_replay_wsize = assoc->sadb_sa_replay;
3081 else
3082 newbie->ipsa_replay_wsize = 0;
3083
3084 newbie->ipsa_addtime = gethrestime_sec();
3085
3086 if (kmcext != NULL) {
3087 newbie->ipsa_kmp = kmcext->sadb_x_kmc_proto;
3088 newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie;
3089 }
3090
3091 /*
3092 * XXX CURRENT lifetime checks MAY BE needed for an UPDATE.
3093 * The spec says that one can update current lifetimes, but
3094 * that seems impractical, especially in the larval-to-mature
3095 * update that this function performs.
3096 */
3097 if (soft != NULL) {
3098 newbie->ipsa_softaddlt = soft->sadb_lifetime_addtime;
3099 newbie->ipsa_softuselt = soft->sadb_lifetime_usetime;
3100 newbie->ipsa_softbyteslt = soft->sadb_lifetime_bytes;
3101 newbie->ipsa_softalloc = soft->sadb_lifetime_allocations;
3102 SET_EXPIRE(newbie, softaddlt, softexpiretime);
3103 }
3104 if (hard != NULL) {
3105 newbie->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
3106 newbie->ipsa_harduselt = hard->sadb_lifetime_usetime;
3107 newbie->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
3108 newbie->ipsa_hardalloc = hard->sadb_lifetime_allocations;
3109 SET_EXPIRE(newbie, hardaddlt, hardexpiretime);
3110 }
3111 if (idle != NULL) {
3112 newbie->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
3113 newbie->ipsa_idleuselt = idle->sadb_lifetime_usetime;
3114 newbie->ipsa_idleexpiretime = newbie->ipsa_addtime +
3115 newbie->ipsa_idleaddlt;
3116 newbie->ipsa_idletime = newbie->ipsa_idleaddlt;
3117 }
3118
3119 newbie->ipsa_authtmpl = NULL;
3120 newbie->ipsa_encrtmpl = NULL;
3121
3122 #ifdef IPSEC_LATENCY_TEST
3123 if (akey != NULL && newbie->ipsa_auth_alg != SADB_AALG_NONE) {
3124 #else
3125 if (akey != NULL) {
3126 #endif
3127 async = (ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
3128 IPSEC_ALGS_EXEC_ASYNC);
3129
3130 newbie->ipsa_authkeybits = akey->sadb_key_bits;
3131 newbie->ipsa_authkeylen = SADB_1TO8(akey->sadb_key_bits);
3132 /* In case we have to round up to the next byte... */
3133 if ((akey->sadb_key_bits & 0x7) != 0)
3134 newbie->ipsa_authkeylen++;
3135 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
3136 KM_NOSLEEP);
3137 if (newbie->ipsa_authkey == NULL) {
3138 error = ENOMEM;
3139 mutex_exit(&newbie->ipsa_lock);
3140 goto error;
3141 }
3142 bcopy(akey + 1, newbie->ipsa_authkey, newbie->ipsa_authkeylen);
3143 bzero(akey + 1, newbie->ipsa_authkeylen);
3144
3145 /*
3146 * Pre-initialize the kernel crypto framework key
3147 * structure.
3148 */
3149 newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
3150 newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
3151 newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
3152
3153 mutex_enter(&ipss->ipsec_alg_lock);
3154 alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
3155 [newbie->ipsa_auth_alg];
3156 if (alg != NULL && ALG_VALID(alg)) {
3157 newbie->ipsa_amech.cm_type = alg->alg_mech_type;
3158 newbie->ipsa_amech.cm_param =
3159 (char *)&newbie->ipsa_mac_len;
3160 newbie->ipsa_amech.cm_param_len = sizeof (size_t);
3161 newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
3162 } else {
3163 newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
3164 }
3165 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
3166 mutex_exit(&ipss->ipsec_alg_lock);
3167 if (error != 0) {
3168 mutex_exit(&newbie->ipsa_lock);
3169 /*
3170 * An error here indicates that alg is the wrong type
3171 * (IE: not authentication) or its not in the alg tables
3172 * created by ipsecalgs(1m), or Kcf does not like the
3173 * parameters passed in with this algorithm, which is
3174 * probably a coding error!
3175 */
3176 *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3177
3178 goto error;
3179 }
3180 }
3181
3182 if (ekey != NULL) {
3183 mutex_enter(&ipss->ipsec_alg_lock);
3184 async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
3185 IPSEC_ALGS_EXEC_ASYNC);
3186 alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
3187 [newbie->ipsa_encr_alg];
3188
3189 if (alg != NULL && ALG_VALID(alg)) {
3190 newbie->ipsa_emech.cm_type = alg->alg_mech_type;
3191 newbie->ipsa_datalen = alg->alg_datalen;
3192 if (alg->alg_flags & ALG_FLAG_COUNTERMODE)
3193 newbie->ipsa_flags |= IPSA_F_COUNTERMODE;
3194
3195 if (alg->alg_flags & ALG_FLAG_COMBINED) {
3196 newbie->ipsa_flags |= IPSA_F_COMBINED;
3197 newbie->ipsa_mac_len = alg->alg_icvlen;
3198 }
3199
3200 if (alg->alg_flags & ALG_FLAG_CCM)
3201 newbie->ipsa_noncefunc = ccm_params_init;
3202 else if (alg->alg_flags & ALG_FLAG_GCM)
3203 newbie->ipsa_noncefunc = gcm_params_init;
3204 else newbie->ipsa_noncefunc = cbc_params_init;
3205
3206 newbie->ipsa_saltlen = alg->alg_saltlen;
3207 newbie->ipsa_saltbits = SADB_8TO1(newbie->ipsa_saltlen);
3208 newbie->ipsa_iv_len = alg->alg_ivlen;
3209 newbie->ipsa_nonce_len = newbie->ipsa_saltlen +
3210 newbie->ipsa_iv_len;
3211 newbie->ipsa_emech.cm_param = NULL;
3212 newbie->ipsa_emech.cm_param_len = 0;
3213 } else {
3214 newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
3215 }
3216 mutex_exit(&ipss->ipsec_alg_lock);
3217
3218 /*
3219 * The byte stream following the sadb_key_t is made up of:
3220 * key bytes, [salt bytes], [IV initial value]
3221 * All of these have variable length. The IV is typically
3222 * randomly generated by this function and not passed in.
3223 * By supporting the injection of a known IV, the whole
3224 * IPsec subsystem and the underlying crypto subsystem
3225 * can be tested with known test vectors.
3226 *
3227 * The keying material has been checked by ext_check()
3228 * and ipsec_valid_key_size(), after removing salt/IV
3229 * bits, whats left is the encryption key. If this is too
3230 * short, ipsec_create_ctx_tmpl() will fail and the SA
3231 * won't get created.
3232 *
3233 * set ipsa_encrkeylen to length of key only.
3234 */
3235 newbie->ipsa_encrkeybits = ekey->sadb_key_bits;
3236 newbie->ipsa_encrkeybits -= ekey->sadb_key_reserved;
3237 newbie->ipsa_encrkeybits -= newbie->ipsa_saltbits;
3238 newbie->ipsa_encrkeylen = SADB_1TO8(newbie->ipsa_encrkeybits);
3239
3240 /* In case we have to round up to the next byte... */
3241 if ((ekey->sadb_key_bits & 0x7) != 0)
3242 newbie->ipsa_encrkeylen++;
3243
3244 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
3245 KM_NOSLEEP);
3246 if (newbie->ipsa_encrkey == NULL) {
3247 error = ENOMEM;
3248 mutex_exit(&newbie->ipsa_lock);
3249 goto error;
3250 }
3251
3252 buf_ptr = (uint8_t *)(ekey + 1);
3253 bcopy(buf_ptr, newbie->ipsa_encrkey, newbie->ipsa_encrkeylen);
3254
3255 if (newbie->ipsa_flags & IPSA_F_COMBINED) {
3256 /*
3257 * Combined mode algs need a nonce. Copy the salt and
3258 * IV into a buffer. The ipsa_nonce is a pointer into
3259 * this buffer, some bytes at the start of the buffer
3260 * may be unused, depends on the salt length. The IV
3261 * is 64 bit aligned so it can be incremented as a
3262 * uint64_t. Zero out key in samsg_t before freeing.
3263 */
3264
3265 newbie->ipsa_nonce_buf = kmem_alloc(
3266 sizeof (ipsec_nonce_t), KM_NOSLEEP);
3267 if (newbie->ipsa_nonce_buf == NULL) {
3268 error = ENOMEM;
3269 mutex_exit(&newbie->ipsa_lock);
3270 goto error;
3271 }
3272 /*
3273 * Initialize nonce and salt pointers to point
3274 * to the nonce buffer. This is just in case we get
3275 * bad data, the pointers will be valid, the data
3276 * won't be.
3277 *
3278 * See sadb.h for layout of nonce.
3279 */
3280 newbie->ipsa_iv = &newbie->ipsa_nonce_buf->iv;
3281 newbie->ipsa_salt = (uint8_t *)newbie->ipsa_nonce_buf;
3282 newbie->ipsa_nonce = newbie->ipsa_salt;
3283 if (newbie->ipsa_saltlen != 0) {
3284 salt_offset = MAXSALTSIZE -
3285 newbie->ipsa_saltlen;
3286 newbie->ipsa_salt = (uint8_t *)
3287 &newbie->ipsa_nonce_buf->salt[salt_offset];
3288 newbie->ipsa_nonce = newbie->ipsa_salt;
3289 buf_ptr += newbie->ipsa_encrkeylen;
3290 bcopy(buf_ptr, newbie->ipsa_salt,
3291 newbie->ipsa_saltlen);
3292 }
3293 /*
3294 * The IV for CCM/GCM mode increments, it should not
3295 * repeat. Get a random value for the IV, make a
3296 * copy, the SA will expire when/if the IV ever
3297 * wraps back to the initial value. If an Initial IV
3298 * is passed in via PF_KEY, save this in the SA.
3299 * Initialising IV for inbound is pointless as its
3300 * taken from the inbound packet.
3301 */
3302 if (!is_inbound) {
3303 if (ekey->sadb_key_reserved != 0) {
3304 buf_ptr += newbie->ipsa_saltlen;
3305 bcopy(buf_ptr, (uint8_t *)newbie->
3306 ipsa_iv, SADB_1TO8(ekey->
3307 sadb_key_reserved));
3308 } else {
3309 (void) random_get_pseudo_bytes(
3310 (uint8_t *)newbie->ipsa_iv,
3311 newbie->ipsa_iv_len);
3312 }
3313 newbie->ipsa_iv_softexpire =
3314 (*newbie->ipsa_iv) << 9;
3315 newbie->ipsa_iv_hardexpire = *newbie->ipsa_iv;
3316 }
3317 }
3318 bzero((ekey + 1), SADB_1TO8(ekey->sadb_key_bits));
3319
3320 /*
3321 * Pre-initialize the kernel crypto framework key
3322 * structure.
3323 */
3324 newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
3325 newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
3326 newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
3327
3328 mutex_enter(&ipss->ipsec_alg_lock);
3329 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
3330 mutex_exit(&ipss->ipsec_alg_lock);
3331 if (error != 0) {
3332 mutex_exit(&newbie->ipsa_lock);
3333 /* See above for error explanation. */
3334 *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3335 goto error;
3336 }
3337 }
3338
3339 if (async)
3340 newbie->ipsa_flags |= IPSA_F_ASYNC;
3341
3342 /*
3343 * Ptrs to processing functions.
3344 */
3345 if (newbie->ipsa_type == SADB_SATYPE_ESP)
3346 ipsecesp_init_funcs(newbie);
3347 else
3348 ipsecah_init_funcs(newbie);
3349 ASSERT(newbie->ipsa_output_func != NULL &&
3350 newbie->ipsa_input_func != NULL);
3351
3352 /*
3353 * Certificate ID stuff.
3354 */
3355 if (ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC] != NULL) {
3356 sadb_ident_t *id =
3357 (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
3358
3359 /*
3360 * Can assume strlen() will return okay because ext_check() in
3361 * keysock.c prepares the string for us.
3362 */
3363 newbie->ipsa_src_cid = ipsid_lookup(id->sadb_ident_type,
3364 (char *)(id+1), ns);
3365 if (newbie->ipsa_src_cid == NULL) {
3366 error = ENOMEM;
3367 mutex_exit(&newbie->ipsa_lock);
3368 goto error;
3369 }
3370 }
3371
3372 if (ksi->ks_in_extv[SADB_EXT_IDENTITY_DST] != NULL) {
3373 sadb_ident_t *id =
3374 (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
3375
3376 /*
3377 * Can assume strlen() will return okay because ext_check() in
3378 * keysock.c prepares the string for us.
3379 */
3380 newbie->ipsa_dst_cid = ipsid_lookup(id->sadb_ident_type,
3381 (char *)(id+1), ns);
3382 if (newbie->ipsa_dst_cid == NULL) {
3383 error = ENOMEM;
3384 mutex_exit(&newbie->ipsa_lock);
3385 goto error;
3386 }
3387 }
3388
3389 /*
3390 * sensitivity label handling code:
3391 * Convert sens + bitmap into cred_t, and associate it
3392 * with the new SA.
3393 */
3394 if (sens != NULL) {
3395 uint64_t *bitmap = (uint64_t *)(sens + 1);
3396
3397 newbie->ipsa_tsl = sadb_label_from_sens(sens, bitmap);
3398 }
3399
3400 /*
3401 * Likewise for outer sensitivity.
3402 */
3403 if (osens != NULL) {
3404 uint64_t *bitmap = (uint64_t *)(osens + 1);
3405 ts_label_t *tsl, *effective_tsl;
3406 uint32_t *peer_addr_ptr;
3407 zoneid_t zoneid = GLOBAL_ZONEID;
3408 zone_t *zone;
3409
3410 peer_addr_ptr = is_inbound ? src_addr_ptr : dst_addr_ptr;
3411
3412 tsl = sadb_label_from_sens(osens, bitmap);
3413 newbie->ipsa_mac_exempt = CONN_MAC_DEFAULT;
3414
3415 if (osens->sadb_x_sens_flags & SADB_X_SENS_IMPLICIT) {
3416 newbie->ipsa_mac_exempt = CONN_MAC_IMPLICIT;
3417 }
3418
3419 error = tsol_check_dest(tsl, peer_addr_ptr,
3420 (af == AF_INET6)?IPV6_VERSION:IPV4_VERSION,
3421 newbie->ipsa_mac_exempt, B_TRUE, &effective_tsl);
3422 if (error != 0) {
3423 label_rele(tsl);
3424 mutex_exit(&newbie->ipsa_lock);
3425 goto error;
3426 }
3427
3428 if (effective_tsl != NULL) {
3429 label_rele(tsl);
3430 tsl = effective_tsl;
3431 }
3432
3433 newbie->ipsa_otsl = tsl;
3434
3435 zone = zone_find_by_label(tsl);
3436 if (zone != NULL) {
3437 zoneid = zone->zone_id;
3438 zone_rele(zone);
3439 }
3440 /*
3441 * For exclusive stacks we set the zoneid to zero to operate
3442 * as if in the global zone for tsol_compute_label_v4/v6
3443 */
3444 if (ipst->ips_netstack->netstack_stackid != GLOBAL_NETSTACKID)
3445 zoneid = GLOBAL_ZONEID;
3446
3447 if (af == AF_INET6) {
3448 error = tsol_compute_label_v6(tsl, zoneid,
3449 (in6_addr_t *)peer_addr_ptr,
3450 newbie->ipsa_opt_storage, ipst);
3451 } else {
3452 error = tsol_compute_label_v4(tsl, zoneid,
3453 *peer_addr_ptr, newbie->ipsa_opt_storage, ipst);
3454 }
3455 if (error != 0) {
3456 mutex_exit(&newbie->ipsa_lock);
3457 goto error;
3458 }
3459 }
3460
3461
3462 if (replayext != NULL) {
3463 if ((replayext->sadb_x_rc_replay32 == 0) &&
3464 (replayext->sadb_x_rc_replay64 != 0)) {
3465 error = EOPNOTSUPP;
3466 *diagnostic = SADB_X_DIAGNOSTIC_INVALID_REPLAY;
3467 mutex_exit(&newbie->ipsa_lock);
3468 goto error;
3469 }
3470 newbie->ipsa_replay = replayext->sadb_x_rc_replay32;
3471 }
3472
3473 /* now that the SA has been updated, set its new state */
3474 newbie->ipsa_state = assoc->sadb_sa_state;
3475
3476 if (clone) {
3477 newbie->ipsa_haspeer = B_TRUE;
3478 } else {
3479 if (!is_inbound) {
3480 lifetime_fuzz(newbie);
3481 }
3482 }
3483 /*
3484 * The less locks I hold when doing an insertion and possible cloning,
3485 * the better!
3486 */
3487 mutex_exit(&newbie->ipsa_lock);
3488
3489 if (clone) {
3490 newbie_clone = sadb_cloneassoc(newbie);
3491
3492 if (newbie_clone == NULL) {
3493 error = ENOMEM;
3494 goto error;
3495 }
3496 }
3497
3498 /*
3499 * Enter the bucket locks. The order of entry is outbound,
3500 * inbound. We map "primary" and "secondary" into outbound and inbound
3501 * based on the destination address type. If the destination address
3502 * type is for a node that isn't mine (or potentially mine), the
3503 * "primary" bucket is the outbound one.
3504 */
3505 if (!is_inbound) {
3506 /* primary == outbound */
3507 mutex_enter(&primary->isaf_lock);
3508 mutex_enter(&secondary->isaf_lock);
3509 } else {
3510 /* primary == inbound */
3511 mutex_enter(&secondary->isaf_lock);
3512 mutex_enter(&primary->isaf_lock);
3513 }
3514
3515 /*
3516 * sadb_insertassoc() doesn't increment the reference
3517 * count. We therefore have to increment the
3518 * reference count one more time to reflect the
3519 * pointers of the table that reference this SA.
3520 */
3521 IPSA_REFHOLD(newbie);
3522
3523 if (isupdate) {
3524 /*
3525 * Unlink from larval holding cell in the "inbound" fanout.
3526 */
3527 ASSERT(newbie->ipsa_linklock == &primary->isaf_lock ||
3528 newbie->ipsa_linklock == &secondary->isaf_lock);
3529 sadb_unlinkassoc(newbie);
3530 }
3531
3532 mutex_enter(&newbie->ipsa_lock);
3533 error = sadb_insertassoc(newbie, primary);
3534 mutex_exit(&newbie->ipsa_lock);
3535
3536 if (error != 0) {
3537 /*
3538 * Since sadb_insertassoc() failed, we must decrement the
3539 * refcount again so the cleanup code will actually free
3540 * the offending SA.
3541 */
3542 IPSA_REFRELE(newbie);
3543 goto error_unlock;
3544 }
3545
3546 if (newbie_clone != NULL) {
3547 mutex_enter(&newbie_clone->ipsa_lock);
3548 error = sadb_insertassoc(newbie_clone, secondary);
3549 mutex_exit(&newbie_clone->ipsa_lock);
3550 if (error != 0) {
3551 /* Collision in secondary table. */
3552 sadb_unlinkassoc(newbie); /* This does REFRELE. */
3553 goto error_unlock;
3554 }
3555 IPSA_REFHOLD(newbie_clone);
3556 } else {
3557 ASSERT(primary != secondary);
3558 scratch = ipsec_getassocbyspi(secondary, newbie->ipsa_spi,
3559 ALL_ZEROES_PTR, newbie->ipsa_dstaddr, af);
3560 if (scratch != NULL) {
3561 /* Collision in secondary table. */
3562 sadb_unlinkassoc(newbie); /* This does REFRELE. */
3563 /* Set the error, since ipsec_getassocbyspi() can't. */
3564 error = EEXIST;
3565 goto error_unlock;
3566 }
3567 }
3568
3569 /* OKAY! So let's do some reality check assertions. */
3570
3571 ASSERT(MUTEX_NOT_HELD(&newbie->ipsa_lock));
3572 ASSERT(newbie_clone == NULL ||
3573 (MUTEX_NOT_HELD(&newbie_clone->ipsa_lock)));
3574
3575 error_unlock:
3576
3577 /*
3578 * We can exit the locks in any order. Only entrance needs to
3579 * follow any protocol.
3580 */
3581 mutex_exit(&secondary->isaf_lock);
3582 mutex_exit(&primary->isaf_lock);
3583
3584 if (pair_ext != NULL && error == 0) {
3585 /* update pair_spi if it exists. */
3586 ipsa_query_t sq;
3587
3588 sq.spp = spp; /* XXX param */
3589 error = sadb_form_query(ksi, IPSA_Q_DST, IPSA_Q_SRC|IPSA_Q_DST|
3590 IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND, &sq, diagnostic);
3591 if (error)
3592 return (error);
3593
3594 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
3595
3596 if (error != 0)
3597 goto error;
3598
3599 if (ipsapp.ipsap_psa_ptr != NULL) {
3600 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
3601 error = EINVAL;
3602 } else {
3603 /* update_pairing() sets diagnostic */
3604 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
3605 }
3606 }
3607 /* Common error point for this routine. */
3608 error:
3609 if (newbie != NULL) {
3610 if (error != 0) {
3611 /* This SA is broken, let the reaper clean up. */
3612 mutex_enter(&newbie->ipsa_lock);
3613 newbie->ipsa_state = IPSA_STATE_DEAD;
3614 newbie->ipsa_hardexpiretime = 1;
3615 mutex_exit(&newbie->ipsa_lock);
3616 }
3617 IPSA_REFRELE(newbie);
3618 }
3619 if (newbie_clone != NULL) {
3620 IPSA_REFRELE(newbie_clone);
3621 }
3622
3623 if (error == 0) {
3624 /*
3625 * Construct favorable PF_KEY return message and send to
3626 * keysock. Update the flags in the original keysock message
3627 * to reflect the actual flags in the new SA.
3628 * (Q: Do I need to pass "newbie"? If I do,
3629 * make sure to REFHOLD, call, then REFRELE.)
3630 */
3631 assoc->sadb_sa_flags = newbie->ipsa_flags;
3632 sadb_pfkey_echo(pfkey_q, mp, samsg, ksi, NULL);
3633 }
3634
3635 destroy_ipsa_pair(&ipsapp);
3636 return (error);
3637 }
3638
3639 /*
3640 * Set the time of first use for a security association. Update any
3641 * expiration times as a result.
3642 */
3643 void
3644 sadb_set_usetime(ipsa_t *assoc)
3645 {
3646 time_t snapshot = gethrestime_sec();
3647
3648 mutex_enter(&assoc->ipsa_lock);
3649 assoc->ipsa_lastuse = snapshot;
3650 assoc->ipsa_idleexpiretime = snapshot + assoc->ipsa_idletime;
3651
3652 /*
3653 * Caller does check usetime before calling me usually, and
3654 * double-checking is better than a mutex_enter/exit hit.
3655 */
3656 if (assoc->ipsa_usetime == 0) {
3657 /*
3658 * This is redundant for outbound SA's, as
3659 * ipsec_getassocbyconn() sets the IPSA_F_USED flag already.
3660 * Inbound SAs, however, have no such protection.
3661 */
3662 assoc->ipsa_flags |= IPSA_F_USED;
3663 assoc->ipsa_usetime = snapshot;
3664
3665 /*
3666 * After setting the use time, see if we have a use lifetime
3667 * that would cause the actual SA expiration time to shorten.
3668 */
3669 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
3670 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
3671 }
3672 mutex_exit(&assoc->ipsa_lock);
3673 }
3674
3675 /*
3676 * Send up a PF_KEY expire message for this association.
3677 */
3678 static void
3679 sadb_expire_assoc(queue_t *pfkey_q, ipsa_t *assoc)
3680 {
3681 mblk_t *mp, *mp1;
3682 int alloclen, af;
3683 sadb_msg_t *samsg;
3684 sadb_lifetime_t *current, *expire;
3685 sadb_sa_t *saext;
3686 uint8_t *end;
3687 boolean_t tunnel_mode;
3688
3689 ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3690
3691 /* Don't bother sending if there's no queue. */
3692 if (pfkey_q == NULL)
3693 return;
3694
3695 mp = sadb_keysock_out(0);
3696 if (mp == NULL) {
3697 /* cmn_err(CE_WARN, */
3698 /* "sadb_expire_assoc: Can't allocate KEYSOCK_OUT.\n"); */
3699 return;
3700 }
3701
3702 alloclen = sizeof (*samsg) + sizeof (*current) + sizeof (*expire) +
3703 2 * sizeof (sadb_address_t) + sizeof (*saext);
3704
3705 af = assoc->ipsa_addrfam;
3706 switch (af) {
3707 case AF_INET:
3708 alloclen += 2 * sizeof (struct sockaddr_in);
3709 break;
3710 case AF_INET6:
3711 alloclen += 2 * sizeof (struct sockaddr_in6);
3712 break;
3713 default:
3714 /* Won't happen unless there's a kernel bug. */
3715 freeb(mp);
3716 cmn_err(CE_WARN,
3717 "sadb_expire_assoc: Unknown address length.\n");
3718 return;
3719 }
3720
3721 tunnel_mode = (assoc->ipsa_flags & IPSA_F_TUNNEL);
3722 if (tunnel_mode) {
3723 alloclen += 2 * sizeof (sadb_address_t);
3724 switch (assoc->ipsa_innerfam) {
3725 case AF_INET:
3726 alloclen += 2 * sizeof (struct sockaddr_in);
3727 break;
3728 case AF_INET6:
3729 alloclen += 2 * sizeof (struct sockaddr_in6);
3730 break;
3731 default:
3732 /* Won't happen unless there's a kernel bug. */
3733 freeb(mp);
3734 cmn_err(CE_WARN, "sadb_expire_assoc: "
3735 "Unknown inner address length.\n");
3736 return;
3737 }
3738 }
3739
3740 mp->b_cont = allocb(alloclen, BPRI_HI);
3741 if (mp->b_cont == NULL) {
3742 freeb(mp);
3743 /* cmn_err(CE_WARN, */
3744 /* "sadb_expire_assoc: Can't allocate message.\n"); */
3745 return;
3746 }
3747
3748 mp1 = mp;
3749 mp = mp->b_cont;
3750 end = mp->b_wptr + alloclen;
3751
3752 samsg = (sadb_msg_t *)mp->b_wptr;
3753 mp->b_wptr += sizeof (*samsg);
3754 samsg->sadb_msg_version = PF_KEY_V2;
3755 samsg->sadb_msg_type = SADB_EXPIRE;
3756 samsg->sadb_msg_errno = 0;
3757 samsg->sadb_msg_satype = assoc->ipsa_type;
3758 samsg->sadb_msg_len = SADB_8TO64(alloclen);
3759 samsg->sadb_msg_reserved = 0;
3760 samsg->sadb_msg_seq = 0;
3761 samsg->sadb_msg_pid = 0;
3762
3763 saext = (sadb_sa_t *)mp->b_wptr;
3764 mp->b_wptr += sizeof (*saext);
3765 saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
3766 saext->sadb_sa_exttype = SADB_EXT_SA;
3767 saext->sadb_sa_spi = assoc->ipsa_spi;
3768 saext->sadb_sa_replay = assoc->ipsa_replay_wsize;
3769 saext->sadb_sa_state = assoc->ipsa_state;
3770 saext->sadb_sa_auth = assoc->ipsa_auth_alg;
3771 saext->sadb_sa_encrypt = assoc->ipsa_encr_alg;
3772 saext->sadb_sa_flags = assoc->ipsa_flags;
3773
3774 current = (sadb_lifetime_t *)mp->b_wptr;
3775 mp->b_wptr += sizeof (sadb_lifetime_t);
3776 current->sadb_lifetime_len = SADB_8TO64(sizeof (*current));
3777 current->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
3778 /* We do not support the concept. */
3779 current->sadb_lifetime_allocations = 0;
3780 current->sadb_lifetime_bytes = assoc->ipsa_bytes;
3781 current->sadb_lifetime_addtime = assoc->ipsa_addtime;
3782 current->sadb_lifetime_usetime = assoc->ipsa_usetime;
3783
3784 expire = (sadb_lifetime_t *)mp->b_wptr;
3785 mp->b_wptr += sizeof (*expire);
3786 expire->sadb_lifetime_len = SADB_8TO64(sizeof (*expire));
3787
3788 if (assoc->ipsa_state == IPSA_STATE_DEAD) {
3789 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
3790 expire->sadb_lifetime_allocations = assoc->ipsa_hardalloc;
3791 expire->sadb_lifetime_bytes = assoc->ipsa_hardbyteslt;
3792 expire->sadb_lifetime_addtime = assoc->ipsa_hardaddlt;
3793 expire->sadb_lifetime_usetime = assoc->ipsa_harduselt;
3794 } else if (assoc->ipsa_state == IPSA_STATE_DYING) {
3795 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
3796 expire->sadb_lifetime_allocations = assoc->ipsa_softalloc;
3797 expire->sadb_lifetime_bytes = assoc->ipsa_softbyteslt;
3798 expire->sadb_lifetime_addtime = assoc->ipsa_softaddlt;
3799 expire->sadb_lifetime_usetime = assoc->ipsa_softuselt;
3800 } else {
3801 ASSERT(assoc->ipsa_state == IPSA_STATE_MATURE);
3802 expire->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
3803 expire->sadb_lifetime_allocations = 0;
3804 expire->sadb_lifetime_bytes = 0;
3805 expire->sadb_lifetime_addtime = assoc->ipsa_idleaddlt;
3806 expire->sadb_lifetime_usetime = assoc->ipsa_idleuselt;
3807 }
3808
3809 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_SRC,
3810 af, assoc->ipsa_srcaddr, tunnel_mode ? 0 : SA_SRCPORT(assoc),
3811 SA_PROTO(assoc), 0);
3812 ASSERT(mp->b_wptr != NULL);
3813
3814 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_DST,
3815 af, assoc->ipsa_dstaddr, tunnel_mode ? 0 : SA_DSTPORT(assoc),
3816 SA_PROTO(assoc), 0);
3817 ASSERT(mp->b_wptr != NULL);
3818
3819 if (tunnel_mode) {
3820 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
3821 SADB_X_EXT_ADDRESS_INNER_SRC, assoc->ipsa_innerfam,
3822 assoc->ipsa_innersrc, SA_SRCPORT(assoc), SA_IPROTO(assoc),
3823 assoc->ipsa_innersrcpfx);
3824 ASSERT(mp->b_wptr != NULL);
3825 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
3826 SADB_X_EXT_ADDRESS_INNER_DST, assoc->ipsa_innerfam,
3827 assoc->ipsa_innerdst, SA_DSTPORT(assoc), SA_IPROTO(assoc),
3828 assoc->ipsa_innerdstpfx);
3829 ASSERT(mp->b_wptr != NULL);
3830 }
3831
3832 /* Can just putnext, we're ready to go! */
3833 putnext(pfkey_q, mp1);
3834 }
3835
3836 /*
3837 * "Age" the SA with the number of bytes that was used to protect traffic.
3838 * Send an SADB_EXPIRE message if appropriate. Return B_TRUE if there was
3839 * enough "charge" left in the SA to protect the data. Return B_FALSE
3840 * otherwise. (If B_FALSE is returned, the association either was, or became
3841 * DEAD.)
3842 */
3843 boolean_t
3844 sadb_age_bytes(queue_t *pfkey_q, ipsa_t *assoc, uint64_t bytes,
3845 boolean_t sendmsg)
3846 {
3847 boolean_t rc = B_TRUE;
3848 uint64_t newtotal;
3849
3850 mutex_enter(&assoc->ipsa_lock);
3851 newtotal = assoc->ipsa_bytes + bytes;
3852 if (assoc->ipsa_hardbyteslt != 0 &&
3853 newtotal >= assoc->ipsa_hardbyteslt) {
3854 if (assoc->ipsa_state != IPSA_STATE_DEAD) {
3855 /*
3856 * Send EXPIRE message to PF_KEY. May wish to pawn
3857 * this off on another non-interrupt thread. Also
3858 * unlink this SA immediately.
3859 */
3860 assoc->ipsa_state = IPSA_STATE_DEAD;
3861 if (sendmsg)
3862 sadb_expire_assoc(pfkey_q, assoc);
3863 /*
3864 * Set non-zero expiration time so sadb_age_assoc()
3865 * will work when reaping.
3866 */
3867 assoc->ipsa_hardexpiretime = (time_t)1;
3868 } /* Else someone beat me to it! */
3869 rc = B_FALSE;
3870 } else if (assoc->ipsa_softbyteslt != 0 &&
3871 (newtotal >= assoc->ipsa_softbyteslt)) {
3872 if (assoc->ipsa_state < IPSA_STATE_DYING) {
3873 /*
3874 * Send EXPIRE message to PF_KEY. May wish to pawn
3875 * this off on another non-interrupt thread.
3876 */
3877 assoc->ipsa_state = IPSA_STATE_DYING;
3878 assoc->ipsa_bytes = newtotal;
3879 if (sendmsg)
3880 sadb_expire_assoc(pfkey_q, assoc);
3881 } /* Else someone beat me to it! */
3882 }
3883 if (rc == B_TRUE)
3884 assoc->ipsa_bytes = newtotal;
3885 mutex_exit(&assoc->ipsa_lock);
3886 return (rc);
3887 }
3888
3889 /*
3890 * "Torch" an individual SA. Returns NULL, so it can be tail-called from
3891 * sadb_age_assoc().
3892 */
3893 static ipsa_t *
3894 sadb_torch_assoc(isaf_t *head, ipsa_t *sa)
3895 {
3896 ASSERT(MUTEX_HELD(&head->isaf_lock));
3897 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
3898 ASSERT(sa->ipsa_state == IPSA_STATE_DEAD);
3899
3900 /*
3901 * Force cached SAs to be revalidated..
3902 */
3903 head->isaf_gen++;
3904
3905 mutex_exit(&sa->ipsa_lock);
3906 sadb_unlinkassoc(sa);
3907
3908 return (NULL);
3909 }
3910
3911 /*
3912 * Do various SA-is-idle activities depending on delta (the number of idle
3913 * seconds on the SA) and/or other properties of the SA.
3914 *
3915 * Return B_TRUE if I've sent a packet, because I have to drop the
3916 * association's mutex before sending a packet out the wire.
3917 */
3918 /* ARGSUSED */
3919 static boolean_t
3920 sadb_idle_activities(ipsa_t *assoc, time_t delta, boolean_t inbound)
3921 {
3922 ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
3923 int nat_t_interval = espstack->ipsecesp_nat_keepalive_interval;
3924
3925 ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3926
3927 if (!inbound && (assoc->ipsa_flags & IPSA_F_NATT_LOC) &&
3928 delta >= nat_t_interval &&
3929 gethrestime_sec() - assoc->ipsa_last_nat_t_ka >= nat_t_interval) {
3930 ASSERT(assoc->ipsa_type == SADB_SATYPE_ESP);
3931 assoc->ipsa_last_nat_t_ka = gethrestime_sec();
3932 mutex_exit(&assoc->ipsa_lock);
3933 ipsecesp_send_keepalive(assoc);
3934 return (B_TRUE);
3935 }
3936 return (B_FALSE);
3937 }
3938
3939 /*
3940 * Return "assoc" if haspeer is true and I send an expire. This allows
3941 * the consumers' aging functions to tidy up an expired SA's peer.
3942 */
3943 static ipsa_t *
3944 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
3945 time_t current, int reap_delay, boolean_t inbound)
3946 {
3947 ipsa_t *retval = NULL;
3948 boolean_t dropped_mutex = B_FALSE;
3949
3950 ASSERT(MUTEX_HELD(&head->isaf_lock));
3951
3952 mutex_enter(&assoc->ipsa_lock);
3953
3954 if (((assoc->ipsa_state == IPSA_STATE_LARVAL) ||
3955 ((assoc->ipsa_state == IPSA_STATE_IDLE) ||
3956 (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) &&
3957 (assoc->ipsa_hardexpiretime != 0))) &&
3958 (assoc->ipsa_hardexpiretime <= current)) {
3959 assoc->ipsa_state = IPSA_STATE_DEAD;
3960 return (sadb_torch_assoc(head, assoc));
3961 }
3962
3963 /*
3964 * Check lifetimes. Fortunately, SA setup is done
3965 * such that there are only two times to look at,
3966 * softexpiretime, and hardexpiretime.
3967 *
3968 * Check hard first.
3969 */
3970
3971 if (assoc->ipsa_hardexpiretime != 0 &&
3972 assoc->ipsa_hardexpiretime <= current) {
3973 if (assoc->ipsa_state == IPSA_STATE_DEAD)
3974 return (sadb_torch_assoc(head, assoc));
3975
3976 /*
3977 * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
3978 */
3979 assoc->ipsa_state = IPSA_STATE_DEAD;
3980 if (assoc->ipsa_haspeer || assoc->ipsa_otherspi != 0) {
3981 /*
3982 * If the SA is paired or peered with another, put
3983 * a copy on a list which can be processed later, the
3984 * pair/peer SA needs to be updated so the both die
3985 * at the same time.
3986 *
3987 * If I return assoc, I have to bump up its reference
3988 * count to keep with the ipsa_t reference count
3989 * semantics.
3990 */
3991 IPSA_REFHOLD(assoc);
3992 retval = assoc;
3993 }
3994 sadb_expire_assoc(pfkey_q, assoc);
3995 assoc->ipsa_hardexpiretime = current + reap_delay;
3996 } else if (assoc->ipsa_softexpiretime != 0 &&
3997 assoc->ipsa_softexpiretime <= current &&
3998 assoc->ipsa_state < IPSA_STATE_DYING) {
3999 /*
4000 * Send EXPIRE message to PF_KEY. May wish to pawn
4001 * this off on another non-interrupt thread.
4002 */
4003 assoc->ipsa_state = IPSA_STATE_DYING;
4004 if (assoc->ipsa_haspeer) {
4005 /*
4006 * If the SA has a peer, update the peer's state
4007 * on SOFT_EXPIRE, this is mostly to prevent two
4008 * expire messages from effectively the same SA.
4009 *
4010 * Don't care about paired SA's, then can (and should)
4011 * be able to soft expire at different times.
4012 *
4013 * If I return assoc, I have to bump up its
4014 * reference count to keep with the ipsa_t reference
4015 * count semantics.
4016 */
4017 IPSA_REFHOLD(assoc);
4018 retval = assoc;
4019 }
4020 sadb_expire_assoc(pfkey_q, assoc);
4021 } else if (assoc->ipsa_idletime != 0 &&
4022 assoc->ipsa_idleexpiretime <= current) {
4023 if (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) {
4024 assoc->ipsa_state = IPSA_STATE_IDLE;
4025 }
4026
4027 /*
4028 * Need to handle Mature case
4029 */
4030 if (assoc->ipsa_state == IPSA_STATE_MATURE) {
4031 sadb_expire_assoc(pfkey_q, assoc);
4032 }
4033 } else {
4034 /* Check idle time activities. */
4035 dropped_mutex = sadb_idle_activities(assoc,
4036 current - assoc->ipsa_lastuse, inbound);
4037 }
4038
4039 if (!dropped_mutex)
4040 mutex_exit(&assoc->ipsa_lock);
4041 return (retval);
4042 }
4043
4044 /*
4045 * Called by a consumer protocol to do ther dirty work of reaping dead
4046 * Security Associations.
4047 *
4048 * NOTE: sadb_age_assoc() marks expired SA's as DEAD but only removed
4049 * SA's that are already marked DEAD, so expired SA's are only reaped
4050 * the second time sadb_ager() runs.
4051 */
4052 void
4053 sadb_ager(sadb_t *sp, queue_t *pfkey_q, int reap_delay, netstack_t *ns)
4054 {
4055 int i;
4056 isaf_t *bucket;
4057 ipsa_t *assoc, *spare;
4058 iacqf_t *acqlist;
4059 ipsacq_t *acqrec, *spareacq;
4060 templist_t *haspeerlist, *newbie;
4061 /* Snapshot current time now. */
4062 time_t current = gethrestime_sec();
4063 haspeerlist = NULL;
4064
4065 /*
4066 * Do my dirty work. This includes aging real entries, aging
4067 * larvals, and aging outstanding ACQUIREs.
4068 *
4069 * I hope I don't tie up resources for too long.
4070 */
4071
4072 /* Age acquires. */
4073
4074 for (i = 0; i < sp->sdb_hashsize; i++) {
4075 acqlist = &sp->sdb_acq[i];
4076 mutex_enter(&acqlist->iacqf_lock);
4077 for (acqrec = acqlist->iacqf_ipsacq; acqrec != NULL;
4078 acqrec = spareacq) {
4079 spareacq = acqrec->ipsacq_next;
4080 if (current > acqrec->ipsacq_expire)
4081 sadb_destroy_acquire(acqrec, ns);
4082 }
4083 mutex_exit(&acqlist->iacqf_lock);
4084 }
4085
4086 /* Age inbound associations. */
4087 for (i = 0; i < sp->sdb_hashsize; i++) {
4088 bucket = &(sp->sdb_if[i]);
4089 mutex_enter(&bucket->isaf_lock);
4090 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4091 assoc = spare) {
4092 spare = assoc->ipsa_next;
4093 if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4094 reap_delay, B_TRUE) != NULL) {
4095 /*
4096 * Put SA's which have a peer or SA's which
4097 * are paired on a list for processing after
4098 * all the hash tables have been walked.
4099 *
4100 * sadb_age_assoc() increments the refcnt,
4101 * effectively doing an IPSA_REFHOLD().
4102 */
4103 newbie = kmem_alloc(sizeof (*newbie),
4104 KM_NOSLEEP);
4105 if (newbie == NULL) {
4106 /*
4107 * Don't forget to REFRELE().
4108 */
4109 IPSA_REFRELE(assoc);
4110 continue; /* for loop... */
4111 }
4112 newbie->next = haspeerlist;
4113 newbie->ipsa = assoc;
4114 haspeerlist = newbie;
4115 }
4116 }
4117 mutex_exit(&bucket->isaf_lock);
4118 }
4119
4120 age_pair_peer_list(haspeerlist, sp, B_FALSE);
4121 haspeerlist = NULL;
4122
4123 /* Age outbound associations. */
4124 for (i = 0; i < sp->sdb_hashsize; i++) {
4125 bucket = &(sp->sdb_of[i]);
4126 mutex_enter(&bucket->isaf_lock);
4127 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4128 assoc = spare) {
4129 spare = assoc->ipsa_next;
4130 if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4131 reap_delay, B_FALSE) != NULL) {
4132 /*
4133 * sadb_age_assoc() increments the refcnt,
4134 * effectively doing an IPSA_REFHOLD().
4135 */
4136 newbie = kmem_alloc(sizeof (*newbie),
4137 KM_NOSLEEP);
4138 if (newbie == NULL) {
4139 /*
4140 * Don't forget to REFRELE().
4141 */
4142 IPSA_REFRELE(assoc);
4143 continue; /* for loop... */
4144 }
4145 newbie->next = haspeerlist;
4146 newbie->ipsa = assoc;
4147 haspeerlist = newbie;
4148 }
4149 }
4150 mutex_exit(&bucket->isaf_lock);
4151 }
4152
4153 age_pair_peer_list(haspeerlist, sp, B_TRUE);
4154
4155 /*
4156 * Run a GC pass to clean out dead identities.
4157 */
4158 ipsid_gc(ns);
4159 }
4160
4161 /*
4162 * Figure out when to reschedule the ager.
4163 */
4164 timeout_id_t
4165 sadb_retimeout(hrtime_t begin, queue_t *pfkey_q, void (*ager)(void *),
4166 void *agerarg, uint_t *intp, uint_t intmax, short mid)
4167 {
4168 hrtime_t end = gethrtime();
4169 uint_t interval = *intp; /* "interval" is in ms. */
4170
4171 /*
4172 * See how long this took. If it took too long, increase the
4173 * aging interval.
4174 */
4175 if ((end - begin) > MSEC2NSEC(interval)) {
4176 if (interval >= intmax) {
4177 /* XXX Rate limit this? Or recommend flush? */
4178 (void) strlog(mid, 0, 0, SL_ERROR | SL_WARN,
4179 "Too many SA's to age out in %d msec.\n",
4180 intmax);
4181 } else {
4182 /* Double by shifting by one bit. */
4183 interval <<= 1;
4184 interval = min(interval, intmax);
4185 }
4186 } else if ((end - begin) <= (MSEC2NSEC(interval) / 2) &&
4187 interval > SADB_AGE_INTERVAL_DEFAULT) {
4188 /*
4189 * If I took less than half of the interval, then I should
4190 * ratchet the interval back down. Never automatically
4191 * shift below the default aging interval.
4192 *
4193 * NOTE:This even overrides manual setting of the age
4194 * interval using NDD to lower the setting past the
4195 * default. In other words, if you set the interval
4196 * lower than the default, and your SADB gets too big,
4197 * the interval will only self-lower back to the default.
4198 */
4199 /* Halve by shifting one bit. */
4200 interval >>= 1;
4201 interval = max(interval, SADB_AGE_INTERVAL_DEFAULT);
4202 }
4203 *intp = interval;
4204 return (qtimeout(pfkey_q, ager, agerarg,
4205 drv_usectohz(interval * (MICROSEC / MILLISEC))));
4206 }
4207
4208
4209 /*
4210 * Update the lifetime values of an SA. This is the path an SADB_UPDATE
4211 * message takes when updating a MATURE or DYING SA.
4212 */
4213 static void
4214 sadb_update_lifetimes(ipsa_t *assoc, sadb_lifetime_t *hard,
4215 sadb_lifetime_t *soft, sadb_lifetime_t *idle, boolean_t outbound)
4216 {
4217 mutex_enter(&assoc->ipsa_lock);
4218
4219 /*
4220 * XXX RFC 2367 mentions how an SADB_EXT_LIFETIME_CURRENT can be
4221 * passed in during an update message. We currently don't handle
4222 * these.
4223 */
4224
4225 if (hard != NULL) {
4226 if (hard->sadb_lifetime_bytes != 0)
4227 assoc->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
4228 if (hard->sadb_lifetime_usetime != 0)
4229 assoc->ipsa_harduselt = hard->sadb_lifetime_usetime;
4230 if (hard->sadb_lifetime_addtime != 0)
4231 assoc->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
4232 if (assoc->ipsa_hardaddlt != 0) {
4233 assoc->ipsa_hardexpiretime =
4234 assoc->ipsa_addtime + assoc->ipsa_hardaddlt;
4235 }
4236 if (assoc->ipsa_harduselt != 0 &&
4237 assoc->ipsa_flags & IPSA_F_USED) {
4238 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
4239 }
4240 if (hard->sadb_lifetime_allocations != 0)
4241 assoc->ipsa_hardalloc = hard->sadb_lifetime_allocations;
4242 }
4243
4244 if (soft != NULL) {
4245 if (soft->sadb_lifetime_bytes != 0) {
4246 if (soft->sadb_lifetime_bytes >
4247 assoc->ipsa_hardbyteslt) {
4248 assoc->ipsa_softbyteslt =
4249 assoc->ipsa_hardbyteslt;
4250 } else {
4251 assoc->ipsa_softbyteslt =
4252 soft->sadb_lifetime_bytes;
4253 }
4254 }
4255 if (soft->sadb_lifetime_usetime != 0) {
4256 if (soft->sadb_lifetime_usetime >
4257 assoc->ipsa_harduselt) {
4258 assoc->ipsa_softuselt =
4259 assoc->ipsa_harduselt;
4260 } else {
4261 assoc->ipsa_softuselt =
4262 soft->sadb_lifetime_usetime;
4263 }
4264 }
4265 if (soft->sadb_lifetime_addtime != 0) {
4266 if (soft->sadb_lifetime_addtime >
4267 assoc->ipsa_hardexpiretime) {
4268 assoc->ipsa_softexpiretime =
4269 assoc->ipsa_hardexpiretime;
4270 } else {
4271 assoc->ipsa_softaddlt =
4272 soft->sadb_lifetime_addtime;
4273 }
4274 }
4275 if (assoc->ipsa_softaddlt != 0) {
4276 assoc->ipsa_softexpiretime =
4277 assoc->ipsa_addtime + assoc->ipsa_softaddlt;
4278 }
4279 if (assoc->ipsa_softuselt != 0 &&
4280 assoc->ipsa_flags & IPSA_F_USED) {
4281 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
4282 }
4283 if (outbound && assoc->ipsa_softexpiretime != 0) {
4284 if (assoc->ipsa_state == IPSA_STATE_MATURE)
4285 lifetime_fuzz(assoc);
4286 }
4287
4288 if (soft->sadb_lifetime_allocations != 0)
4289 assoc->ipsa_softalloc = soft->sadb_lifetime_allocations;
4290 }
4291
4292 if (idle != NULL) {
4293 time_t current = gethrestime_sec();
4294 if ((assoc->ipsa_idleexpiretime <= current) &&
4295 (assoc->ipsa_idleaddlt == idle->sadb_lifetime_addtime)) {
4296 assoc->ipsa_idleexpiretime =
4297 current + assoc->ipsa_idleaddlt;
4298 }
4299 if (idle->sadb_lifetime_addtime != 0)
4300 assoc->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
4301 if (idle->sadb_lifetime_usetime != 0)
4302 assoc->ipsa_idleuselt = idle->sadb_lifetime_usetime;
4303 if (assoc->ipsa_idleaddlt != 0) {
4304 assoc->ipsa_idleexpiretime =
4305 current + idle->sadb_lifetime_addtime;
4306 assoc->ipsa_idletime = idle->sadb_lifetime_addtime;
4307 }
4308 if (assoc->ipsa_idleuselt != 0) {
4309 if (assoc->ipsa_idletime != 0) {
4310 assoc->ipsa_idletime = min(assoc->ipsa_idletime,
4311 assoc->ipsa_idleuselt);
4312 assoc->ipsa_idleexpiretime =
4313 current + assoc->ipsa_idletime;
4314 } else {
4315 assoc->ipsa_idleexpiretime =
4316 current + assoc->ipsa_idleuselt;
4317 assoc->ipsa_idletime = assoc->ipsa_idleuselt;
4318 }
4319 }
4320 }
4321 mutex_exit(&assoc->ipsa_lock);
4322 }
4323
4324 static int
4325 sadb_update_state(ipsa_t *assoc, uint_t new_state, mblk_t **ipkt_lst)
4326 {
4327 int rcode = 0;
4328 time_t current = gethrestime_sec();
4329
4330 mutex_enter(&assoc->ipsa_lock);
4331
4332 switch (new_state) {
4333 case SADB_X_SASTATE_ACTIVE_ELSEWHERE:
4334 if (assoc->ipsa_state == SADB_X_SASTATE_IDLE) {
4335 assoc->ipsa_state = IPSA_STATE_ACTIVE_ELSEWHERE;
4336 assoc->ipsa_idleexpiretime =
4337 current + assoc->ipsa_idletime;
4338 }
4339 break;
4340 case SADB_X_SASTATE_IDLE:
4341 if (assoc->ipsa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4342 assoc->ipsa_state = IPSA_STATE_IDLE;
4343 assoc->ipsa_idleexpiretime =
4344 current + assoc->ipsa_idletime;
4345 } else {
4346 rcode = EINVAL;
4347 }
4348 break;
4349
4350 case SADB_X_SASTATE_ACTIVE:
4351 if (assoc->ipsa_state != SADB_X_SASTATE_IDLE) {
4352 rcode = EINVAL;
4353 break;
4354 }
4355 assoc->ipsa_state = IPSA_STATE_MATURE;
4356 assoc->ipsa_idleexpiretime = current + assoc->ipsa_idletime;
4357
4358 if (ipkt_lst == NULL) {
4359 break;
4360 }
4361
4362 if (assoc->ipsa_bpkt_head != NULL) {
4363 *ipkt_lst = assoc->ipsa_bpkt_head;
4364 assoc->ipsa_bpkt_head = assoc->ipsa_bpkt_tail = NULL;
4365 assoc->ipsa_mblkcnt = 0;
4366 } else {
4367 *ipkt_lst = NULL;
4368 }
4369 break;
4370 default:
4371 rcode = EINVAL;
4372 break;
4373 }
4374
4375 mutex_exit(&assoc->ipsa_lock);
4376 return (rcode);
4377 }
4378
4379 /*
4380 * Check a proposed KMC update for sanity.
4381 */
4382 static int
4383 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
4384 {
4385 uint32_t kmp = sq->kmp;
4386 uint32_t kmc = sq->kmc;
4387
4388 if (sa == NULL)
4389 return (0);
4390
4391 if (sa->ipsa_state == IPSA_STATE_DEAD)
4392 return (ESRCH); /* DEAD == Not there, in this case. */
4393
4394 if ((kmp != 0) && ((sa->ipsa_kmp != 0) || (sa->ipsa_kmp != kmp))) {
4395 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
4396 return (EINVAL);
4397 }
4398
4399 if ((kmc != 0) && ((sa->ipsa_kmc != 0) || (sa->ipsa_kmc != kmc))) {
4400 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
4401 return (EINVAL);
4402 }
4403
4404 return (0);
4405 }
4406
4407 /*
4408 * Actually update the KMC info.
4409 */
4410 static void
4411 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
4412 {
4413 uint32_t kmp = sq->kmp;
4414 uint32_t kmc = sq->kmc;
4415
4416 if (kmp != 0)
4417 sa->ipsa_kmp = kmp;
4418 if (kmc != 0)
4419 sa->ipsa_kmc = kmc;
4420 }
4421
4422 /*
4423 * Common code to update an SA.
4424 */
4425
4426 int
4427 sadb_update_sa(mblk_t *mp, keysock_in_t *ksi, mblk_t **ipkt_lst,
4428 sadbp_t *spp, int *diagnostic, queue_t *pfkey_q,
4429 int (*add_sa_func)(mblk_t *, keysock_in_t *, int *, netstack_t *),
4430 netstack_t *ns, uint8_t sadb_msg_type)
4431 {
4432 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
4433 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
4434 sadb_x_replay_ctr_t *replext =
4435 (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
4436 sadb_lifetime_t *soft =
4437 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
4438 sadb_lifetime_t *hard =
4439 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
4440 sadb_lifetime_t *idle =
4441 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
4442 sadb_x_pair_t *pair_ext =
4443 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4444 ipsa_t *echo_target = NULL;
4445 ipsap_t ipsapp;
4446 ipsa_query_t sq;
4447 time_t current = gethrestime_sec();
4448
4449 sq.spp = spp; /* XXX param */
4450 int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
4451 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
4452 &sq, diagnostic);
4453
4454 if (error != 0)
4455 return (error);
4456
4457 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
4458 if (error != 0)
4459 return (error);
4460
4461 if (ipsapp.ipsap_psa_ptr == NULL && ipsapp.ipsap_sa_ptr != NULL) {
4462 if (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) {
4463 /*
4464 * REFRELE the target and let the add_sa_func()
4465 * deal with updating a larval SA.
4466 */
4467 destroy_ipsa_pair(&ipsapp);
4468 return (add_sa_func(mp, ksi, diagnostic, ns));
4469 }
4470 }
4471
4472 /*
4473 * At this point we have an UPDATE to a MATURE SA. There should
4474 * not be any keying material present.
4475 */
4476 if (akey != NULL) {
4477 *diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
4478 error = EINVAL;
4479 goto bail;
4480 }
4481 if (ekey != NULL) {
4482 *diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
4483 error = EINVAL;
4484 goto bail;
4485 }
4486
4487 if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4488 if (ipsapp.ipsap_sa_ptr != NULL &&
4489 ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4490 if ((error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4491 sq.assoc->sadb_sa_state, NULL)) != 0) {
4492 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4493 goto bail;
4494 }
4495 }
4496 if (ipsapp.ipsap_psa_ptr != NULL &&
4497 ipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4498 if ((error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4499 sq.assoc->sadb_sa_state, NULL)) != 0) {
4500 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4501 goto bail;
4502 }
4503 }
4504 }
4505 if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE) {
4506 if (ipsapp.ipsap_sa_ptr != NULL) {
4507 error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4508 sq.assoc->sadb_sa_state,
4509 (ipsapp.ipsap_sa_ptr->ipsa_flags &
4510 IPSA_F_INBOUND) ? ipkt_lst : NULL);
4511 if (error) {
4512 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4513 goto bail;
4514 }
4515 }
4516 if (ipsapp.ipsap_psa_ptr != NULL) {
4517 error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4518 sq.assoc->sadb_sa_state,
4519 (ipsapp.ipsap_psa_ptr->ipsa_flags &
4520 IPSA_F_INBOUND) ? ipkt_lst : NULL);
4521 if (error) {
4522 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4523 goto bail;
4524 }
4525 }
4526 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4527 ksi, echo_target);
4528 goto bail;
4529 }
4530
4531 /*
4532 * Reality checks for updates of active associations.
4533 * Sundry first-pass UPDATE-specific reality checks.
4534 * Have to do the checks here, because it's after the add_sa code.
4535 * XXX STATS : logging/stats here?
4536 */
4537
4538 if (!((sq.assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
4539 (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE))) {
4540 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4541 error = EINVAL;
4542 goto bail;
4543 }
4544 if (sq.assoc->sadb_sa_flags & ~spp->s_updateflags) {
4545 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
4546 error = EINVAL;
4547 goto bail;
4548 }
4549 if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
4550 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_LIFETIME;
4551 error = EOPNOTSUPP;
4552 goto bail;
4553 }
4554
4555 if ((*diagnostic = sadb_hardsoftchk(hard, soft, idle)) != 0) {
4556 error = EINVAL;
4557 goto bail;
4558 }
4559
4560 if ((*diagnostic = sadb_labelchk(ksi)) != 0)
4561 return (EINVAL);
4562
4563 error = sadb_check_kmc(&sq, ipsapp.ipsap_sa_ptr, diagnostic);
4564 if (error != 0)
4565 goto bail;
4566
4567 error = sadb_check_kmc(&sq, ipsapp.ipsap_psa_ptr, diagnostic);
4568 if (error != 0)
4569 goto bail;
4570
4571
4572 if (ipsapp.ipsap_sa_ptr != NULL) {
4573 /*
4574 * Do not allow replay value change for MATURE or LARVAL SA.
4575 */
4576
4577 if ((replext != NULL) &&
4578 ((ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) ||
4579 (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_MATURE))) {
4580 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4581 error = EINVAL;
4582 goto bail;
4583 }
4584 }
4585
4586
4587 if (ipsapp.ipsap_sa_ptr != NULL) {
4588 sadb_update_lifetimes(ipsapp.ipsap_sa_ptr, hard, soft,
4589 idle, B_TRUE);
4590 sadb_update_kmc(&sq, ipsapp.ipsap_sa_ptr);
4591 if ((replext != NULL) &&
4592 (ipsapp.ipsap_sa_ptr->ipsa_replay_wsize != 0)) {
4593 /*
4594 * If an inbound SA, update the replay counter
4595 * and check off all the other sequence number
4596 */
4597 if (ksi->ks_in_dsttype == KS_IN_ADDR_ME) {
4598 if (!sadb_replay_check(ipsapp.ipsap_sa_ptr,
4599 replext->sadb_x_rc_replay32)) {
4600 *diagnostic =
4601 SADB_X_DIAGNOSTIC_INVALID_REPLAY;
4602 error = EINVAL;
4603 goto bail;
4604 }
4605 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4606 ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4607 current +
4608 ipsapp.ipsap_sa_ptr->ipsa_idletime;
4609 mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4610 } else {
4611 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4612 ipsapp.ipsap_sa_ptr->ipsa_replay =
4613 replext->sadb_x_rc_replay32;
4614 ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4615 current +
4616 ipsapp.ipsap_sa_ptr->ipsa_idletime;
4617 mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4618 }
4619 }
4620 }
4621
4622 if (sadb_msg_type == SADB_X_UPDATEPAIR) {
4623 if (ipsapp.ipsap_psa_ptr != NULL) {
4624 sadb_update_lifetimes(ipsapp.ipsap_psa_ptr, hard, soft,
4625 idle, B_FALSE);
4626 sadb_update_kmc(&sq, ipsapp.ipsap_psa_ptr);
4627 } else {
4628 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
4629 error = ESRCH;
4630 goto bail;
4631 }
4632 }
4633
4634 if (pair_ext != NULL)
4635 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
4636
4637 if (error == 0)
4638 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4639 ksi, echo_target);
4640 bail:
4641
4642 destroy_ipsa_pair(&ipsapp);
4643
4644 return (error);
4645 }
4646
4647
4648 static int
4649 update_pairing(ipsap_t *ipsapp, ipsa_query_t *sq, keysock_in_t *ksi,
4650 int *diagnostic)
4651 {
4652 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
4653 sadb_x_pair_t *pair_ext =
4654 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4655 int error = 0;
4656 ipsap_t oipsapp;
4657 boolean_t undo_pair = B_FALSE;
4658 uint32_t ipsa_flags;
4659
4660 if (pair_ext->sadb_x_pair_spi == 0 || pair_ext->sadb_x_pair_spi ==
4661 assoc->sadb_sa_spi) {
4662 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4663 return (EINVAL);
4664 }
4665
4666 /*
4667 * Assume for now that the spi value provided in the SADB_UPDATE
4668 * message was valid, update the SA with its pair spi value.
4669 * If the spi turns out to be bogus or the SA no longer exists
4670 * then this will be detected when the reverse update is made
4671 * below.
4672 */
4673 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4674 ipsapp->ipsap_sa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4675 ipsapp->ipsap_sa_ptr->ipsa_otherspi = pair_ext->sadb_x_pair_spi;
4676 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4677
4678 /*
4679 * After updating the ipsa_otherspi element of the SA, get_ipsa_pair()
4680 * should now return pointers to the SA *AND* its pair, if this is not
4681 * the case, the "otherspi" either did not exist or was deleted. Also
4682 * check that "otherspi" is not already paired. If everything looks
4683 * good, complete the update. IPSA_REFRELE the first pair_pointer
4684 * after this update to ensure its not deleted until we are done.
4685 */
4686 error = get_ipsa_pair(sq, &oipsapp, diagnostic);
4687 if (error != 0) {
4688 /*
4689 * This should never happen, calling function still has
4690 * IPSA_REFHELD on the SA we just updated.
4691 */
4692 return (error); /* XXX EINVAL instead of ESRCH? */
4693 }
4694
4695 if (oipsapp.ipsap_psa_ptr == NULL) {
4696 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4697 error = EINVAL;
4698 undo_pair = B_TRUE;
4699 } else {
4700 ipsa_flags = oipsapp.ipsap_psa_ptr->ipsa_flags;
4701 if ((oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DEAD) ||
4702 (oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DYING)) {
4703 /* Its dead Jim! */
4704 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4705 undo_pair = B_TRUE;
4706 } else if ((ipsa_flags & (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) ==
4707 (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) {
4708 /* This SA is in both hashtables. */
4709 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4710 undo_pair = B_TRUE;
4711 } else if (ipsa_flags & IPSA_F_PAIRED) {
4712 /* This SA is already paired with another. */
4713 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
4714 undo_pair = B_TRUE;
4715 }
4716 }
4717
4718 if (undo_pair) {
4719 /* The pair SA does not exist. */
4720 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4721 ipsapp->ipsap_sa_ptr->ipsa_flags &= ~IPSA_F_PAIRED;
4722 ipsapp->ipsap_sa_ptr->ipsa_otherspi = 0;
4723 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4724 } else {
4725 mutex_enter(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4726 oipsapp.ipsap_psa_ptr->ipsa_otherspi = assoc->sadb_sa_spi;
4727 oipsapp.ipsap_psa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4728 mutex_exit(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4729 }
4730
4731 destroy_ipsa_pair(&oipsapp);
4732 return (error);
4733 }
4734
4735 /*
4736 * The following functions deal with ACQUIRE LISTS. An ACQUIRE list is
4737 * a list of outstanding SADB_ACQUIRE messages. If ipsec_getassocbyconn() fails
4738 * for an outbound datagram, that datagram is queued up on an ACQUIRE record,
4739 * and an SADB_ACQUIRE message is sent up. Presumably, a user-space key
4740 * management daemon will process the ACQUIRE, use a SADB_GETSPI to reserve
4741 * an SPI value and a larval SA, then SADB_UPDATE the larval SA, and ADD the
4742 * other direction's SA.
4743 */
4744
4745 /*
4746 * Check the ACQUIRE lists. If there's an existing ACQUIRE record,
4747 * grab it, lock it, and return it. Otherwise return NULL.
4748 *
4749 * XXX MLS number of arguments getting unwieldy here
4750 */
4751 static ipsacq_t *
4752 sadb_checkacquire(iacqf_t *bucket, ipsec_action_t *ap, ipsec_policy_t *pp,
4753 uint32_t *src, uint32_t *dst, uint32_t *isrc, uint32_t *idst,
4754 uint64_t unique_id, ts_label_t *tsl)
4755 {
4756 ipsacq_t *walker;
4757 sa_family_t fam;
4758 uint32_t blank_address[4] = {0, 0, 0, 0};
4759
4760 if (isrc == NULL) {
4761 ASSERT(idst == NULL);
4762 isrc = idst = blank_address;
4763 }
4764
4765 /*
4766 * Scan list for duplicates. Check for UNIQUE, src/dest, policy.
4767 *
4768 * XXX May need search for duplicates based on other things too!
4769 */
4770 for (walker = bucket->iacqf_ipsacq; walker != NULL;
4771 walker = walker->ipsacq_next) {
4772 mutex_enter(&walker->ipsacq_lock);
4773 fam = walker->ipsacq_addrfam;
4774 if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
4775 IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
4776 ip_addr_match((uint8_t *)isrc, walker->ipsacq_innersrcpfx,
4777 (in6_addr_t *)walker->ipsacq_innersrc) &&
4778 ip_addr_match((uint8_t *)idst, walker->ipsacq_innerdstpfx,
4779 (in6_addr_t *)walker->ipsacq_innerdst) &&
4780 (ap == walker->ipsacq_act) &&
4781 (pp == walker->ipsacq_policy) &&
4782 /* XXX do deep compares of ap/pp? */
4783 (unique_id == walker->ipsacq_unique_id) &&
4784 (ipsec_label_match(tsl, walker->ipsacq_tsl)))
4785 break; /* everything matched */
4786 mutex_exit(&walker->ipsacq_lock);
4787 }
4788
4789 return (walker);
4790 }
4791
4792 /*
4793 * For this mblk, insert a new acquire record. Assume bucket contains addrs
4794 * of all of the same length. Give up (and drop) if memory
4795 * cannot be allocated for a new one; otherwise, invoke callback to
4796 * send the acquire up..
4797 *
4798 * In cases where we need both AH and ESP, add the SA to the ESP ACQUIRE
4799 * list. The ah_add_sa_finish() routines can look at the packet's attached
4800 * attributes and handle this case specially.
4801 */
4802 void
4803 sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah,
4804 boolean_t need_esp)
4805 {
4806 mblk_t *asyncmp;
4807 sadbp_t *spp;
4808 sadb_t *sp;
4809 ipsacq_t *newbie;
4810 iacqf_t *bucket;
4811 mblk_t *extended;
4812 ipha_t *ipha = (ipha_t *)datamp->b_rptr;
4813 ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
4814 uint32_t *src, *dst, *isrc, *idst;
4815 ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
4816 ipsec_action_t *ap = ixa->ixa_ipsec_action;
4817 sa_family_t af;
4818 int hashoffset;
4819 uint32_t seq;
4820 uint64_t unique_id = 0;
4821 ipsec_selector_t sel;
4822 boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0;
4823 ts_label_t *tsl = NULL;
4824 netstack_t *ns = ixa->ixa_ipst->ips_netstack;
4825 ipsec_stack_t *ipss = ns->netstack_ipsec;
4826 sadb_sens_t *sens = NULL;
4827 int sens_len;
4828
4829 ASSERT((pp != NULL) || (ap != NULL));
4830
4831 ASSERT(need_ah != NULL || need_esp != NULL);
4832
4833 /* Assign sadb pointers */
4834 if (need_esp) { /* ESP for AH+ESP */
4835 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
4836
4837 spp = &espstack->esp_sadb;
4838 } else {
4839 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
4840
4841 spp = &ahstack->ah_sadb;
4842 }
4843 sp = (ixa->ixa_flags & IXAF_IS_IPV4) ? &spp->s_v4 : &spp->s_v6;
4844
4845 if (is_system_labeled())
4846 tsl = ixa->ixa_tsl;
4847
4848 if (ap == NULL)
4849 ap = pp->ipsp_act;
4850
4851 ASSERT(ap != NULL);
4852
4853 if (ap->ipa_act.ipa_apply.ipp_use_unique || tunnel_mode)
4854 unique_id = SA_FORM_UNIQUE_ID(ixa);
4855
4856 /*
4857 * Set up an ACQUIRE record.
4858 *
4859 * Immediately, make sure the ACQUIRE sequence number doesn't slip
4860 * below the lowest point allowed in the kernel. (In other words,
4861 * make sure the high bit on the sequence number is set.)
4862 */
4863
4864 seq = keysock_next_seq(ns) | IACQF_LOWEST_SEQ;
4865
4866 if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
4867 src = (uint32_t *)&ipha->ipha_src;
4868 dst = (uint32_t *)&ipha->ipha_dst;
4869 af = AF_INET;
4870 hashoffset = OUTBOUND_HASH_V4(sp, ipha->ipha_dst);
4871 ASSERT(ixa->ixa_flags & IXAF_IS_IPV4);
4872 } else {
4873 ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
4874 src = (uint32_t *)&ip6h->ip6_src;
4875 dst = (uint32_t *)&ip6h->ip6_dst;
4876 af = AF_INET6;
4877 hashoffset = OUTBOUND_HASH_V6(sp, ip6h->ip6_dst);
4878 ASSERT(!(ixa->ixa_flags & IXAF_IS_IPV4));
4879 }
4880
4881 if (tunnel_mode) {
4882 if (pp == NULL) {
4883 /*
4884 * Tunnel mode with no policy pointer means this is a
4885 * reflected ICMP (like a ECHO REQUEST) that came in
4886 * with self-encapsulated protection. Until we better
4887 * support this, drop the packet.
4888 */
4889 ip_drop_packet(datamp, B_FALSE, NULL,
4890 DROPPER(ipss, ipds_spd_got_selfencap),
4891 &ipss->ipsec_spd_dropper);
4892 return;
4893 }
4894 /* Snag inner addresses. */
4895 isrc = ixa->ixa_ipsec_insrc;
4896 idst = ixa->ixa_ipsec_indst;
4897 } else {
4898 isrc = idst = NULL;
4899 }
4900
4901 /*
4902 * Check buckets to see if there is an existing entry. If so,
4903 * grab it. sadb_checkacquire locks newbie if found.
4904 */
4905 bucket = &(sp->sdb_acq[hashoffset]);
4906 mutex_enter(&bucket->iacqf_lock);
4907 newbie = sadb_checkacquire(bucket, ap, pp, src, dst, isrc, idst,
4908 unique_id, tsl);
4909
4910 if (newbie == NULL) {
4911 /*
4912 * Otherwise, allocate a new one.
4913 */
4914 newbie = kmem_zalloc(sizeof (*newbie), KM_NOSLEEP);
4915 if (newbie == NULL) {
4916 mutex_exit(&bucket->iacqf_lock);
4917 ip_drop_packet(datamp, B_FALSE, NULL,
4918 DROPPER(ipss, ipds_sadb_acquire_nomem),
4919 &ipss->ipsec_sadb_dropper);
4920 return;
4921 }
4922 newbie->ipsacq_policy = pp;
4923 if (pp != NULL) {
4924 IPPOL_REFHOLD(pp);
4925 }
4926 IPACT_REFHOLD(ap);
4927 newbie->ipsacq_act = ap;
4928 newbie->ipsacq_linklock = &bucket->iacqf_lock;
4929 newbie->ipsacq_next = bucket->iacqf_ipsacq;
4930 newbie->ipsacq_ptpn = &bucket->iacqf_ipsacq;
4931 if (newbie->ipsacq_next != NULL)
4932 newbie->ipsacq_next->ipsacq_ptpn = &newbie->ipsacq_next;
4933
4934 bucket->iacqf_ipsacq = newbie;
4935 mutex_init(&newbie->ipsacq_lock, NULL, MUTEX_DEFAULT, NULL);
4936 mutex_enter(&newbie->ipsacq_lock);
4937 }
4938
4939 /*
4940 * XXX MLS does it actually help us to drop the bucket lock here?
4941 * we have inserted a half-built, locked acquire record into the
4942 * bucket. any competing thread will now be able to lock the bucket
4943 * to scan it, but will immediately pile up on the new acquire
4944 * record's lock; I don't think we gain anything here other than to
4945 * disperse blame for lock contention.
4946 *
4947 * we might be able to dispense with acquire record locks entirely..
4948 * just use the bucket locks..
4949 */
4950
4951 mutex_exit(&bucket->iacqf_lock);
4952
4953 /*
4954 * This assert looks silly for now, but we may need to enter newbie's
4955 * mutex during a search.
4956 */
4957 ASSERT(MUTEX_HELD(&newbie->ipsacq_lock));
4958
4959 /*
4960 * Make the ip_xmit_attr_t into something we can queue.
4961 * If no memory it frees datamp.
4962 */
4963 asyncmp = ip_xmit_attr_to_mblk(ixa);
4964 if (asyncmp != NULL)
4965 linkb(asyncmp, datamp);
4966
4967 /* Queue up packet. Use b_next. */
4968
4969 if (asyncmp == NULL) {
4970 /* Statistics for allocation failure */
4971 if (ixa->ixa_flags & IXAF_IS_IPV4) {
4972 BUMP_MIB(&ixa->ixa_ipst->ips_ip_mib,
4973 ipIfStatsOutDiscards);
4974 } else {
4975 BUMP_MIB(&ixa->ixa_ipst->ips_ip6_mib,
4976 ipIfStatsOutDiscards);
4977 }
4978 ip_drop_output("No memory for asyncmp", datamp, NULL);
4979 freemsg(datamp);
4980 } else if (newbie->ipsacq_numpackets == 0) {
4981 /* First one. */
4982 newbie->ipsacq_mp = asyncmp;
4983 newbie->ipsacq_numpackets = 1;
4984 newbie->ipsacq_expire = gethrestime_sec();
4985 /*
4986 * Extended ACQUIRE with both AH+ESP will use ESP's timeout
4987 * value.
4988 */
4989 newbie->ipsacq_expire += *spp->s_acquire_timeout;
4990 newbie->ipsacq_seq = seq;
4991 newbie->ipsacq_addrfam = af;
4992
4993 newbie->ipsacq_srcport = ixa->ixa_ipsec_src_port;
4994 newbie->ipsacq_dstport = ixa->ixa_ipsec_dst_port;
4995 newbie->ipsacq_icmp_type = ixa->ixa_ipsec_icmp_type;
4996 newbie->ipsacq_icmp_code = ixa->ixa_ipsec_icmp_code;
4997 if (tunnel_mode) {
4998 newbie->ipsacq_inneraddrfam = ixa->ixa_ipsec_inaf;
4999 newbie->ipsacq_proto = ixa->ixa_ipsec_inaf == AF_INET6 ?
5000 IPPROTO_IPV6 : IPPROTO_ENCAP;
5001 newbie->ipsacq_innersrcpfx = ixa->ixa_ipsec_insrcpfx;
5002 newbie->ipsacq_innerdstpfx = ixa->ixa_ipsec_indstpfx;
5003 IPSA_COPY_ADDR(newbie->ipsacq_innersrc,
5004 ixa->ixa_ipsec_insrc, ixa->ixa_ipsec_inaf);
5005 IPSA_COPY_ADDR(newbie->ipsacq_innerdst,
5006 ixa->ixa_ipsec_indst, ixa->ixa_ipsec_inaf);
5007 } else {
5008 newbie->ipsacq_proto = ixa->ixa_ipsec_proto;
5009 }
5010 newbie->ipsacq_unique_id = unique_id;
5011
5012 if (ixa->ixa_tsl != NULL) {
5013 label_hold(ixa->ixa_tsl);
5014 newbie->ipsacq_tsl = ixa->ixa_tsl;
5015 }
5016 } else {
5017 /* Scan to the end of the list & insert. */
5018 mblk_t *lastone = newbie->ipsacq_mp;
5019
5020 while (lastone->b_next != NULL)
5021 lastone = lastone->b_next;
5022 lastone->b_next = asyncmp;
5023 if (newbie->ipsacq_numpackets++ == ipsacq_maxpackets) {
5024 newbie->ipsacq_numpackets = ipsacq_maxpackets;
5025 lastone = newbie->ipsacq_mp;
5026 newbie->ipsacq_mp = lastone->b_next;
5027 lastone->b_next = NULL;
5028
5029 /* Freeing the async message */
5030 lastone = ip_xmit_attr_free_mblk(lastone);
5031 ip_drop_packet(lastone, B_FALSE, NULL,
5032 DROPPER(ipss, ipds_sadb_acquire_toofull),
5033 &ipss->ipsec_sadb_dropper);
5034 } else {
5035 IP_ACQUIRE_STAT(ipss, qhiwater,
5036 newbie->ipsacq_numpackets);
5037 }
5038 }
5039
5040 /*
5041 * Reset addresses. Set them to the most recently added mblk chain,
5042 * so that the address pointers in the acquire record will point
5043 * at an mblk still attached to the acquire list.
5044 */
5045
5046 newbie->ipsacq_srcaddr = src;
5047 newbie->ipsacq_dstaddr = dst;
5048
5049 /*
5050 * If the acquire record has more than one queued packet, we've
5051 * already sent an ACQUIRE, and don't need to repeat ourself.
5052 */
5053 if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1) {
5054 /* I have an acquire outstanding already! */
5055 mutex_exit(&newbie->ipsacq_lock);
5056 return;
5057 }
5058
5059 if (!keysock_extended_reg(ns))
5060 goto punt_extended;
5061 /*
5062 * Construct an extended ACQUIRE. There are logging
5063 * opportunities here in failure cases.
5064 */
5065 bzero(&sel, sizeof (sel));
5066 sel.ips_isv4 = (ixa->ixa_flags & IXAF_IS_IPV4) != 0;
5067 if (tunnel_mode) {
5068 sel.ips_protocol = (ixa->ixa_ipsec_inaf == AF_INET) ?
5069 IPPROTO_ENCAP : IPPROTO_IPV6;
5070 } else {
5071 sel.ips_protocol = ixa->ixa_ipsec_proto;
5072 sel.ips_local_port = ixa->ixa_ipsec_src_port;
5073 sel.ips_remote_port = ixa->ixa_ipsec_dst_port;
5074 }
5075 sel.ips_icmp_type = ixa->ixa_ipsec_icmp_type;
5076 sel.ips_icmp_code = ixa->ixa_ipsec_icmp_code;
5077 sel.ips_is_icmp_inv_acq = 0;
5078 if (af == AF_INET) {
5079 sel.ips_local_addr_v4 = ipha->ipha_src;
5080 sel.ips_remote_addr_v4 = ipha->ipha_dst;
5081 } else {
5082 sel.ips_local_addr_v6 = ip6h->ip6_src;
5083 sel.ips_remote_addr_v6 = ip6h->ip6_dst;
5084 }
5085
5086 extended = sadb_keysock_out(0);
5087 if (extended == NULL)
5088 goto punt_extended;
5089
5090 if (ixa->ixa_tsl != NULL) {
5091 /*
5092 * XXX MLS correct condition here?
5093 * XXX MLS other credential attributes in acquire?
5094 * XXX malloc failure? don't fall back to original?
5095 */
5096 sens = sadb_make_sens_ext(ixa->ixa_tsl, &sens_len);
5097
5098 if (sens == NULL) {
5099 freeb(extended);
5100 goto punt_extended;
5101 }
5102 }
5103
5104 extended->b_cont = sadb_extended_acquire(&sel, pp, ap, tunnel_mode,
5105 seq, 0, sens, ns);
5106
5107 if (sens != NULL)
5108 kmem_free(sens, sens_len);
5109
5110 if (extended->b_cont == NULL) {
5111 freeb(extended);
5112 goto punt_extended;
5113 }
5114
5115 /*
5116 * Send an ACQUIRE message (and possible an extended ACQUIRE) based on
5117 * this new record. The send-acquire callback assumes that acqrec is
5118 * already locked.
5119 */
5120 (*spp->s_acqfn)(newbie, extended, ns);
5121 return;
5122
5123 punt_extended:
5124 (*spp->s_acqfn)(newbie, NULL, ns);
5125 }
5126
5127 /*
5128 * Unlink and free an acquire record.
5129 */
5130 void
5131 sadb_destroy_acquire(ipsacq_t *acqrec, netstack_t *ns)
5132 {
5133 mblk_t *mp;
5134 ipsec_stack_t *ipss = ns->netstack_ipsec;
5135
5136 ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
5137
5138 if (acqrec->ipsacq_policy != NULL) {
5139 IPPOL_REFRELE(acqrec->ipsacq_policy);
5140 }
5141 if (acqrec->ipsacq_act != NULL) {
5142 IPACT_REFRELE(acqrec->ipsacq_act);
5143 }
5144
5145 /* Unlink */
5146 *(acqrec->ipsacq_ptpn) = acqrec->ipsacq_next;
5147 if (acqrec->ipsacq_next != NULL)
5148 acqrec->ipsacq_next->ipsacq_ptpn = acqrec->ipsacq_ptpn;
5149
5150 if (acqrec->ipsacq_tsl != NULL) {
5151 label_rele(acqrec->ipsacq_tsl);
5152 acqrec->ipsacq_tsl = NULL;
5153 }
5154
5155 /*
5156 * Free hanging mp's.
5157 *
5158 * XXX Instead of freemsg(), perhaps use IPSEC_REQ_FAILED.
5159 */
5160
5161 mutex_enter(&acqrec->ipsacq_lock);
5162 while (acqrec->ipsacq_mp != NULL) {
5163 mp = acqrec->ipsacq_mp;
5164 acqrec->ipsacq_mp = mp->b_next;
5165 mp->b_next = NULL;
5166 /* Freeing the async message */
5167 mp = ip_xmit_attr_free_mblk(mp);
5168 ip_drop_packet(mp, B_FALSE, NULL,
5169 DROPPER(ipss, ipds_sadb_acquire_timeout),
5170 &ipss->ipsec_sadb_dropper);
5171 }
5172 mutex_exit(&acqrec->ipsacq_lock);
5173
5174 /* Free */
5175 mutex_destroy(&acqrec->ipsacq_lock);
5176 kmem_free(acqrec, sizeof (*acqrec));
5177 }
5178
5179 /*
5180 * Destroy an acquire list fanout.
5181 */
5182 static void
5183 sadb_destroy_acqlist(iacqf_t **listp, uint_t numentries, boolean_t forever,
5184 netstack_t *ns)
5185 {
5186 int i;
5187 iacqf_t *list = *listp;
5188
5189 if (list == NULL)
5190 return;
5191
5192 for (i = 0; i < numentries; i++) {
5193 mutex_enter(&(list[i].iacqf_lock));
5194 while (list[i].iacqf_ipsacq != NULL)
5195 sadb_destroy_acquire(list[i].iacqf_ipsacq, ns);
5196 mutex_exit(&(list[i].iacqf_lock));
5197 if (forever)
5198 mutex_destroy(&(list[i].iacqf_lock));
5199 }
5200
5201 if (forever) {
5202 *listp = NULL;
5203 kmem_free(list, numentries * sizeof (*list));
5204 }
5205 }
5206
5207 /*
5208 * Create an algorithm descriptor for an extended ACQUIRE. Filter crypto
5209 * framework's view of reality vs. IPsec's. EF's wins, BTW.
5210 */
5211 static uint8_t *
5212 sadb_new_algdesc(uint8_t *start, uint8_t *limit,
5213 sadb_x_ecomb_t *ecomb, uint8_t satype, uint8_t algtype,
5214 uint8_t alg, uint16_t minbits, uint16_t maxbits, ipsec_stack_t *ipss)
5215 {
5216 uint8_t *cur = start;
5217 ipsec_alginfo_t *algp;
5218 sadb_x_algdesc_t *algdesc = (sadb_x_algdesc_t *)cur;
5219
5220 cur += sizeof (*algdesc);
5221 if (cur >= limit)
5222 return (NULL);
5223
5224 ecomb->sadb_x_ecomb_numalgs++;
5225
5226 /*
5227 * Normalize vs. crypto framework's limits. This way, you can specify
5228 * a stronger policy, and when the framework loads a stronger version,
5229 * you can just keep plowing w/o rewhacking your SPD.
5230 */
5231 mutex_enter(&ipss->ipsec_alg_lock);
5232 algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
5233 IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
5234 if (algp == NULL) {
5235 mutex_exit(&ipss->ipsec_alg_lock);
5236 return (NULL); /* Algorithm doesn't exist. Fail gracefully. */
5237 }
5238 if (minbits < algp->alg_ef_minbits)
5239 minbits = algp->alg_ef_minbits;
5240 if (maxbits > algp->alg_ef_maxbits)
5241 maxbits = algp->alg_ef_maxbits;
5242 mutex_exit(&ipss->ipsec_alg_lock);
5243
5244 algdesc->sadb_x_algdesc_reserved = SADB_8TO1(algp->alg_saltlen);
5245 algdesc->sadb_x_algdesc_satype = satype;
5246 algdesc->sadb_x_algdesc_algtype = algtype;
5247 algdesc->sadb_x_algdesc_alg = alg;
5248 algdesc->sadb_x_algdesc_minbits = minbits;
5249 algdesc->sadb_x_algdesc_maxbits = maxbits;
5250
5251 return (cur);
5252 }
5253
5254 /*
5255 * Convert the given ipsec_action_t into an ecomb starting at *ecomb
5256 * which must fit before *limit
5257 *
5258 * return NULL if we ran out of room or a pointer to the end of the ecomb.
5259 */
5260 static uint8_t *
5261 sadb_action_to_ecomb(uint8_t *start, uint8_t *limit, ipsec_action_t *act,
5262 netstack_t *ns)
5263 {
5264 uint8_t *cur = start;
5265 sadb_x_ecomb_t *ecomb = (sadb_x_ecomb_t *)cur;
5266 ipsec_prot_t *ipp;
5267 ipsec_stack_t *ipss = ns->netstack_ipsec;
5268
5269 cur += sizeof (*ecomb);
5270 if (cur >= limit)
5271 return (NULL);
5272
5273 ASSERT(act->ipa_act.ipa_type == IPSEC_ACT_APPLY);
5274
5275 ipp = &act->ipa_act.ipa_apply;
5276
5277 ecomb->sadb_x_ecomb_numalgs = 0;
5278 ecomb->sadb_x_ecomb_reserved = 0;
5279 ecomb->sadb_x_ecomb_reserved2 = 0;
5280 /*
5281 * No limits on allocations, since we really don't support that
5282 * concept currently.
5283 */
5284 ecomb->sadb_x_ecomb_soft_allocations = 0;
5285 ecomb->sadb_x_ecomb_hard_allocations = 0;
5286
5287 /*
5288 * XXX TBD: Policy or global parameters will eventually be
5289 * able to fill in some of these.
5290 */
5291 ecomb->sadb_x_ecomb_flags = 0;
5292 ecomb->sadb_x_ecomb_soft_bytes = 0;
5293 ecomb->sadb_x_ecomb_hard_bytes = 0;
5294 ecomb->sadb_x_ecomb_soft_addtime = 0;
5295 ecomb->sadb_x_ecomb_hard_addtime = 0;
5296 ecomb->sadb_x_ecomb_soft_usetime = 0;
5297 ecomb->sadb_x_ecomb_hard_usetime = 0;
5298
5299 if (ipp->ipp_use_ah) {
5300 cur = sadb_new_algdesc(cur, limit, ecomb,
5301 SADB_SATYPE_AH, SADB_X_ALGTYPE_AUTH, ipp->ipp_auth_alg,
5302 ipp->ipp_ah_minbits, ipp->ipp_ah_maxbits, ipss);
5303 if (cur == NULL)
5304 return (NULL);
5305 ipsecah_fill_defs(ecomb, ns);
5306 }
5307
5308 if (ipp->ipp_use_esp) {
5309 if (ipp->ipp_use_espa) {
5310 cur = sadb_new_algdesc(cur, limit, ecomb,
5311 SADB_SATYPE_ESP, SADB_X_ALGTYPE_AUTH,
5312 ipp->ipp_esp_auth_alg,
5313 ipp->ipp_espa_minbits,
5314 ipp->ipp_espa_maxbits, ipss);
5315 if (cur == NULL)
5316 return (NULL);
5317 }
5318
5319 cur = sadb_new_algdesc(cur, limit, ecomb,
5320 SADB_SATYPE_ESP, SADB_X_ALGTYPE_CRYPT,
5321 ipp->ipp_encr_alg,
5322 ipp->ipp_espe_minbits,
5323 ipp->ipp_espe_maxbits, ipss);
5324 if (cur == NULL)
5325 return (NULL);
5326 /* Fill in lifetimes if and only if AH didn't already... */
5327 if (!ipp->ipp_use_ah)
5328 ipsecesp_fill_defs(ecomb, ns);
5329 }
5330
5331 return (cur);
5332 }
5333
5334 #include <sys/tsol/label_macro.h> /* XXX should not need this */
5335
5336 /*
5337 * From a cred_t, construct a sensitivity label extension
5338 *
5339 * We send up a fixed-size sensitivity label bitmap, and are perhaps
5340 * overly chummy with the underlying data structures here.
5341 */
5342
5343 /* ARGSUSED */
5344 int
5345 sadb_sens_len_from_label(ts_label_t *tsl)
5346 {
5347 int baselen = sizeof (sadb_sens_t) + _C_LEN * 4;
5348 return (roundup(baselen, sizeof (uint64_t)));
5349 }
5350
5351 void
5352 sadb_sens_from_label(sadb_sens_t *sens, int exttype, ts_label_t *tsl,
5353 int senslen)
5354 {
5355 uint8_t *bitmap;
5356 bslabel_t *sl;
5357
5358 /* LINTED */
5359 ASSERT((_C_LEN & 1) == 0);
5360 ASSERT((senslen & 7) == 0);
5361
5362 sl = label2bslabel(tsl);
5363
5364 sens->sadb_sens_exttype = exttype;
5365 sens->sadb_sens_len = SADB_8TO64(senslen);
5366
5367 sens->sadb_sens_dpd = tsl->tsl_doi;
5368 sens->sadb_sens_sens_level = LCLASS(sl);
5369 sens->sadb_sens_integ_level = 0; /* TBD */
5370 sens->sadb_sens_sens_len = _C_LEN >> 1;
5371 sens->sadb_sens_integ_len = 0; /* TBD */
5372 sens->sadb_x_sens_flags = 0;
5373
5374 bitmap = (uint8_t *)(sens + 1);
5375 bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
5376 }
5377
5378 static sadb_sens_t *
5379 sadb_make_sens_ext(ts_label_t *tsl, int *len)
5380 {
5381 /* XXX allocation failure? */
5382 int sens_len = sadb_sens_len_from_label(tsl);
5383
5384 sadb_sens_t *sens = kmem_alloc(sens_len, KM_SLEEP);
5385
5386 sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY, tsl, sens_len);
5387
5388 *len = sens_len;
5389
5390 return (sens);
5391 }
5392
5393 /*
5394 * Okay, how do we report errors/invalid labels from this?
5395 * With a special designated "not a label" cred_t ?
5396 */
5397 /* ARGSUSED */
5398 ts_label_t *
5399 sadb_label_from_sens(sadb_sens_t *sens, uint64_t *bitmap)
5400 {
5401 int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
5402 bslabel_t sl;
5403 ts_label_t *tsl;
5404
5405 if (sens->sadb_sens_integ_level != 0)
5406 return (NULL);
5407 if (sens->sadb_sens_integ_len != 0)
5408 return (NULL);
5409 if (bitmap_len > _C_LEN * 4)
5410 return (NULL);
5411
5412 bsllow(&sl);
5413 LCLASS_SET((_bslabel_impl_t *)&sl, sens->sadb_sens_sens_level);
5414 bcopy(bitmap, &((_bslabel_impl_t *)&sl)->compartments,
5415 bitmap_len);
5416
5417 tsl = labelalloc(&sl, sens->sadb_sens_dpd, KM_NOSLEEP);
5418 if (tsl == NULL)
5419 return (NULL);
5420
5421 if (sens->sadb_x_sens_flags & SADB_X_SENS_UNLABELED)
5422 tsl->tsl_flags |= TSLF_UNLABELED;
5423 return (tsl);
5424 }
5425
5426 /* End XXX label-library-leakage */
5427
5428 /*
5429 * Construct an extended ACQUIRE message based on a selector and the resulting
5430 * IPsec action.
5431 *
5432 * NOTE: This is used by both inverse ACQUIRE and actual ACQUIRE
5433 * generation. As a consequence, expect this function to evolve
5434 * rapidly.
5435 */
5436 static mblk_t *
5437 sadb_extended_acquire(ipsec_selector_t *sel, ipsec_policy_t *pol,
5438 ipsec_action_t *act, boolean_t tunnel_mode, uint32_t seq, uint32_t pid,
5439 sadb_sens_t *sens, netstack_t *ns)
5440 {
5441 mblk_t *mp;
5442 sadb_msg_t *samsg;
5443 uint8_t *start, *cur, *end;
5444 uint32_t *saddrptr, *daddrptr;
5445 sa_family_t af;
5446 sadb_prop_t *eprop;
5447 ipsec_action_t *ap, *an;
5448 ipsec_selkey_t *ipsl;
5449 uint8_t proto, pfxlen;
5450 uint16_t lport, rport;
5451 uint32_t kmp, kmc;
5452
5453 /*
5454 * Find the action we want sooner rather than later..
5455 */
5456 an = NULL;
5457 if (pol == NULL) {
5458 ap = act;
5459 } else {
5460 ap = pol->ipsp_act;
5461
5462 if (ap != NULL)
5463 an = ap->ipa_next;
5464 }
5465
5466 /*
5467 * Just take a swag for the allocation for now. We can always
5468 * alter it later.
5469 */
5470 #define SADB_EXTENDED_ACQUIRE_SIZE 4096
5471 mp = allocb(SADB_EXTENDED_ACQUIRE_SIZE, BPRI_HI);
5472 if (mp == NULL)
5473 return (NULL);
5474
5475 start = mp->b_rptr;
5476 end = start + SADB_EXTENDED_ACQUIRE_SIZE;
5477
5478 cur = start;
5479
5480 samsg = (sadb_msg_t *)cur;
5481 cur += sizeof (*samsg);
5482
5483 samsg->sadb_msg_version = PF_KEY_V2;
5484 samsg->sadb_msg_type = SADB_ACQUIRE;
5485 samsg->sadb_msg_errno = 0;
5486 samsg->sadb_msg_reserved = 0;
5487 samsg->sadb_msg_satype = 0;
5488 samsg->sadb_msg_seq = seq;
5489 samsg->sadb_msg_pid = pid;
5490
5491 if (tunnel_mode) {
5492 /*
5493 * Form inner address extensions based NOT on the inner
5494 * selectors (i.e. the packet data), but on the policy's
5495 * selector key (i.e. the policy's selector information).
5496 *
5497 * NOTE: The position of IPv4 and IPv6 addresses is the
5498 * same in ipsec_selkey_t (unless the compiler does very
5499 * strange things with unions, consult your local C language
5500 * lawyer for details).
5501 */
5502 ASSERT(pol != NULL);
5503
5504 ipsl = &(pol->ipsp_sel->ipsl_key);
5505 if (ipsl->ipsl_valid & IPSL_IPV4) {
5506 af = AF_INET;
5507 ASSERT(sel->ips_protocol == IPPROTO_ENCAP);
5508 ASSERT(!(ipsl->ipsl_valid & IPSL_IPV6));
5509 } else {
5510 af = AF_INET6;
5511 ASSERT(sel->ips_protocol == IPPROTO_IPV6);
5512 ASSERT(ipsl->ipsl_valid & IPSL_IPV6);
5513 }
5514
5515 if (ipsl->ipsl_valid & IPSL_LOCAL_ADDR) {
5516 saddrptr = (uint32_t *)(&ipsl->ipsl_local);
5517 pfxlen = ipsl->ipsl_local_pfxlen;
5518 } else {
5519 saddrptr = (uint32_t *)(&ipv6_all_zeros);
5520 pfxlen = 0;
5521 }
5522 /* XXX What about ICMP type/code? */
5523 lport = (ipsl->ipsl_valid & IPSL_LOCAL_PORT) ?
5524 ipsl->ipsl_lport : 0;
5525 proto = (ipsl->ipsl_valid & IPSL_PROTOCOL) ?
5526 ipsl->ipsl_proto : 0;
5527
5528 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
5529 af, saddrptr, lport, proto, pfxlen);
5530 if (cur == NULL) {
5531 freeb(mp);
5532 return (NULL);
5533 }
5534
5535 if (ipsl->ipsl_valid & IPSL_REMOTE_ADDR) {
5536 daddrptr = (uint32_t *)(&ipsl->ipsl_remote);
5537 pfxlen = ipsl->ipsl_remote_pfxlen;
5538 } else {
5539 daddrptr = (uint32_t *)(&ipv6_all_zeros);
5540 pfxlen = 0;
5541 }
5542 /* XXX What about ICMP type/code? */
5543 rport = (ipsl->ipsl_valid & IPSL_REMOTE_PORT) ?
5544 ipsl->ipsl_rport : 0;
5545
5546 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5547 af, daddrptr, rport, proto, pfxlen);
5548 if (cur == NULL) {
5549 freeb(mp);
5550 return (NULL);
5551 }
5552 /*
5553 * TODO - if we go to 3408's dream of transport mode IP-in-IP
5554 * _with_ inner-packet address selectors, we'll need to further
5555 * distinguish tunnel mode here. For now, having inner
5556 * addresses and/or ports is sufficient.
5557 *
5558 * Meanwhile, whack proto/ports to reflect IP-in-IP for the
5559 * outer addresses.
5560 */
5561 proto = sel->ips_protocol; /* Either _ENCAP or _IPV6 */
5562 lport = rport = 0;
5563 } else if ((ap != NULL) && (!ap->ipa_want_unique)) {
5564 proto = 0;
5565 lport = 0;
5566 rport = 0;
5567 if (pol != NULL) {
5568 ipsl = &(pol->ipsp_sel->ipsl_key);
5569 if (ipsl->ipsl_valid & IPSL_PROTOCOL)
5570 proto = ipsl->ipsl_proto;
5571 if (ipsl->ipsl_valid & IPSL_REMOTE_PORT)
5572 rport = ipsl->ipsl_rport;
5573 if (ipsl->ipsl_valid & IPSL_LOCAL_PORT)
5574 lport = ipsl->ipsl_lport;
5575 }
5576 } else {
5577 proto = sel->ips_protocol;
5578 lport = sel->ips_local_port;
5579 rport = sel->ips_remote_port;
5580 }
5581
5582 af = sel->ips_isv4 ? AF_INET : AF_INET6;
5583
5584 /*
5585 * NOTE: The position of IPv4 and IPv6 addresses is the same in
5586 * ipsec_selector_t.
5587 */
5588 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5589 (uint32_t *)(&sel->ips_local_addr_v6), lport, proto, 0);
5590
5591 if (cur == NULL) {
5592 freeb(mp);
5593 return (NULL);
5594 }
5595
5596 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5597 (uint32_t *)(&sel->ips_remote_addr_v6), rport, proto, 0);
5598
5599 if (cur == NULL) {
5600 freeb(mp);
5601 return (NULL);
5602 }
5603
5604 if (sens != NULL) {
5605 uint8_t *sensext = cur;
5606 int senslen = SADB_64TO8(sens->sadb_sens_len);
5607
5608 cur += senslen;
5609 if (cur > end) {
5610 freeb(mp);
5611 return (NULL);
5612 }
5613 bcopy(sens, sensext, senslen);
5614 }
5615
5616 /*
5617 * This section will change a lot as policy evolves.
5618 * For now, it'll be relatively simple.
5619 */
5620 eprop = (sadb_prop_t *)cur;
5621 cur += sizeof (*eprop);
5622 if (cur > end) {
5623 /* no space left */
5624 freeb(mp);
5625 return (NULL);
5626 }
5627
5628 eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
5629 eprop->sadb_x_prop_ereserved = 0;
5630 eprop->sadb_x_prop_numecombs = 0;
5631 eprop->sadb_prop_replay = 32; /* default */
5632
5633 kmc = kmp = 0;
5634
5635 for (; ap != NULL; ap = an) {
5636 an = (pol != NULL) ? ap->ipa_next : NULL;
5637
5638 /*
5639 * Skip non-IPsec policies
5640 */
5641 if (ap->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5642 continue;
5643
5644 if (ap->ipa_act.ipa_apply.ipp_km_proto)
5645 kmp = ap->ipa_act.ipa_apply.ipp_km_proto;
5646 if (ap->ipa_act.ipa_apply.ipp_km_cookie)
5647 kmc = ap->ipa_act.ipa_apply.ipp_km_cookie;
5648 if (ap->ipa_act.ipa_apply.ipp_replay_depth) {
5649 eprop->sadb_prop_replay =
5650 ap->ipa_act.ipa_apply.ipp_replay_depth;
5651 }
5652
5653 cur = sadb_action_to_ecomb(cur, end, ap, ns);
5654 if (cur == NULL) { /* no space */
5655 freeb(mp);
5656 return (NULL);
5657 }
5658 eprop->sadb_x_prop_numecombs++;
5659 }
5660
5661 if (eprop->sadb_x_prop_numecombs == 0) {
5662 /*
5663 * This will happen if we fail to find a policy
5664 * allowing for IPsec processing.
5665 * Construct an error message.
5666 */
5667 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
5668 samsg->sadb_msg_errno = ENOENT;
5669 samsg->sadb_x_msg_diagnostic = 0;
5670 return (mp);
5671 }
5672
5673 if ((kmp != 0) || (kmc != 0)) {
5674 cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
5675 if (cur == NULL) {
5676 freeb(mp);
5677 return (NULL);
5678 }
5679 }
5680
5681 eprop->sadb_prop_len = SADB_8TO64(cur - (uint8_t *)eprop);
5682 samsg->sadb_msg_len = SADB_8TO64(cur - start);
5683 mp->b_wptr = cur;
5684
5685 return (mp);
5686 }
5687
5688 /*
5689 * Generic setup of an RFC 2367 ACQUIRE message. Caller sets satype.
5690 *
5691 * NOTE: This function acquires alg_lock as a side-effect if-and-only-if we
5692 * succeed (i.e. return non-NULL). Caller MUST release it. This is to
5693 * maximize code consolidation while preventing algorithm changes from messing
5694 * with the callers finishing touches on the ACQUIRE itself.
5695 */
5696 mblk_t *
5697 sadb_setup_acquire(ipsacq_t *acqrec, uint8_t satype, ipsec_stack_t *ipss)
5698 {
5699 uint_t allocsize;
5700 mblk_t *pfkeymp, *msgmp;
5701 sa_family_t af;
5702 uint8_t *cur, *end;
5703 sadb_msg_t *samsg;
5704 uint16_t sport_typecode;
5705 uint16_t dport_typecode;
5706 uint8_t check_proto;
5707 boolean_t tunnel_mode = (acqrec->ipsacq_inneraddrfam != 0);
5708
5709 ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
5710
5711 pfkeymp = sadb_keysock_out(0);
5712 if (pfkeymp == NULL)
5713 return (NULL);
5714
5715 /*
5716 * First, allocate a basic ACQUIRE message
5717 */
5718 allocsize = sizeof (sadb_msg_t) + sizeof (sadb_address_t) +
5719 sizeof (sadb_address_t) + sizeof (sadb_prop_t);
5720
5721 /* Make sure there's enough to cover both AF_INET and AF_INET6. */
5722 allocsize += 2 * sizeof (struct sockaddr_in6);
5723
5724 mutex_enter(&ipss->ipsec_alg_lock);
5725 /* NOTE: The lock is now held through to this function's return. */
5726 allocsize += ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
5727 ipss->ipsec_nalgs[IPSEC_ALG_ENCR] * sizeof (sadb_comb_t);
5728
5729 if (tunnel_mode) {
5730 /* Tunnel mode! */
5731 allocsize += 2 * sizeof (sadb_address_t);
5732 /* Enough to cover both AF_INET and AF_INET6. */
5733 allocsize += 2 * sizeof (struct sockaddr_in6);
5734 }
5735
5736 msgmp = allocb(allocsize, BPRI_HI);
5737 if (msgmp == NULL) {
5738 freeb(pfkeymp);
5739 mutex_exit(&ipss->ipsec_alg_lock);
5740 return (NULL);
5741 }
5742
5743 pfkeymp->b_cont = msgmp;
5744 cur = msgmp->b_rptr;
5745 end = cur + allocsize;
5746 samsg = (sadb_msg_t *)cur;
5747 cur += sizeof (sadb_msg_t);
5748
5749 af = acqrec->ipsacq_addrfam;
5750 switch (af) {
5751 case AF_INET:
5752 check_proto = IPPROTO_ICMP;
5753 break;
5754 case AF_INET6:
5755 check_proto = IPPROTO_ICMPV6;
5756 break;
5757 default:
5758 /* This should never happen unless we have kernel bugs. */
5759 cmn_err(CE_WARN,
5760 "sadb_setup_acquire: corrupt ACQUIRE record.\n");
5761 ASSERT(0);
5762 mutex_exit(&ipss->ipsec_alg_lock);
5763 return (NULL);
5764 }
5765
5766 samsg->sadb_msg_version = PF_KEY_V2;
5767 samsg->sadb_msg_type = SADB_ACQUIRE;
5768 samsg->sadb_msg_satype = satype;
5769 samsg->sadb_msg_errno = 0;
5770 samsg->sadb_msg_pid = 0;
5771 samsg->sadb_msg_reserved = 0;
5772 samsg->sadb_msg_seq = acqrec->ipsacq_seq;
5773
5774 ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
5775
5776 if ((acqrec->ipsacq_proto == check_proto) || tunnel_mode) {
5777 sport_typecode = dport_typecode = 0;
5778 } else {
5779 sport_typecode = acqrec->ipsacq_srcport;
5780 dport_typecode = acqrec->ipsacq_dstport;
5781 }
5782
5783 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5784 acqrec->ipsacq_srcaddr, sport_typecode, acqrec->ipsacq_proto, 0);
5785
5786 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5787 acqrec->ipsacq_dstaddr, dport_typecode, acqrec->ipsacq_proto, 0);
5788
5789 if (tunnel_mode) {
5790 sport_typecode = acqrec->ipsacq_srcport;
5791 dport_typecode = acqrec->ipsacq_dstport;
5792 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
5793 acqrec->ipsacq_inneraddrfam, acqrec->ipsacq_innersrc,
5794 sport_typecode, acqrec->ipsacq_inner_proto,
5795 acqrec->ipsacq_innersrcpfx);
5796 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5797 acqrec->ipsacq_inneraddrfam, acqrec->ipsacq_innerdst,
5798 dport_typecode, acqrec->ipsacq_inner_proto,
5799 acqrec->ipsacq_innerdstpfx);
5800 }
5801
5802 /* XXX Insert identity information here. */
5803
5804 /* XXXMLS Insert sensitivity information here. */
5805
5806 if (cur != NULL)
5807 samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
5808 else
5809 mutex_exit(&ipss->ipsec_alg_lock);
5810
5811 return (pfkeymp);
5812 }
5813
5814 /*
5815 * Given an SADB_GETSPI message, find an appropriately ranged SA and
5816 * allocate an SA. If there are message improprieties, return (ipsa_t *)-1.
5817 * If there was a memory allocation error, return NULL. (Assume NULL !=
5818 * (ipsa_t *)-1).
5819 *
5820 * master_spi is passed in host order.
5821 */
5822 ipsa_t *
5823 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
5824 netstack_t *ns, uint_t sa_type)
5825 {
5826 sadb_address_t *src =
5827 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
5828 *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
5829 sadb_spirange_t *range =
5830 (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
5831 struct sockaddr_in *ssa, *dsa;
5832 struct sockaddr_in6 *ssa6, *dsa6;
5833 uint32_t *srcaddr, *dstaddr;
5834 sa_family_t af;
5835 uint32_t add, min, max;
5836
5837 if (src == NULL) {
5838 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
5839 return ((ipsa_t *)-1);
5840 }
5841 if (dst == NULL) {
5842 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
5843 return ((ipsa_t *)-1);
5844 }
5845 if (range == NULL) {
5846 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_RANGE;
5847 return ((ipsa_t *)-1);
5848 }
5849
5850 min = ntohl(range->sadb_spirange_min);
5851 max = ntohl(range->sadb_spirange_max);
5852 dsa = (struct sockaddr_in *)(dst + 1);
5853 dsa6 = (struct sockaddr_in6 *)dsa;
5854
5855 ssa = (struct sockaddr_in *)(src + 1);
5856 ssa6 = (struct sockaddr_in6 *)ssa;
5857 ASSERT(dsa->sin_family == ssa->sin_family);
5858
5859 srcaddr = ALL_ZEROES_PTR;
5860 af = dsa->sin_family;
5861 switch (af) {
5862 case AF_INET:
5863 if (src != NULL)
5864 srcaddr = (uint32_t *)(&ssa->sin_addr);
5865 dstaddr = (uint32_t *)(&dsa->sin_addr);
5866 break;
5867 case AF_INET6:
5868 if (src != NULL)
5869 srcaddr = (uint32_t *)(&ssa6->sin6_addr);
5870 dstaddr = (uint32_t *)(&dsa6->sin6_addr);
5871 break;
5872 default:
5873 *diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
5874 return ((ipsa_t *)-1);
5875 }
5876
5877 if (master_spi < min || master_spi > max) {
5878 /* Return a random value in the range. */
5879 (void) random_get_pseudo_bytes((uint8_t *)&add, sizeof (add));
5880 master_spi = min + (add % (max - min + 1));
5881 }
5882
5883 /*
5884 * Since master_spi is passed in host order, we need to htonl() it
5885 * for the purposes of creating a new SA.
5886 */
5887 return (sadb_makelarvalassoc(htonl(master_spi), srcaddr, dstaddr, af,
5888 ns));
5889 }
5890
5891 /*
5892 *
5893 * Locate an ACQUIRE and nuke it. If I have an samsg that's larger than the
5894 * base header, just ignore it. Otherwise, lock down the whole ACQUIRE list
5895 * and scan for the sequence number in question. I may wish to accept an
5896 * address pair with it, for easier searching.
5897 *
5898 * Caller frees the message, so we don't have to here.
5899 *
5900 * NOTE: The pfkey_q parameter may be used in the future for ACQUIRE
5901 * failures.
5902 */
5903 /* ARGSUSED */
5904 void
5905 sadb_in_acquire(sadb_msg_t *samsg, sadbp_t *sp, queue_t *pfkey_q,
5906 netstack_t *ns)
5907 {
5908 int i;
5909 ipsacq_t *acqrec;
5910 iacqf_t *bucket;
5911
5912 /*
5913 * I only accept the base header for this!
5914 * Though to be honest, requiring the dst address would help
5915 * immensely.
5916 *
5917 * XXX There are already cases where I can get the dst address.
5918 */
5919 if (samsg->sadb_msg_len > SADB_8TO64(sizeof (*samsg)))
5920 return;
5921
5922 /*
5923 * Using the samsg->sadb_msg_seq, find the ACQUIRE record, delete it,
5924 * (and in the future send a message to IP with the appropriate error
5925 * number).
5926 *
5927 * Q: Do I want to reject if pid != 0?
5928 */
5929
5930 for (i = 0; i < sp->s_v4.sdb_hashsize; i++) {
5931 bucket = &sp->s_v4.sdb_acq[i];
5932 mutex_enter(&bucket->iacqf_lock);
5933 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
5934 acqrec = acqrec->ipsacq_next) {
5935 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
5936 break; /* for acqrec... loop. */
5937 }
5938 if (acqrec != NULL)
5939 break; /* for i = 0... loop. */
5940
5941 mutex_exit(&bucket->iacqf_lock);
5942 }
5943
5944 if (acqrec == NULL) {
5945 for (i = 0; i < sp->s_v6.sdb_hashsize; i++) {
5946 bucket = &sp->s_v6.sdb_acq[i];
5947 mutex_enter(&bucket->iacqf_lock);
5948 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
5949 acqrec = acqrec->ipsacq_next) {
5950 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
5951 break; /* for acqrec... loop. */
5952 }
5953 if (acqrec != NULL)
5954 break; /* for i = 0... loop. */
5955
5956 mutex_exit(&bucket->iacqf_lock);
5957 }
5958 }
5959
5960
5961 if (acqrec == NULL)
5962 return;
5963
5964 /*
5965 * What do I do with the errno and IP? I may need mp's services a
5966 * little more. See sadb_destroy_acquire() for future directions
5967 * beyond free the mblk chain on the acquire record.
5968 */
5969
5970 ASSERT(&bucket->iacqf_lock == acqrec->ipsacq_linklock);
5971 sadb_destroy_acquire(acqrec, ns);
5972 /* Have to exit mutex here, because of breaking out of for loop. */
5973 mutex_exit(&bucket->iacqf_lock);
5974 }
5975
5976 /*
5977 * The following functions work with the replay windows of an SA. They assume
5978 * the ipsa->ipsa_replay_arr is an array of uint64_t, and that the bit vector
5979 * represents the highest sequence number packet received, and back
5980 * (ipsa->ipsa_replay_wsize) packets.
5981 */
5982
5983 /*
5984 * Is the replay bit set?
5985 */
5986 static boolean_t
5987 ipsa_is_replay_set(ipsa_t *ipsa, uint32_t offset)
5988 {
5989 uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
5990
5991 return ((bit & ipsa->ipsa_replay_arr[offset >> 6]) ? B_TRUE : B_FALSE);
5992 }
5993
5994 /*
5995 * Shift the bits of the replay window over.
5996 */
5997 static void
5998 ipsa_shift_replay(ipsa_t *ipsa, uint32_t shift)
5999 {
6000 int i;
6001 int jump = ((shift - 1) >> 6) + 1;
6002
6003 if (shift == 0)
6004 return;
6005
6006 for (i = (ipsa->ipsa_replay_wsize - 1) >> 6; i >= 0; i--) {
6007 if (i + jump <= (ipsa->ipsa_replay_wsize - 1) >> 6) {
6008 ipsa->ipsa_replay_arr[i + jump] |=
6009 ipsa->ipsa_replay_arr[i] >> (64 - (shift & 63));
6010 }
6011 ipsa->ipsa_replay_arr[i] <<= shift;
6012 }
6013 }
6014
6015 /*
6016 * Set a bit in the bit vector.
6017 */
6018 static void
6019 ipsa_set_replay(ipsa_t *ipsa, uint32_t offset)
6020 {
6021 uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
6022
6023 ipsa->ipsa_replay_arr[offset >> 6] |= bit;
6024 }
6025
6026 #define SADB_MAX_REPLAY_VALUE 0xffffffff
6027
6028 /*
6029 * Assume caller has NOT done ntohl() already on seq. Check to see
6030 * if replay sequence number "seq" has been seen already.
6031 */
6032 boolean_t
6033 sadb_replay_check(ipsa_t *ipsa, uint32_t seq)
6034 {
6035 boolean_t rc;
6036 uint32_t diff;
6037
6038 if (ipsa->ipsa_replay_wsize == 0)
6039 return (B_TRUE);
6040
6041 /*
6042 * NOTE: I've already checked for 0 on the wire in sadb_replay_peek().
6043 */
6044
6045 /* Convert sequence number into host order before holding the mutex. */
6046 seq = ntohl(seq);
6047
6048 mutex_enter(&ipsa->ipsa_lock);
6049
6050 /* Initialize inbound SA's ipsa_replay field to last one received. */
6051 if (ipsa->ipsa_replay == 0)
6052 ipsa->ipsa_replay = 1;
6053
6054 if (seq > ipsa->ipsa_replay) {
6055 /*
6056 * I have received a new "highest value received". Shift
6057 * the replay window over.
6058 */
6059 diff = seq - ipsa->ipsa_replay;
6060 if (diff < ipsa->ipsa_replay_wsize) {
6061 /* In replay window, shift bits over. */
6062 ipsa_shift_replay(ipsa, diff);
6063 } else {
6064 /* WAY FAR AHEAD, clear bits and start again. */
6065 bzero(ipsa->ipsa_replay_arr,
6066 sizeof (ipsa->ipsa_replay_arr));
6067 }
6068 ipsa_set_replay(ipsa, 0);
6069 ipsa->ipsa_replay = seq;
6070 rc = B_TRUE;
6071 goto done;
6072 }
6073 diff = ipsa->ipsa_replay - seq;
6074 if (diff >= ipsa->ipsa_replay_wsize || ipsa_is_replay_set(ipsa, diff)) {
6075 rc = B_FALSE;
6076 goto done;
6077 }
6078 /* Set this packet as seen. */
6079 ipsa_set_replay(ipsa, diff);
6080
6081 rc = B_TRUE;
6082 done:
6083 mutex_exit(&ipsa->ipsa_lock);
6084 return (rc);
6085 }
6086
6087 /*
6088 * "Peek" and see if we should even bother going through the effort of
6089 * running an authentication check on the sequence number passed in.
6090 * this takes into account packets that are below the replay window,
6091 * and collisions with already replayed packets. Return B_TRUE if it
6092 * is okay to proceed, B_FALSE if this packet should be dropped immediately.
6093 * Assume same byte-ordering as sadb_replay_check.
6094 */
6095 boolean_t
6096 sadb_replay_peek(ipsa_t *ipsa, uint32_t seq)
6097 {
6098 boolean_t rc = B_FALSE;
6099 uint32_t diff;
6100
6101 if (ipsa->ipsa_replay_wsize == 0)
6102 return (B_TRUE);
6103
6104 /*
6105 * 0 is 0, regardless of byte order... :)
6106 *
6107 * If I get 0 on the wire (and there is a replay window) then the
6108 * sender most likely wrapped. This ipsa may need to be marked or
6109 * something.
6110 */
6111 if (seq == 0)
6112 return (B_FALSE);
6113
6114 seq = ntohl(seq);
6115 mutex_enter(&ipsa->ipsa_lock);
6116 if (seq < ipsa->ipsa_replay - ipsa->ipsa_replay_wsize &&
6117 ipsa->ipsa_replay >= ipsa->ipsa_replay_wsize)
6118 goto done;
6119
6120 /*
6121 * If I've hit 0xffffffff, then quite honestly, I don't need to
6122 * bother with formalities. I'm not accepting any more packets
6123 * on this SA.
6124 */
6125 if (ipsa->ipsa_replay == SADB_MAX_REPLAY_VALUE) {
6126 /*
6127 * Since we're already holding the lock, update the
6128 * expire time ala. sadb_replay_delete() and return.
6129 */
6130 ipsa->ipsa_hardexpiretime = (time_t)1;
6131 goto done;
6132 }
6133
6134 if (seq <= ipsa->ipsa_replay) {
6135 /*
6136 * This seq is in the replay window. I'm not below it,
6137 * because I already checked for that above!
6138 */
6139 diff = ipsa->ipsa_replay - seq;
6140 if (ipsa_is_replay_set(ipsa, diff))
6141 goto done;
6142 }
6143 /* Else return B_TRUE, I'm going to advance the window. */
6144
6145 rc = B_TRUE;
6146 done:
6147 mutex_exit(&ipsa->ipsa_lock);
6148 return (rc);
6149 }
6150
6151 /*
6152 * Delete a single SA.
6153 *
6154 * For now, use the quick-and-dirty trick of making the association's
6155 * hard-expire lifetime (time_t)1, ensuring deletion by the *_ager().
6156 */
6157 void
6158 sadb_replay_delete(ipsa_t *assoc)
6159 {
6160 mutex_enter(&assoc->ipsa_lock);
6161 assoc->ipsa_hardexpiretime = (time_t)1;
6162 mutex_exit(&assoc->ipsa_lock);
6163 }
6164
6165 /*
6166 * Special front-end to ipsec_rl_strlog() dealing with SA failure.
6167 * this is designed to take only a format string with "* %x * %s *", so
6168 * that "spi" is printed first, then "addr" is converted using inet_pton().
6169 *
6170 * This is abstracted out to save the stack space for only when inet_pton()
6171 * is called. Make sure "spi" is in network order; it usually is when this
6172 * would get called.
6173 */
6174 void
6175 ipsec_assocfailure(short mid, short sid, char level, ushort_t sl, char *fmt,
6176 uint32_t spi, void *addr, int af, netstack_t *ns)
6177 {
6178 char buf[INET6_ADDRSTRLEN];
6179
6180 ASSERT(af == AF_INET6 || af == AF_INET);
6181
6182 ipsec_rl_strlog(ns, mid, sid, level, sl, fmt, ntohl(spi),
6183 inet_ntop(af, addr, buf, sizeof (buf)));
6184 }
6185
6186 /*
6187 * Fills in a reference to the policy, if any, from the conn, in *ppp
6188 */
6189 static void
6190 ipsec_conn_pol(ipsec_selector_t *sel, conn_t *connp, ipsec_policy_t **ppp)
6191 {
6192 ipsec_policy_t *pp;
6193 ipsec_latch_t *ipl = connp->conn_latch;
6194
6195 if ((ipl != NULL) && (connp->conn_ixa->ixa_ipsec_policy != NULL)) {
6196 pp = connp->conn_ixa->ixa_ipsec_policy;
6197 IPPOL_REFHOLD(pp);
6198 } else {
6199 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, connp, sel,
6200 connp->conn_netstack);
6201 }
6202 *ppp = pp;
6203 }
6204
6205 /*
6206 * The following functions scan through active conn_t structures
6207 * and return a reference to the best-matching policy it can find.
6208 * Caller must release the reference.
6209 */
6210 static void
6211 ipsec_udp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6212 {
6213 connf_t *connfp;
6214 conn_t *connp = NULL;
6215 ipsec_selector_t portonly;
6216
6217 bzero((void *)&portonly, sizeof (portonly));
6218
6219 if (sel->ips_local_port == 0)
6220 return;
6221
6222 connfp = &ipst->ips_ipcl_udp_fanout[IPCL_UDP_HASH(sel->ips_local_port,
6223 ipst)];
6224 mutex_enter(&connfp->connf_lock);
6225
6226 if (sel->ips_isv4) {
6227 connp = connfp->connf_head;
6228 while (connp != NULL) {
6229 if (IPCL_UDP_MATCH(connp, sel->ips_local_port,
6230 sel->ips_local_addr_v4, sel->ips_remote_port,
6231 sel->ips_remote_addr_v4))
6232 break;
6233 connp = connp->conn_next;
6234 }
6235
6236 if (connp == NULL) {
6237 /* Try port-only match in IPv6. */
6238 portonly.ips_local_port = sel->ips_local_port;
6239 sel = &portonly;
6240 }
6241 }
6242
6243 if (connp == NULL) {
6244 connp = connfp->connf_head;
6245 while (connp != NULL) {
6246 if (IPCL_UDP_MATCH_V6(connp, sel->ips_local_port,
6247 sel->ips_local_addr_v6, sel->ips_remote_port,
6248 sel->ips_remote_addr_v6))
6249 break;
6250 connp = connp->conn_next;
6251 }
6252
6253 if (connp == NULL) {
6254 mutex_exit(&connfp->connf_lock);
6255 return;
6256 }
6257 }
6258
6259 CONN_INC_REF(connp);
6260 mutex_exit(&connfp->connf_lock);
6261
6262 ipsec_conn_pol(sel, connp, ppp);
6263 CONN_DEC_REF(connp);
6264 }
6265
6266 static conn_t *
6267 ipsec_find_listen_conn(uint16_t *pptr, ipsec_selector_t *sel, ip_stack_t *ipst)
6268 {
6269 connf_t *connfp;
6270 conn_t *connp = NULL;
6271 const in6_addr_t *v6addrmatch = &sel->ips_local_addr_v6;
6272
6273 if (sel->ips_local_port == 0)
6274 return (NULL);
6275
6276 connfp = &ipst->ips_ipcl_bind_fanout[
6277 IPCL_BIND_HASH(sel->ips_local_port, ipst)];
6278 mutex_enter(&connfp->connf_lock);
6279
6280 if (sel->ips_isv4) {
6281 connp = connfp->connf_head;
6282 while (connp != NULL) {
6283 if (IPCL_BIND_MATCH(connp, IPPROTO_TCP,
6284 sel->ips_local_addr_v4, pptr[1]))
6285 break;
6286 connp = connp->conn_next;
6287 }
6288
6289 if (connp == NULL) {
6290 /* Match to all-zeroes. */
6291 v6addrmatch = &ipv6_all_zeros;
6292 }
6293 }
6294
6295 if (connp == NULL) {
6296 connp = connfp->connf_head;
6297 while (connp != NULL) {
6298 if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP,
6299 *v6addrmatch, pptr[1]))
6300 break;
6301 connp = connp->conn_next;
6302 }
6303
6304 if (connp == NULL) {
6305 mutex_exit(&connfp->connf_lock);
6306 return (NULL);
6307 }
6308 }
6309
6310 CONN_INC_REF(connp);
6311 mutex_exit(&connfp->connf_lock);
6312 return (connp);
6313 }
6314
6315 static void
6316 ipsec_tcp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6317 {
6318 connf_t *connfp;
6319 conn_t *connp;
6320 uint32_t ports;
6321 uint16_t *pptr = (uint16_t *)&ports;
6322
6323 /*
6324 * Find TCP state in the following order:
6325 * 1.) Connected conns.
6326 * 2.) Listeners.
6327 *
6328 * Even though #2 will be the common case for inbound traffic, only
6329 * following this order insures correctness.
6330 */
6331
6332 if (sel->ips_local_port == 0)
6333 return;
6334
6335 /*
6336 * 0 should be fport, 1 should be lport. SRC is the local one here.
6337 * See ipsec_construct_inverse_acquire() for details.
6338 */
6339 pptr[0] = sel->ips_remote_port;
6340 pptr[1] = sel->ips_local_port;
6341
6342 connfp = &ipst->ips_ipcl_conn_fanout[
6343 IPCL_CONN_HASH(sel->ips_remote_addr_v4, ports, ipst)];
6344 mutex_enter(&connfp->connf_lock);
6345 connp = connfp->connf_head;
6346
6347 if (sel->ips_isv4) {
6348 while (connp != NULL) {
6349 if (IPCL_CONN_MATCH(connp, IPPROTO_TCP,
6350 sel->ips_remote_addr_v4, sel->ips_local_addr_v4,
6351 ports))
6352 break;
6353 connp = connp->conn_next;
6354 }
6355 } else {
6356 while (connp != NULL) {
6357 if (IPCL_CONN_MATCH_V6(connp, IPPROTO_TCP,
6358 sel->ips_remote_addr_v6, sel->ips_local_addr_v6,
6359 ports))
6360 break;
6361 connp = connp->conn_next;
6362 }
6363 }
6364
6365 if (connp != NULL) {
6366 CONN_INC_REF(connp);
6367 mutex_exit(&connfp->connf_lock);
6368 } else {
6369 mutex_exit(&connfp->connf_lock);
6370
6371 /* Try the listen hash. */
6372 if ((connp = ipsec_find_listen_conn(pptr, sel, ipst)) == NULL)
6373 return;
6374 }
6375
6376 ipsec_conn_pol(sel, connp, ppp);
6377 CONN_DEC_REF(connp);
6378 }
6379
6380 static void
6381 ipsec_sctp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6382 ip_stack_t *ipst)
6383 {
6384 conn_t *connp;
6385 uint32_t ports;
6386 uint16_t *pptr = (uint16_t *)&ports;
6387
6388 /*
6389 * Find SCP state in the following order:
6390 * 1.) Connected conns.
6391 * 2.) Listeners.
6392 *
6393 * Even though #2 will be the common case for inbound traffic, only
6394 * following this order insures correctness.
6395 */
6396
6397 if (sel->ips_local_port == 0)
6398 return;
6399
6400 /*
6401 * 0 should be fport, 1 should be lport. SRC is the local one here.
6402 * See ipsec_construct_inverse_acquire() for details.
6403 */
6404 pptr[0] = sel->ips_remote_port;
6405 pptr[1] = sel->ips_local_port;
6406
6407 /*
6408 * For labeled systems, there's no need to check the
6409 * label here. It's known to be good as we checked
6410 * before allowing the connection to become bound.
6411 */
6412 if (sel->ips_isv4) {
6413 in6_addr_t src, dst;
6414
6415 IN6_IPADDR_TO_V4MAPPED(sel->ips_remote_addr_v4, &dst);
6416 IN6_IPADDR_TO_V4MAPPED(sel->ips_local_addr_v4, &src);
6417 connp = sctp_find_conn(&dst, &src, ports, ALL_ZONES,
6418 0, ipst->ips_netstack->netstack_sctp);
6419 } else {
6420 connp = sctp_find_conn(&sel->ips_remote_addr_v6,
6421 &sel->ips_local_addr_v6, ports, ALL_ZONES,
6422 0, ipst->ips_netstack->netstack_sctp);
6423 }
6424 if (connp == NULL)
6425 return;
6426 ipsec_conn_pol(sel, connp, ppp);
6427 CONN_DEC_REF(connp);
6428 }
6429
6430 /*
6431 * Fill in a query for the SPD (in "sel") using two PF_KEY address extensions.
6432 * Returns 0 or errno, and always sets *diagnostic to something appropriate
6433 * to PF_KEY.
6434 *
6435 * NOTE: For right now, this function (and ipsec_selector_t for that matter),
6436 * ignore prefix lengths in the address extension. Since we match on first-
6437 * entered policies, this shouldn't matter. Also, since we normalize prefix-
6438 * set addresses to mask out the lower bits, we should get a suitable search
6439 * key for the SPD anyway. This is the function to change if the assumption
6440 * about suitable search keys is wrong.
6441 */
6442 static int
6443 ipsec_get_inverse_acquire_sel(ipsec_selector_t *sel, sadb_address_t *srcext,
6444 sadb_address_t *dstext, int *diagnostic)
6445 {
6446 struct sockaddr_in *src, *dst;
6447 struct sockaddr_in6 *src6, *dst6;
6448
6449 *diagnostic = 0;
6450
6451 bzero(sel, sizeof (*sel));
6452 sel->ips_protocol = srcext->sadb_address_proto;
6453 dst = (struct sockaddr_in *)(dstext + 1);
6454 if (dst->sin_family == AF_INET6) {
6455 dst6 = (struct sockaddr_in6 *)dst;
6456 src6 = (struct sockaddr_in6 *)(srcext + 1);
6457 if (src6->sin6_family != AF_INET6) {
6458 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6459 return (EINVAL);
6460 }
6461 sel->ips_remote_addr_v6 = dst6->sin6_addr;
6462 sel->ips_local_addr_v6 = src6->sin6_addr;
6463 if (sel->ips_protocol == IPPROTO_ICMPV6) {
6464 sel->ips_is_icmp_inv_acq = 1;
6465 } else {
6466 sel->ips_remote_port = dst6->sin6_port;
6467 sel->ips_local_port = src6->sin6_port;
6468 }
6469 sel->ips_isv4 = B_FALSE;
6470 } else {
6471 src = (struct sockaddr_in *)(srcext + 1);
6472 if (src->sin_family != AF_INET) {
6473 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6474 return (EINVAL);
6475 }
6476 sel->ips_remote_addr_v4 = dst->sin_addr.s_addr;
6477 sel->ips_local_addr_v4 = src->sin_addr.s_addr;
6478 if (sel->ips_protocol == IPPROTO_ICMP) {
6479 sel->ips_is_icmp_inv_acq = 1;
6480 } else {
6481 sel->ips_remote_port = dst->sin_port;
6482 sel->ips_local_port = src->sin_port;
6483 }
6484 sel->ips_isv4 = B_TRUE;
6485 }
6486 return (0);
6487 }
6488
6489 /*
6490 * We have encapsulation.
6491 * - Lookup tun_t by address and look for an associated
6492 * tunnel policy
6493 * - If there are inner selectors
6494 * - check ITPF_P_TUNNEL and ITPF_P_ACTIVE
6495 * - Look up tunnel policy based on selectors
6496 * - Else
6497 * - Sanity check the negotation
6498 * - If appropriate, fall through to global policy
6499 */
6500 static int
6501 ipsec_tun_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6502 sadb_address_t *innsrcext, sadb_address_t *inndstext, ipsec_tun_pol_t *itp,
6503 int *diagnostic)
6504 {
6505 int err;
6506 ipsec_policy_head_t *polhead;
6507
6508 *diagnostic = 0;
6509
6510 /* Check for inner selectors and act appropriately */
6511
6512 if (innsrcext != NULL) {
6513 /* Inner selectors present */
6514 ASSERT(inndstext != NULL);
6515 if ((itp == NULL) ||
6516 (itp->itp_flags & (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) !=
6517 (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) {
6518 /*
6519 * If inner packet selectors, we must have negotiate
6520 * tunnel and active policy. If the tunnel has
6521 * transport-mode policy set on it, or has no policy,
6522 * fail.
6523 */
6524 return (ENOENT);
6525 } else {
6526 /*
6527 * Reset "sel" to indicate inner selectors. Pass
6528 * inner PF_KEY address extensions for this to happen.
6529 */
6530 if ((err = ipsec_get_inverse_acquire_sel(sel,
6531 innsrcext, inndstext, diagnostic)) != 0)
6532 return (err);
6533 /*
6534 * Now look for a tunnel policy based on those inner
6535 * selectors. (Common code is below.)
6536 */
6537 }
6538 } else {
6539 /* No inner selectors present */
6540 if ((itp == NULL) || !(itp->itp_flags & ITPF_P_ACTIVE)) {
6541 /*
6542 * Transport mode negotiation with no tunnel policy
6543 * configured - return to indicate a global policy
6544 * check is needed.
6545 */
6546 return (0);
6547 } else if (itp->itp_flags & ITPF_P_TUNNEL) {
6548 /* Tunnel mode set with no inner selectors. */
6549 return (ENOENT);
6550 }
6551 /*
6552 * Else, this is a tunnel policy configured with ifconfig(1m)
6553 * or "negotiate transport" with ipsecconf(1m). We have an
6554 * itp with policy set based on any match, so don't bother
6555 * changing fields in "sel".
6556 */
6557 }
6558
6559 ASSERT(itp != NULL);
6560 polhead = itp->itp_policy;
6561 ASSERT(polhead != NULL);
6562 rw_enter(&polhead->iph_lock, RW_READER);
6563 *ppp = ipsec_find_policy_head(NULL, polhead, IPSEC_TYPE_INBOUND, sel);
6564 rw_exit(&polhead->iph_lock);
6565
6566 /*
6567 * Don't default to global if we didn't find a matching policy entry.
6568 * Instead, send ENOENT, just like if we hit a transport-mode tunnel.
6569 */
6570 if (*ppp == NULL)
6571 return (ENOENT);
6572
6573 return (0);
6574 }
6575
6576 /*
6577 * For sctp conn_faddr is the primary address, hence this is of limited
6578 * use for sctp.
6579 */
6580 static void
6581 ipsec_oth_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6582 ip_stack_t *ipst)
6583 {
6584 boolean_t isv4 = sel->ips_isv4;
6585 connf_t *connfp;
6586 conn_t *connp;
6587
6588 if (isv4) {
6589 connfp = &ipst->ips_ipcl_proto_fanout_v4[sel->ips_protocol];
6590 } else {
6591 connfp = &ipst->ips_ipcl_proto_fanout_v6[sel->ips_protocol];
6592 }
6593
6594 mutex_enter(&connfp->connf_lock);
6595 for (connp = connfp->connf_head; connp != NULL;
6596 connp = connp->conn_next) {
6597 if (isv4) {
6598 if ((connp->conn_laddr_v4 == INADDR_ANY ||
6599 connp->conn_laddr_v4 == sel->ips_local_addr_v4) &&
6600 (connp->conn_faddr_v4 == INADDR_ANY ||
6601 connp->conn_faddr_v4 == sel->ips_remote_addr_v4))
6602 break;
6603 } else {
6604 if ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
6605 IN6_ARE_ADDR_EQUAL(&connp->conn_laddr_v6,
6606 &sel->ips_local_addr_v6)) &&
6607 (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) ||
6608 IN6_ARE_ADDR_EQUAL(&connp->conn_faddr_v6,
6609 &sel->ips_remote_addr_v6)))
6610 break;
6611 }
6612 }
6613 if (connp == NULL) {
6614 mutex_exit(&connfp->connf_lock);
6615 return;
6616 }
6617
6618 CONN_INC_REF(connp);
6619 mutex_exit(&connfp->connf_lock);
6620
6621 ipsec_conn_pol(sel, connp, ppp);
6622 CONN_DEC_REF(connp);
6623 }
6624
6625 /*
6626 * Construct an inverse ACQUIRE reply based on:
6627 *
6628 * 1.) Current global policy.
6629 * 2.) An conn_t match depending on what all was passed in the extv[].
6630 * 3.) A tunnel's policy head.
6631 * ...
6632 * N.) Other stuff TBD (e.g. identities)
6633 *
6634 * If there is an error, set sadb_msg_errno and sadb_x_msg_diagnostic
6635 * in this function so the caller can extract them where appropriately.
6636 *
6637 * The SRC address is the local one - just like an outbound ACQUIRE message.
6638 *
6639 * XXX MLS: key management supplies a label which we just reflect back up
6640 * again. clearly we need to involve the label in the rest of the checks.
6641 */
6642 mblk_t *
6643 ipsec_construct_inverse_acquire(sadb_msg_t *samsg, sadb_ext_t *extv[],
6644 netstack_t *ns)
6645 {
6646 int err;
6647 int diagnostic;
6648 sadb_address_t *srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC],
6649 *dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST],
6650 *innsrcext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC],
6651 *inndstext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST];
6652 sadb_sens_t *sens = (sadb_sens_t *)extv[SADB_EXT_SENSITIVITY];
6653 struct sockaddr_in6 *src, *dst;
6654 struct sockaddr_in6 *isrc, *idst;
6655 ipsec_tun_pol_t *itp = NULL;
6656 ipsec_policy_t *pp = NULL;
6657 ipsec_selector_t sel, isel;
6658 mblk_t *retmp = NULL;
6659 ip_stack_t *ipst = ns->netstack_ip;
6660
6661
6662 /* Normalize addresses */
6663 if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)srcext, 0, ns)
6664 == KS_IN_ADDR_UNKNOWN) {
6665 err = EINVAL;
6666 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC;
6667 goto bail;
6668 }
6669 src = (struct sockaddr_in6 *)(srcext + 1);
6670 if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)dstext, 0, ns)
6671 == KS_IN_ADDR_UNKNOWN) {
6672 err = EINVAL;
6673 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST;
6674 goto bail;
6675 }
6676 dst = (struct sockaddr_in6 *)(dstext + 1);
6677 if (src->sin6_family != dst->sin6_family) {
6678 err = EINVAL;
6679 diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6680 goto bail;
6681 }
6682
6683 /* Check for tunnel mode and act appropriately */
6684 if (innsrcext != NULL) {
6685 if (inndstext == NULL) {
6686 err = EINVAL;
6687 diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_DST;
6688 goto bail;
6689 }
6690 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
6691 (sadb_ext_t *)innsrcext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
6692 err = EINVAL;
6693 diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC;
6694 goto bail;
6695 }
6696 isrc = (struct sockaddr_in6 *)(innsrcext + 1);
6697 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
6698 (sadb_ext_t *)inndstext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
6699 err = EINVAL;
6700 diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST;
6701 goto bail;
6702 }
6703 idst = (struct sockaddr_in6 *)(inndstext + 1);
6704 if (isrc->sin6_family != idst->sin6_family) {
6705 err = EINVAL;
6706 diagnostic = SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
6707 goto bail;
6708 }
6709 if (isrc->sin6_family != AF_INET &&
6710 isrc->sin6_family != AF_INET6) {
6711 err = EINVAL;
6712 diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_SRC_AF;
6713 goto bail;
6714 }
6715 } else if (inndstext != NULL) {
6716 err = EINVAL;
6717 diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
6718 goto bail;
6719 }
6720
6721 /* Get selectors first, based on outer addresses */
6722 err = ipsec_get_inverse_acquire_sel(&sel, srcext, dstext, &diagnostic);
6723 if (err != 0)
6724 goto bail;
6725
6726 /* Check for tunnel mode mismatches. */
6727 if (innsrcext != NULL &&
6728 ((isrc->sin6_family == AF_INET &&
6729 sel.ips_protocol != IPPROTO_ENCAP && sel.ips_protocol != 0) ||
6730 (isrc->sin6_family == AF_INET6 &&
6731 sel.ips_protocol != IPPROTO_IPV6 && sel.ips_protocol != 0))) {
6732 err = EPROTOTYPE;
6733 goto bail;
6734 }
6735
6736 /*
6737 * Okay, we have the addresses and other selector information.
6738 * Let's first find a conn...
6739 */
6740 pp = NULL;
6741 switch (sel.ips_protocol) {
6742 case IPPROTO_TCP:
6743 ipsec_tcp_pol(&sel, &pp, ipst);
6744 break;
6745 case IPPROTO_UDP:
6746 ipsec_udp_pol(&sel, &pp, ipst);
6747 break;
6748 case IPPROTO_SCTP:
6749 ipsec_sctp_pol(&sel, &pp, ipst);
6750 break;
6751 case IPPROTO_ENCAP:
6752 case IPPROTO_IPV6:
6753 /*
6754 * Assume sel.ips_remote_addr_* has the right address at
6755 * that exact position.
6756 */
6757 itp = itp_get_byaddr((uint32_t *)(&sel.ips_local_addr_v6),
6758 (uint32_t *)(&sel.ips_remote_addr_v6), src->sin6_family,
6759 ipst);
6760
6761 if (innsrcext == NULL) {
6762 /*
6763 * Transport-mode tunnel, make sure we fake out isel
6764 * to contain something based on the outer protocol.
6765 */
6766 bzero(&isel, sizeof (isel));
6767 isel.ips_isv4 = (sel.ips_protocol == IPPROTO_ENCAP);
6768 } /* Else isel is initialized by ipsec_tun_pol(). */
6769 err = ipsec_tun_pol(&isel, &pp, innsrcext, inndstext, itp,
6770 &diagnostic);
6771 /*
6772 * NOTE: isel isn't used for now, but in RFC 430x IPsec, it
6773 * may be.
6774 */
6775 if (err != 0)
6776 goto bail;
6777 break;
6778 default:
6779 ipsec_oth_pol(&sel, &pp, ipst);
6780 break;
6781 }
6782
6783 /*
6784 * If we didn't find a matching conn_t or other policy head, take a
6785 * look in the global policy.
6786 */
6787 if (pp == NULL) {
6788 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, &sel, ns);
6789 if (pp == NULL) {
6790 /* There's no global policy. */
6791 err = ENOENT;
6792 diagnostic = 0;
6793 goto bail;
6794 }
6795 }
6796
6797 /*
6798 * Now that we have a policy entry/widget, construct an ACQUIRE
6799 * message based on that, fix fields where appropriate,
6800 * and return the message.
6801 */
6802 retmp = sadb_extended_acquire(&sel, pp, NULL,
6803 (itp != NULL && (itp->itp_flags & ITPF_P_TUNNEL)),
6804 samsg->sadb_msg_seq, samsg->sadb_msg_pid, sens, ns);
6805 if (pp != NULL) {
6806 IPPOL_REFRELE(pp);
6807 }
6808 ASSERT(err == 0 && diagnostic == 0);
6809 if (retmp == NULL)
6810 err = ENOMEM;
6811 bail:
6812 if (itp != NULL) {
6813 ITP_REFRELE(itp, ns);
6814 }
6815 samsg->sadb_msg_errno = (uint8_t)err;
6816 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
6817 return (retmp);
6818 }
6819
6820 /*
6821 * ipsa_lpkt is a one-element queue, only manipulated by the next two
6822 * functions. They have to hold the ipsa_lock because of potential races
6823 * between key management using SADB_UPDATE, and inbound packets that may
6824 * queue up on the larval SA (hence the 'l' in "lpkt").
6825 */
6826
6827 /*
6828 * sadb_set_lpkt:
6829 *
6830 * Returns the passed-in packet if the SA is no longer larval.
6831 *
6832 * Returns NULL if the SA is larval, and needs to be swapped into the SA for
6833 * processing after an SADB_UPDATE.
6834 */
6835 mblk_t *
6836 sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt, ip_recv_attr_t *ira)
6837 {
6838 mblk_t *opkt;
6839
6840 mutex_enter(&ipsa->ipsa_lock);
6841 opkt = ipsa->ipsa_lpkt;
6842 if (ipsa->ipsa_state == IPSA_STATE_LARVAL) {
6843 /*
6844 * Consume npkt and place it in the LARVAL SA's inbound
6845 * packet slot.
6846 */
6847 mblk_t *attrmp;
6848
6849 attrmp = ip_recv_attr_to_mblk(ira);
6850 if (attrmp == NULL) {
6851 ill_t *ill = ira->ira_ill;
6852
6853 BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
6854 ip_drop_input("ipIfStatsInDiscards", npkt, ill);
6855 freemsg(npkt);
6856 opkt = NULL;
6857 } else {
6858 ASSERT(attrmp->b_cont == NULL);
6859 attrmp->b_cont = npkt;
6860 ipsa->ipsa_lpkt = attrmp;
6861 }
6862 npkt = NULL;
6863 } else {
6864 /*
6865 * If not larval, we lost the race. NOTE: ipsa_lpkt may still
6866 * have been non-NULL in the non-larval case, because of
6867 * inbound packets arriving prior to sadb_common_add()
6868 * transferring the SA completely out of larval state, but
6869 * after lpkt was grabbed by the AH/ESP-specific add routines.
6870 * We should clear the old ipsa_lpkt in this case to make sure
6871 * that it doesn't linger on the now-MATURE IPsec SA, or get
6872 * picked up as an out-of-order packet.
6873 */
6874 ipsa->ipsa_lpkt = NULL;
6875 }
6876 mutex_exit(&ipsa->ipsa_lock);
6877
6878 if (opkt != NULL) {
6879 ipsec_stack_t *ipss;
6880
6881 ipss = ira->ira_ill->ill_ipst->ips_netstack->netstack_ipsec;
6882 opkt = ip_recv_attr_free_mblk(opkt);
6883 ip_drop_packet(opkt, B_TRUE, ira->ira_ill,
6884 DROPPER(ipss, ipds_sadb_inlarval_replace),
6885 &ipss->ipsec_sadb_dropper);
6886 }
6887 return (npkt);
6888 }
6889
6890 /*
6891 * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
6892 * previous value.
6893 */
6894 mblk_t *
6895 sadb_clear_lpkt(ipsa_t *ipsa)
6896 {
6897 mblk_t *opkt;
6898
6899 mutex_enter(&ipsa->ipsa_lock);
6900 opkt = ipsa->ipsa_lpkt;
6901 ipsa->ipsa_lpkt = NULL;
6902 mutex_exit(&ipsa->ipsa_lock);
6903 return (opkt);
6904 }
6905
6906 /*
6907 * Buffer a packet that's in IDLE state as set by Solaris Clustering.
6908 */
6909 void
6910 sadb_buf_pkt(ipsa_t *ipsa, mblk_t *bpkt, ip_recv_attr_t *ira)
6911 {
6912 netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack;
6913 ipsec_stack_t *ipss = ns->netstack_ipsec;
6914
6915 ASSERT(ipsa->ipsa_state == IPSA_STATE_IDLE);
6916
6917 ip_drop_packet(bpkt, B_TRUE, ira->ira_ill,
6918 DROPPER(ipss, ipds_sadb_inidle_overflow),
6919 &ipss->ipsec_sadb_dropper);
6920 return;
6921 }
6922
6923 /*
6924 * Stub function that taskq_dispatch() invokes to take the mblk (in arg)
6925 * and put into STREAMS again.
6926 */
6927 void
6928 sadb_clear_buf_pkt(void *ipkt)
6929 {
6930 mblk_t *tmp, *buf_pkt;
6931 ip_recv_attr_t iras;
6932
6933 buf_pkt = (mblk_t *)ipkt;
6934
6935 while (buf_pkt != NULL) {
6936 mblk_t *data_mp;
6937
6938 tmp = buf_pkt->b_next;
6939 buf_pkt->b_next = NULL;
6940
6941 data_mp = buf_pkt->b_cont;
6942 buf_pkt->b_cont = NULL;
6943 if (!ip_recv_attr_from_mblk(buf_pkt, &iras)) {
6944 /* The ill or ip_stack_t disappeared on us. */
6945 ip_drop_input("ip_recv_attr_from_mblk", data_mp, NULL);
6946 freemsg(data_mp);
6947 } else {
6948 ip_input_post_ipsec(data_mp, &iras);
6949 }
6950 ira_cleanup(&iras, B_TRUE);
6951 buf_pkt = tmp;
6952 }
6953 }
6954 /*
6955 * Walker callback used by sadb_alg_update() to free/create crypto
6956 * context template when a crypto software provider is removed or
6957 * added.
6958 */
6959
6960 struct sadb_update_alg_state {
6961 ipsec_algtype_t alg_type;
6962 uint8_t alg_id;
6963 boolean_t is_added;
6964 boolean_t async_auth;
6965 boolean_t async_encr;
6966 };
6967
6968 static void
6969 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
6970 {
6971 struct sadb_update_alg_state *update_state =
6972 (struct sadb_update_alg_state *)cookie;
6973 crypto_ctx_template_t *ctx_tmpl = NULL;
6974
6975 ASSERT(MUTEX_HELD(&head->isaf_lock));
6976
6977 if (entry->ipsa_state == IPSA_STATE_LARVAL)
6978 return;
6979
6980 mutex_enter(&entry->ipsa_lock);
6981
6982 if ((entry->ipsa_encr_alg != SADB_EALG_NONE && entry->ipsa_encr_alg !=
6983 SADB_EALG_NULL && update_state->async_encr) ||
6984 (entry->ipsa_auth_alg != SADB_AALG_NONE &&
6985 update_state->async_auth)) {
6986 entry->ipsa_flags |= IPSA_F_ASYNC;
6987 } else {
6988 entry->ipsa_flags &= ~IPSA_F_ASYNC;
6989 }
6990
6991 switch (update_state->alg_type) {
6992 case IPSEC_ALG_AUTH:
6993 if (entry->ipsa_auth_alg == update_state->alg_id)
6994 ctx_tmpl = &entry->ipsa_authtmpl;
6995 break;
6996 case IPSEC_ALG_ENCR:
6997 if (entry->ipsa_encr_alg == update_state->alg_id)
6998 ctx_tmpl = &entry->ipsa_encrtmpl;
6999 break;
7000 default:
7001 ctx_tmpl = NULL;
7002 }
7003
7004 if (ctx_tmpl == NULL) {
7005 mutex_exit(&entry->ipsa_lock);
7006 return;
7007 }
7008
7009 /*
7010 * The context template of the SA may be affected by the change
7011 * of crypto provider.
7012 */
7013 if (update_state->is_added) {
7014 /* create the context template if not already done */
7015 if (*ctx_tmpl == NULL) {
7016 (void) ipsec_create_ctx_tmpl(entry,
7017 update_state->alg_type);
7018 }
7019 } else {
7020 /*
7021 * The crypto provider was removed. If the context template
7022 * exists but it is no longer valid, free it.
7023 */
7024 if (*ctx_tmpl != NULL)
7025 ipsec_destroy_ctx_tmpl(entry, update_state->alg_type);
7026 }
7027
7028 mutex_exit(&entry->ipsa_lock);
7029 }
7030
7031 /*
7032 * Invoked by IP when an software crypto provider has been updated, or if
7033 * the crypto synchrony changes. The type and id of the corresponding
7034 * algorithm is passed as argument. The type is set to ALL in the case of
7035 * a synchrony change.
7036 *
7037 * is_added is B_TRUE if the provider was added, B_FALSE if it was
7038 * removed. The function updates the SADB and free/creates the
7039 * context templates associated with SAs if needed.
7040 */
7041
7042 #define SADB_ALG_UPDATE_WALK(sadb, table) \
7043 sadb_walker((sadb).table, (sadb).sdb_hashsize, sadb_alg_update_cb, \
7044 &update_state)
7045
7046 void
7047 sadb_alg_update(ipsec_algtype_t alg_type, uint8_t alg_id, boolean_t is_added,
7048 netstack_t *ns)
7049 {
7050 struct sadb_update_alg_state update_state;
7051 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
7052 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
7053 ipsec_stack_t *ipss = ns->netstack_ipsec;
7054
7055 update_state.alg_type = alg_type;
7056 update_state.alg_id = alg_id;
7057 update_state.is_added = is_added;
7058 update_state.async_auth = ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
7059 IPSEC_ALGS_EXEC_ASYNC;
7060 update_state.async_encr = ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
7061 IPSEC_ALGS_EXEC_ASYNC;
7062
7063 if (alg_type == IPSEC_ALG_AUTH || alg_type == IPSEC_ALG_ALL) {
7064 /* walk the AH tables only for auth. algorithm changes */
7065 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_of);
7066 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_if);
7067 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_of);
7068 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_if);
7069 }
7070
7071 /* walk the ESP tables */
7072 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_of);
7073 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_if);
7074 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_of);
7075 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_if);
7076 }
7077
7078 /*
7079 * Creates a context template for the specified SA. This function
7080 * is called when an SA is created and when a context template needs
7081 * to be created due to a change of software provider.
7082 */
7083 int
7084 ipsec_create_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7085 {
7086 ipsec_alginfo_t *alg;
7087 crypto_mechanism_t mech;
7088 crypto_key_t *key;
7089 crypto_ctx_template_t *sa_tmpl;
7090 int rv;
7091 ipsec_stack_t *ipss = sa->ipsa_netstack->netstack_ipsec;
7092
7093 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
7094 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7095
7096 /* get pointers to the algorithm info, context template, and key */
7097 switch (alg_type) {
7098 case IPSEC_ALG_AUTH:
7099 key = &sa->ipsa_kcfauthkey;
7100 sa_tmpl = &sa->ipsa_authtmpl;
7101 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_auth_alg];
7102 break;
7103 case IPSEC_ALG_ENCR:
7104 key = &sa->ipsa_kcfencrkey;
7105 sa_tmpl = &sa->ipsa_encrtmpl;
7106 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_encr_alg];
7107 break;
7108 default:
7109 alg = NULL;
7110 }
7111
7112 if (alg == NULL || !ALG_VALID(alg))
7113 return (EINVAL);
7114
7115 /* initialize the mech info structure for the framework */
7116 ASSERT(alg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
7117 mech.cm_type = alg->alg_mech_type;
7118 mech.cm_param = NULL;
7119 mech.cm_param_len = 0;
7120
7121 /* create a new context template */
7122 rv = crypto_create_ctx_template(&mech, key, sa_tmpl, KM_NOSLEEP);
7123
7124 /*
7125 * CRYPTO_MECH_NOT_SUPPORTED can be returned if only hardware
7126 * providers are available for that mechanism. In that case
7127 * we don't fail, and will generate the context template from
7128 * the framework callback when a software provider for that
7129 * mechanism registers.
7130 *
7131 * The context template is assigned the special value
7132 * IPSEC_CTX_TMPL_ALLOC if the allocation failed due to a
7133 * lack of memory. No attempt will be made to use
7134 * the context template if it is set to this value.
7135 */
7136 if (rv == CRYPTO_HOST_MEMORY) {
7137 *sa_tmpl = IPSEC_CTX_TMPL_ALLOC;
7138 } else if (rv != CRYPTO_SUCCESS) {
7139 *sa_tmpl = NULL;
7140 if (rv != CRYPTO_MECH_NOT_SUPPORTED)
7141 return (EINVAL);
7142 }
7143
7144 return (0);
7145 }
7146
7147 /*
7148 * Destroy the context template of the specified algorithm type
7149 * of the specified SA. Must be called while holding the SA lock.
7150 */
7151 void
7152 ipsec_destroy_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7153 {
7154 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7155
7156 if (alg_type == IPSEC_ALG_AUTH) {
7157 if (sa->ipsa_authtmpl == IPSEC_CTX_TMPL_ALLOC)
7158 sa->ipsa_authtmpl = NULL;
7159 else if (sa->ipsa_authtmpl != NULL) {
7160 crypto_destroy_ctx_template(sa->ipsa_authtmpl);
7161 sa->ipsa_authtmpl = NULL;
7162 }
7163 } else {
7164 ASSERT(alg_type == IPSEC_ALG_ENCR);
7165 if (sa->ipsa_encrtmpl == IPSEC_CTX_TMPL_ALLOC)
7166 sa->ipsa_encrtmpl = NULL;
7167 else if (sa->ipsa_encrtmpl != NULL) {
7168 crypto_destroy_ctx_template(sa->ipsa_encrtmpl);
7169 sa->ipsa_encrtmpl = NULL;
7170 }
7171 }
7172 }
7173
7174 /*
7175 * Use the kernel crypto framework to check the validity of a key received
7176 * via keysock. Returns 0 if the key is OK, -1 otherwise.
7177 */
7178 int
7179 ipsec_check_key(crypto_mech_type_t mech_type, sadb_key_t *sadb_key,
7180 boolean_t is_auth, int *diag)
7181 {
7182 crypto_mechanism_t mech;
7183 crypto_key_t crypto_key;
7184 int crypto_rc;
7185
7186 mech.cm_type = mech_type;
7187 mech.cm_param = NULL;
7188 mech.cm_param_len = 0;
7189
7190 crypto_key.ck_format = CRYPTO_KEY_RAW;
7191 crypto_key.ck_data = sadb_key + 1;
7192 crypto_key.ck_length = sadb_key->sadb_key_bits;
7193
7194 crypto_rc = crypto_key_check(&mech, &crypto_key);
7195
7196 switch (crypto_rc) {
7197 case CRYPTO_SUCCESS:
7198 return (0);
7199 case CRYPTO_MECHANISM_INVALID:
7200 case CRYPTO_MECH_NOT_SUPPORTED:
7201 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AALG :
7202 SADB_X_DIAGNOSTIC_BAD_EALG;
7203 break;
7204 case CRYPTO_KEY_SIZE_RANGE:
7205 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AKEYBITS :
7206 SADB_X_DIAGNOSTIC_BAD_EKEYBITS;
7207 break;
7208 case CRYPTO_WEAK_KEY:
7209 *diag = is_auth ? SADB_X_DIAGNOSTIC_WEAK_AKEY :
7210 SADB_X_DIAGNOSTIC_WEAK_EKEY;
7211 break;
7212 }
7213
7214 return (-1);
7215 }
7216
7217 /*
7218 * Whack options in the outer IP header when ipsec changes the outer label
7219 *
7220 * This is inelegant and really could use refactoring.
7221 */
7222 mblk_t *
7223 sadb_whack_label_v4(mblk_t *mp, ipsa_t *assoc, kstat_named_t *counter,
7224 ipdropper_t *dropper)
7225 {
7226 int delta;
7227 int plen;
7228 dblk_t *db;
7229 int hlen;
7230 uint8_t *opt_storage = assoc->ipsa_opt_storage;
7231 ipha_t *ipha = (ipha_t *)mp->b_rptr;
7232
7233 plen = ntohs(ipha->ipha_length);
7234
7235 delta = tsol_remove_secopt(ipha, MBLKL(mp));
7236 mp->b_wptr += delta;
7237 plen += delta;
7238
7239 /* XXX XXX code copied from tsol_check_label */
7240
7241 /* Make sure we have room for the worst-case addition */
7242 hlen = IPH_HDR_LENGTH(ipha) + opt_storage[IPOPT_OLEN];
7243 hlen = (hlen + 3) & ~3;
7244 if (hlen > IP_MAX_HDR_LENGTH)
7245 hlen = IP_MAX_HDR_LENGTH;
7246 hlen -= IPH_HDR_LENGTH(ipha);
7247
7248 db = mp->b_datap;
7249 if ((db->db_ref != 1) || (mp->b_wptr + hlen > db->db_lim)) {
7250 int copylen;
7251 mblk_t *new_mp;
7252
7253 /* allocate enough to be meaningful, but not *too* much */
7254 copylen = MBLKL(mp);
7255 if (copylen > 256)
7256 copylen = 256;
7257 new_mp = allocb_tmpl(hlen + copylen +
7258 (mp->b_rptr - mp->b_datap->db_base), mp);
7259
7260 if (new_mp == NULL) {
7261 ip_drop_packet(mp, B_FALSE, NULL, counter, dropper);
7262 return (NULL);
7263 }
7264
7265 /* keep the bias */
7266 new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
7267 new_mp->b_wptr = new_mp->b_rptr + copylen;
7268 bcopy(mp->b_rptr, new_mp->b_rptr, copylen);
7269 new_mp->b_cont = mp;
7270 if ((mp->b_rptr += copylen) >= mp->b_wptr) {
7271 new_mp->b_cont = mp->b_cont;
7272 freeb(mp);
7273 }
7274 mp = new_mp;
7275 ipha = (ipha_t *)mp->b_rptr;
7276 }
7277
7278 delta = tsol_prepend_option(assoc->ipsa_opt_storage, ipha, MBLKL(mp));
7279
7280 ASSERT(delta != -1);
7281
7282 plen += delta;
7283 mp->b_wptr += delta;
7284
7285 /*
7286 * Paranoia
7287 */
7288 db = mp->b_datap;
7289
7290 ASSERT3P(mp->b_wptr, <=, db->db_lim);
7291 ASSERT3P(mp->b_rptr, <=, db->db_lim);
7292
7293 ASSERT3P(mp->b_wptr, >=, db->db_base);
7294 ASSERT3P(mp->b_rptr, >=, db->db_base);
7295 /* End paranoia */
7296
7297 ipha->ipha_length = htons(plen);
7298
7299 return (mp);
7300 }
7301
7302 mblk_t *
7303 sadb_whack_label_v6(mblk_t *mp, ipsa_t *assoc, kstat_named_t *counter,
7304 ipdropper_t *dropper)
7305 {
7306 int delta;
7307 int plen;
7308 dblk_t *db;
7309 int hlen;
7310 uint8_t *opt_storage = assoc->ipsa_opt_storage;
7311 uint_t sec_opt_len; /* label option length not including type, len */
7312 ip6_t *ip6h = (ip6_t *)mp->b_rptr;
7313
7314 plen = ntohs(ip6h->ip6_plen);
7315
7316 delta = tsol_remove_secopt_v6(ip6h, MBLKL(mp));
7317 mp->b_wptr += delta;
7318 plen += delta;
7319
7320 /* XXX XXX code copied from tsol_check_label_v6 */
7321 /*
7322 * Make sure we have room for the worst-case addition. Add 2 bytes for
7323 * the hop-by-hop ext header's next header and length fields. Add
7324 * another 2 bytes for the label option type, len and then round
7325 * up to the next 8-byte multiple.
7326 */
7327 sec_opt_len = opt_storage[1];
7328
7329 db = mp->b_datap;
7330 hlen = (4 + sec_opt_len + 7) & ~7;
7331
7332 if ((db->db_ref != 1) || (mp->b_wptr + hlen > db->db_lim)) {
7333 int copylen;
7334 mblk_t *new_mp;
7335 uint16_t hdr_len;
7336
7337 hdr_len = ip_hdr_length_v6(mp, ip6h);
7338 /*
7339 * Allocate enough to be meaningful, but not *too* much.
7340 * Also all the IPv6 extension headers must be in the same mblk
7341 */
7342 copylen = MBLKL(mp);
7343 if (copylen > 256)
7344 copylen = 256;
7345 if (copylen < hdr_len)
7346 copylen = hdr_len;
7347 new_mp = allocb_tmpl(hlen + copylen +
7348 (mp->b_rptr - mp->b_datap->db_base), mp);
7349 if (new_mp == NULL) {
7350 ip_drop_packet(mp, B_FALSE, NULL, counter, dropper);
7351 return (NULL);
7352 }
7353
7354 /* keep the bias */
7355 new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
7356 new_mp->b_wptr = new_mp->b_rptr + copylen;
7357 bcopy(mp->b_rptr, new_mp->b_rptr, copylen);
7358 new_mp->b_cont = mp;
7359 if ((mp->b_rptr += copylen) >= mp->b_wptr) {
7360 new_mp->b_cont = mp->b_cont;
7361 freeb(mp);
7362 }
7363 mp = new_mp;
7364 ip6h = (ip6_t *)mp->b_rptr;
7365 }
7366
7367 delta = tsol_prepend_option_v6(assoc->ipsa_opt_storage,
7368 ip6h, MBLKL(mp));
7369
7370 ASSERT(delta != -1);
7371
7372 plen += delta;
7373 mp->b_wptr += delta;
7374
7375 /*
7376 * Paranoia
7377 */
7378 db = mp->b_datap;
7379
7380 ASSERT3P(mp->b_wptr, <=, db->db_lim);
7381 ASSERT3P(mp->b_rptr, <=, db->db_lim);
7382
7383 ASSERT3P(mp->b_wptr, >=, db->db_base);
7384 ASSERT3P(mp->b_rptr, >=, db->db_base);
7385 /* End paranoia */
7386
7387 ip6h->ip6_plen = htons(plen);
7388
7389 return (mp);
7390 }
7391
7392 /* Whack the labels and update ip_xmit_attr_t as needed */
7393 mblk_t *
7394 sadb_whack_label(mblk_t *mp, ipsa_t *assoc, ip_xmit_attr_t *ixa,
7395 kstat_named_t *counter, ipdropper_t *dropper)
7396 {
7397 int adjust;
7398 int iplen;
7399
7400 if (ixa->ixa_flags & IXAF_IS_IPV4) {
7401 ipha_t *ipha = (ipha_t *)mp->b_rptr;
7402
7403 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
7404 iplen = ntohs(ipha->ipha_length);
7405 mp = sadb_whack_label_v4(mp, assoc, counter, dropper);
7406 if (mp == NULL)
7407 return (NULL);
7408
7409 ipha = (ipha_t *)mp->b_rptr;
7410 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
7411 adjust = (int)ntohs(ipha->ipha_length) - iplen;
7412 } else {
7413 ip6_t *ip6h = (ip6_t *)mp->b_rptr;
7414
7415 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
7416 iplen = ntohs(ip6h->ip6_plen);
7417 mp = sadb_whack_label_v6(mp, assoc, counter, dropper);
7418 if (mp == NULL)
7419 return (NULL);
7420
7421 ip6h = (ip6_t *)mp->b_rptr;
7422 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
7423 adjust = (int)ntohs(ip6h->ip6_plen) - iplen;
7424 }
7425 ixa->ixa_pktlen += adjust;
7426 ixa->ixa_ip_hdr_length += adjust;
7427 return (mp);
7428 }
7429
7430 /*
7431 * If this is an outgoing SA then add some fuzz to the
7432 * SOFT EXPIRE time. The reason for this is to stop
7433 * peers trying to renegotiate SOFT expiring SA's at
7434 * the same time. The amount of fuzz needs to be at
7435 * least 8 seconds which is the typical interval
7436 * sadb_ager(), although this is only a guide as it
7437 * selftunes.
7438 */
7439 static void
7440 lifetime_fuzz(ipsa_t *assoc)
7441 {
7442 uint8_t rnd;
7443
7444 if (assoc->ipsa_softaddlt == 0)
7445 return;
7446
7447 (void) random_get_pseudo_bytes(&rnd, sizeof (rnd));
7448 rnd = (rnd & 0xF) + 8;
7449 assoc->ipsa_softexpiretime -= rnd;
7450 assoc->ipsa_softaddlt -= rnd;
7451 }
7452
7453 static void
7454 destroy_ipsa_pair(ipsap_t *ipsapp)
7455 {
7456 /*
7457 * Because of the multi-line macro nature of IPSA_REFRELE, keep
7458 * them in { }.
7459 */
7460 if (ipsapp->ipsap_sa_ptr != NULL) {
7461 IPSA_REFRELE(ipsapp->ipsap_sa_ptr);
7462 }
7463 if (ipsapp->ipsap_psa_ptr != NULL) {
7464 IPSA_REFRELE(ipsapp->ipsap_psa_ptr);
7465 }
7466 init_ipsa_pair(ipsapp);
7467 }
7468
7469 static void
7470 init_ipsa_pair(ipsap_t *ipsapp)
7471 {
7472 ipsapp->ipsap_bucket = NULL;
7473 ipsapp->ipsap_sa_ptr = NULL;
7474 ipsapp->ipsap_pbucket = NULL;
7475 ipsapp->ipsap_psa_ptr = NULL;
7476 }
7477
7478 /*
7479 * The sadb_ager() function walks through the hash tables of SA's and ages
7480 * them, if the SA expires as a result, its marked as DEAD and will be reaped
7481 * the next time sadb_ager() runs. SA's which are paired or have a peer (same
7482 * SA appears in both the inbound and outbound tables because its not possible
7483 * to determine its direction) are placed on a list when they expire. This is
7484 * to ensure that pair/peer SA's are reaped at the same time, even if they
7485 * expire at different times.
7486 *
7487 * This function is called twice by sadb_ager(), one after processing the
7488 * inbound table, then again after processing the outbound table.
7489 */
7490 void
7491 age_pair_peer_list(templist_t *haspeerlist, sadb_t *sp, boolean_t outbound)
7492 {
7493 templist_t *listptr;
7494 int outhash;
7495 isaf_t *bucket;
7496 boolean_t haspeer;
7497 ipsa_t *peer_assoc, *dying;
7498 /*
7499 * Haspeer cases will contain both IPv4 and IPv6. This code
7500 * is address independent.
7501 */
7502 while (haspeerlist != NULL) {
7503 /* "dying" contains the SA that has a peer. */
7504 dying = haspeerlist->ipsa;
7505 haspeer = (dying->ipsa_haspeer);
7506 listptr = haspeerlist;
7507 haspeerlist = listptr->next;
7508 kmem_free(listptr, sizeof (*listptr));
7509 /*
7510 * Pick peer bucket based on addrfam.
7511 */
7512 if (outbound) {
7513 if (haspeer)
7514 bucket = INBOUND_BUCKET(sp, dying->ipsa_spi);
7515 else
7516 bucket = INBOUND_BUCKET(sp,
7517 dying->ipsa_otherspi);
7518 } else { /* inbound */
7519 if (haspeer) {
7520 if (dying->ipsa_addrfam == AF_INET6) {
7521 outhash = OUTBOUND_HASH_V6(sp,
7522 *((in6_addr_t *)&dying->
7523 ipsa_dstaddr));
7524 } else {
7525 outhash = OUTBOUND_HASH_V4(sp,
7526 *((ipaddr_t *)&dying->
7527 ipsa_dstaddr));
7528 }
7529 } else if (dying->ipsa_addrfam == AF_INET6) {
7530 outhash = OUTBOUND_HASH_V6(sp,
7531 *((in6_addr_t *)&dying->
7532 ipsa_srcaddr));
7533 } else {
7534 outhash = OUTBOUND_HASH_V4(sp,
7535 *((ipaddr_t *)&dying->
7536 ipsa_srcaddr));
7537 }
7538 bucket = &(sp->sdb_of[outhash]);
7539 }
7540
7541 mutex_enter(&bucket->isaf_lock);
7542 /*
7543 * "haspeer" SA's have the same src/dst address ordering,
7544 * "paired" SA's have the src/dst addresses reversed.
7545 */
7546 if (haspeer) {
7547 peer_assoc = ipsec_getassocbyspi(bucket,
7548 dying->ipsa_spi, dying->ipsa_srcaddr,
7549 dying->ipsa_dstaddr, dying->ipsa_addrfam);
7550 } else {
7551 peer_assoc = ipsec_getassocbyspi(bucket,
7552 dying->ipsa_otherspi, dying->ipsa_dstaddr,
7553 dying->ipsa_srcaddr, dying->ipsa_addrfam);
7554 }
7555
7556 mutex_exit(&bucket->isaf_lock);
7557 if (peer_assoc != NULL) {
7558 mutex_enter(&peer_assoc->ipsa_lock);
7559 mutex_enter(&dying->ipsa_lock);
7560 if (!haspeer) {
7561 /*
7562 * Only SA's which have a "peer" or are
7563 * "paired" end up on this list, so this
7564 * must be a "paired" SA, update the flags
7565 * to break the pair.
7566 */
7567 peer_assoc->ipsa_otherspi = 0;
7568 peer_assoc->ipsa_flags &= ~IPSA_F_PAIRED;
7569 dying->ipsa_otherspi = 0;
7570 dying->ipsa_flags &= ~IPSA_F_PAIRED;
7571 }
7572 if (haspeer || outbound) {
7573 /*
7574 * Update the state of the "inbound" SA when
7575 * the "outbound" SA has expired. Don't update
7576 * the "outbound" SA when the "inbound" SA
7577 * SA expires because setting the hard_addtime
7578 * below will cause this to happen.
7579 */
7580 peer_assoc->ipsa_state = dying->ipsa_state;
7581 }
7582 if (dying->ipsa_state == IPSA_STATE_DEAD)
7583 peer_assoc->ipsa_hardexpiretime = 1;
7584
7585 mutex_exit(&dying->ipsa_lock);
7586 mutex_exit(&peer_assoc->ipsa_lock);
7587 IPSA_REFRELE(peer_assoc);
7588 }
7589 IPSA_REFRELE(dying);
7590 }
7591 }
7592
7593 /*
7594 * Ensure that the IV used for CCM mode never repeats. The IV should
7595 * only be updated by this function. Also check to see if the IV
7596 * is about to wrap and generate a SOFT Expire. This function is only
7597 * called for outgoing packets, the IV for incomming packets is taken
7598 * from the wire. If the outgoing SA needs to be expired, update
7599 * the matching incomming SA.
7600 */
7601 boolean_t
7602 update_iv(uint8_t *iv_ptr, queue_t *pfkey_q, ipsa_t *assoc,
7603 ipsecesp_stack_t *espstack)
7604 {
7605 boolean_t rc = B_TRUE;
7606 isaf_t *inbound_bucket;
7607 sadb_t *sp;
7608 ipsa_t *pair_sa = NULL;
7609 int sa_new_state = 0;
7610
7611 /* For non counter modes, the IV is random data. */
7612 if (!(assoc->ipsa_flags & IPSA_F_COUNTERMODE)) {
7613 (void) random_get_pseudo_bytes(iv_ptr, assoc->ipsa_iv_len);
7614 return (rc);
7615 }
7616
7617 mutex_enter(&assoc->ipsa_lock);
7618
7619 (*assoc->ipsa_iv)++;
7620
7621 if (*assoc->ipsa_iv == assoc->ipsa_iv_hardexpire) {
7622 sa_new_state = IPSA_STATE_DEAD;
7623 rc = B_FALSE;
7624 } else if (*assoc->ipsa_iv == assoc->ipsa_iv_softexpire) {
7625 if (assoc->ipsa_state != IPSA_STATE_DYING) {
7626 /*
7627 * This SA may have already been expired when its
7628 * PAIR_SA expired.
7629 */
7630 sa_new_state = IPSA_STATE_DYING;
7631 }
7632 }
7633 if (sa_new_state) {
7634 /*
7635 * If there is a state change, we need to update this SA
7636 * and its "pair", we can find the bucket for the "pair" SA
7637 * while holding the ipsa_t mutex, but we won't actually
7638 * update anything untill the ipsa_t mutex has been released
7639 * for _this_ SA.
7640 */
7641 assoc->ipsa_state = sa_new_state;
7642 if (assoc->ipsa_addrfam == AF_INET6) {
7643 sp = &espstack->esp_sadb.s_v6;
7644 } else {
7645 sp = &espstack->esp_sadb.s_v4;
7646 }
7647 inbound_bucket = INBOUND_BUCKET(sp, assoc->ipsa_otherspi);
7648 sadb_expire_assoc(pfkey_q, assoc);
7649 }
7650 if (rc == B_TRUE)
7651 bcopy(assoc->ipsa_iv, iv_ptr, assoc->ipsa_iv_len);
7652
7653 mutex_exit(&assoc->ipsa_lock);
7654
7655 if (sa_new_state) {
7656 /* Find the inbound SA, need to lock hash bucket. */
7657 mutex_enter(&inbound_bucket->isaf_lock);
7658 pair_sa = ipsec_getassocbyspi(inbound_bucket,
7659 assoc->ipsa_otherspi, assoc->ipsa_dstaddr,
7660 assoc->ipsa_srcaddr, assoc->ipsa_addrfam);
7661 mutex_exit(&inbound_bucket->isaf_lock);
7662 if (pair_sa != NULL) {
7663 mutex_enter(&pair_sa->ipsa_lock);
7664 pair_sa->ipsa_state = sa_new_state;
7665 mutex_exit(&pair_sa->ipsa_lock);
7666 IPSA_REFRELE(pair_sa);
7667 }
7668 }
7669
7670 return (rc);
7671 }
7672
7673 void
7674 ccm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7675 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7676 {
7677 uchar_t *nonce;
7678 crypto_mechanism_t *combined_mech;
7679 CK_AES_CCM_PARAMS *params;
7680
7681 combined_mech = (crypto_mechanism_t *)cm_mech;
7682 params = (CK_AES_CCM_PARAMS *)(combined_mech + 1);
7683 nonce = (uchar_t *)(params + 1);
7684 params->ulMACSize = assoc->ipsa_mac_len;
7685 params->ulNonceSize = assoc->ipsa_nonce_len;
7686 params->ulAuthDataSize = sizeof (esph_t);
7687 params->ulDataSize = data_len;
7688 params->nonce = nonce;
7689 params->authData = esph;
7690
7691 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7692 cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_CCM_PARAMS);
7693 cm_mech->combined_mech.cm_param = (caddr_t)params;
7694 /* See gcm_params_init() for comments. */
7695 bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
7696 nonce += assoc->ipsa_saltlen;
7697 bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
7698 crypto_data->cd_miscdata = NULL;
7699 }
7700
7701 /* ARGSUSED */
7702 void
7703 cbc_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7704 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7705 {
7706 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7707 cm_mech->combined_mech.cm_param_len = 0;
7708 cm_mech->combined_mech.cm_param = NULL;
7709 crypto_data->cd_miscdata = (char *)iv_ptr;
7710 }
7711
7712 /* ARGSUSED */
7713 void
7714 gcm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7715 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7716 {
7717 uchar_t *nonce;
7718 crypto_mechanism_t *combined_mech;
7719 CK_AES_GCM_PARAMS *params;
7720
7721 combined_mech = (crypto_mechanism_t *)cm_mech;
7722 params = (CK_AES_GCM_PARAMS *)(combined_mech + 1);
7723 nonce = (uchar_t *)(params + 1);
7724
7725 params->pIv = nonce;
7726 params->ulIvLen = assoc->ipsa_nonce_len;
7727 params->ulIvBits = SADB_8TO1(assoc->ipsa_nonce_len);
7728 params->pAAD = esph;
7729 params->ulAADLen = sizeof (esph_t);
7730 params->ulTagBits = SADB_8TO1(assoc->ipsa_mac_len);
7731
7732 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7733 cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
7734 cm_mech->combined_mech.cm_param = (caddr_t)params;
7735 /*
7736 * Create the nonce, which is made up of the salt and the IV.
7737 * Copy the salt from the SA and the IV from the packet.
7738 * For inbound packets we copy the IV from the packet because it
7739 * was set by the sending system, for outbound packets we copy the IV
7740 * from the packet because the IV in the SA may be changed by another
7741 * thread, the IV in the packet was created while holding a mutex.
7742 */
7743 bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
7744 nonce += assoc->ipsa_saltlen;
7745 bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
7746 crypto_data->cd_miscdata = NULL;
7747 }