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