FreeBSD/Linux Kernel Cross Reference
sys/netkey/key.c
1 /*----------------------------------------------------------------------
2 key.c : Key Management Engine for BSD
3
4 Copyright 1995 by Bao Phan, Randall Atkinson, & Dan McDonald,
5 All Rights Reserved. All Rights have been assigned to the US
6 Naval Research Laboratory (NRL). The NRL Copyright Notice and
7 License governs distribution and use of this software.
8
9 Patents are pending on this technology. NRL grants a license
10 to use this technology at no cost under the terms below with
11 the additional requirement that software, hardware, and
12 documentation relating to use of this technology must include
13 the note that:
14 This product includes technology developed at and
15 licensed from the Information Technology Division,
16 US Naval Research Laboratory.
17
18 ----------------------------------------------------------------------*/
19 /*----------------------------------------------------------------------
20 # @(#)COPYRIGHT 1.1a (NRL) 17 August 1995
21
22 COPYRIGHT NOTICE
23
24 All of the documentation and software included in this software
25 distribution from the US Naval Research Laboratory (NRL) are
26 copyrighted by their respective developers.
27
28 This software and documentation were developed at NRL by various
29 people. Those developers have each copyrighted the portions that they
30 developed at NRL and have assigned All Rights for those portions to
31 NRL. Outside the USA, NRL also has copyright on the software
32 developed at NRL. The affected files all contain specific copyright
33 notices and those notices must be retained in any derived work.
34
35 NRL LICENSE
36
37 NRL grants permission for redistribution and use in source and binary
38 forms, with or without modification, of the software and documentation
39 created at NRL provided that the following conditions are met:
40
41 1. Redistributions of source code must retain the above copyright
42 notice, this list of conditions and the following disclaimer.
43 2. Redistributions in binary form must reproduce the above copyright
44 notice, this list of conditions and the following disclaimer in the
45 documentation and/or other materials provided with the distribution.
46 3. All advertising materials mentioning features or use of this software
47 must display the following acknowledgement:
48
49 This product includes software developed at the Information
50 Technology Division, US Naval Research Laboratory.
51
52 4. Neither the name of the NRL nor the names of its contributors
53 may be used to endorse or promote products derived from this software
54 without specific prior written permission.
55
56 THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
57 IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
58 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
59 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
60 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
61 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
62 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
63 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
64 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
65 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67
68 The views and conclusions contained in the software and documentation
69 are those of the authors and should not be interpreted as representing
70 official policies, either expressed or implied, of the US Naval
71 Research Laboratory (NRL).
72
73 ----------------------------------------------------------------------*/
74
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/kernel.h>
78 #include <sys/domain.h>
79 #include <sys/mbuf.h>
80 #include <sys/proc.h>
81 #include <sys/protosw.h>
82 #include <sys/socket.h>
83 #include <sys/socketvar.h>
84 #include <sys/time.h>
85
86 #include <net/raw_cb.h>
87 #include <net/if.h>
88 #include <net/if_types.h>
89 #include <net/if_dl.h>
90 #include <net/route.h>
91
92 #include <netinet/in.h>
93 #include <netinet/in_var.h>
94 #include <netinet/if_ether.h>
95
96 #ifdef INET6
97 #include <netinet6/in6.h>
98 #include <netinet6/in6_var.h>
99 #endif /* INET6 */
100
101 #include <netkey/key.h>
102 #include <netkey/key_debug.h>
103
104 #define SOCKADDR struct sockaddr
105
106 #define KMALLOC(p, t, n) (p = (t) malloc((unsigned long)(n), M_SECA, M_DONTWAIT))
107 #define KFREE(p) free((caddr_t)p, M_SECA);
108
109 #define CRITICAL_DCL int critical_s;
110 #define CRITICAL_START critical_s = splnet()
111 #define CRITICAL_END splx(critical_s)
112
113 #define TIME_SECONDS time.tv_sec
114 #define CURRENT_PID curproc->p_pid
115
116 #define DEFARGS(arglist, args) arglist args;
117 #define AND ;
118
119 #ifdef INET6
120 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in6))
121 #else
122 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in))
123 #endif
124
125
126 /*
127 * Not clear whether these values should be
128 * tweakable at kernel config time.
129 */
130 #define KEYTBLSIZE 61
131 #define KEYALLOCTBLSIZE 61
132 #define SO2SPITBLSIZE 61
133
134 /*
135 * These values should be tweakable...
136 * perhaps by using sysctl
137 */
138
139 #define MAXLARVALTIME 240; /* Lifetime of a larval key table entry */
140 #define MAXKEYACQUIRE 1; /* Max number of key acquire messages sent */
141 /* per destination address */
142 #define MAXACQUIRETIME 15; /* Lifetime of acquire message */
143
144 /*
145 * Key engine tables and global variables
146 */
147
148 struct key_tblnode keytable[KEYTBLSIZE];
149 struct key_allocnode keyalloctbl[KEYALLOCTBLSIZE];
150 struct key_so2spinode so2spitbl[SO2SPITBLSIZE];
151
152 struct keyso_cb keyso_cb;
153 struct key_tblnode nullkeynode;
154 struct key_registry *keyregtable;
155 struct key_acquirelist *key_acquirelist;
156 u_long maxlarvallifetime = MAXLARVALTIME;
157 int maxkeyacquire = MAXKEYACQUIRE;
158 u_long maxacquiretime = MAXACQUIRETIME;
159
160 extern SOCKADDR key_addr;
161
162 #define ROUNDUP(a) \
163 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
164 #define ADVANCE(x, n) \
165 { x += ROUNDUP(n); }
166
167 static int my_addr __P((SOCKADDR *));
168 static int key_sendup __P((struct socket *, struct key_msghdr *));
169
170 /*----------------------------------------------------------------------
171 * key_secassoc2msghdr():
172 * Copy info from a security association into a key message buffer.
173 * Assume message buffer is sufficiently large to hold all security
174 * association information including src, dst, from, key and iv.
175 ----------------------------------------------------------------------*/
176 int
177 key_secassoc2msghdr(struct key_secassoc *secassoc,
178 struct key_msghdr *km,
179 struct key_msgdata *keyinfo)
180 {
181 char *cp;
182 DPRINTF(IDL_FINISHED, ("Entering key_secassoc2msghdr\n"));
183
184 if ((km == 0) || (keyinfo == 0) || (secassoc == 0))
185 return(-1);
186
187 km->type = secassoc->type;
188 km->state = secassoc->state;
189 km->label = secassoc->label;
190 km->spi = secassoc->spi;
191 km->keylen = secassoc->keylen;
192 km->ivlen = secassoc->ivlen;
193 km->algorithm = secassoc->algorithm;
194 km->lifetype = secassoc->lifetype;
195 km->lifetime1 = secassoc->lifetime1;
196 km->lifetime2 = secassoc->lifetime2;
197
198 /*
199 * Stuff src/dst/from/key/iv in buffer after
200 * the message header.
201 */
202 cp = (char *)(km + 1);
203
204 DPRINTF(IDL_FINISHED, ("sa2msghdr: 1\n"));
205 keyinfo->src = (SOCKADDR *)cp;
206 if (secassoc->src->sa_len) {
207 bcopy(secassoc->src, cp, secassoc->src->sa_len);
208 ADVANCE(cp, secassoc->src->sa_len);
209 } else {
210 bzero(cp, MAX_SOCKADDR_SZ);
211 ADVANCE(cp, MAX_SOCKADDR_SZ);
212 }
213
214 DPRINTF(IDL_FINISHED, ("sa2msghdr: 2\n"));
215 keyinfo->dst = (SOCKADDR *)cp;
216 if (secassoc->dst->sa_len) {
217 bcopy(secassoc->dst, cp, secassoc->dst->sa_len);
218 ADVANCE(cp, secassoc->dst->sa_len);
219 } else {
220 bzero(cp, MAX_SOCKADDR_SZ);
221 ADVANCE(cp, MAX_SOCKADDR_SZ);
222 }
223
224 DPRINTF(IDL_FINISHED, ("sa2msghdr: 3\n"));
225 keyinfo->from = (SOCKADDR *)cp;
226 if (secassoc->from->sa_len) {
227 bcopy(secassoc->from, cp, secassoc->from->sa_len);
228 ADVANCE(cp, secassoc->from->sa_len);
229 } else {
230 bzero(cp, MAX_SOCKADDR_SZ);
231 ADVANCE(cp, MAX_SOCKADDR_SZ);
232 }
233
234 DPRINTF(IDL_FINISHED, ("sa2msghdr: 4\n"));
235
236 keyinfo->key = cp;
237 keyinfo->keylen = secassoc->keylen;
238 if (secassoc->keylen) {
239 bcopy((char *)(secassoc->key), cp, secassoc->keylen);
240 ADVANCE(cp, secassoc->keylen);
241 }
242
243 DPRINTF(IDL_FINISHED, ("sa2msghdr: 5\n"));
244 keyinfo->iv = cp;
245 keyinfo->ivlen = secassoc->ivlen;
246 if (secassoc->ivlen) {
247 bcopy((char *)(secassoc->iv), cp, secassoc->ivlen);
248 ADVANCE(cp, secassoc->ivlen);
249 }
250
251 DDO(IDL_FINISHED,printf("msgbuf(len=%d):\n",(char *)cp - (char *)km));
252 DDO(IDL_FINISHED,dump_buf((char *)km, (char *)cp - (char *)km));
253 DPRINTF(IDL_FINISHED, ("sa2msghdr: 6\n"));
254 return(0);
255 }
256
257
258 /*----------------------------------------------------------------------
259 * key_msghdr2secassoc():
260 * Copy info from a key message buffer into a key_secassoc
261 * structure
262 ----------------------------------------------------------------------*/
263 int
264 key_msghdr2secassoc(struct key_secassoc *secassoc,
265 struct key_msghdr *km,
266 struct key_msgdata *keyinfo)
267 {
268 DPRINTF(IDL_FINISHED, ("Entering key_msghdr2secassoc\n"));
269
270 if ((km == 0) || (keyinfo == 0) || (secassoc == 0))
271 return(-1);
272
273 secassoc->len = sizeof(*secassoc);
274 secassoc->type = km->type;
275 secassoc->state = km->state;
276 secassoc->label = km->label;
277 secassoc->spi = km->spi;
278 secassoc->keylen = km->keylen;
279 secassoc->ivlen = km->ivlen;
280 secassoc->algorithm = km->algorithm;
281 secassoc->lifetype = km->lifetype;
282 secassoc->lifetime1 = km->lifetime1;
283 secassoc->lifetime2 = km->lifetime2;
284
285 if (keyinfo->src) {
286 KMALLOC(secassoc->src, SOCKADDR *, keyinfo->src->sa_len);
287 if (!secassoc->src) {
288 DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for src\n"));
289 return(-1);
290 }
291 bcopy((char *)keyinfo->src, (char *)secassoc->src,
292 keyinfo->src->sa_len);
293 } else
294 secassoc->src = NULL;
295
296 if (keyinfo->dst) {
297 KMALLOC(secassoc->dst, SOCKADDR *, keyinfo->dst->sa_len);
298 if (!secassoc->dst) {
299 DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for dst\n"));
300 return(-1);
301 }
302 bcopy((char *)keyinfo->dst, (char *)secassoc->dst,
303 keyinfo->dst->sa_len);
304 } else
305 secassoc->dst = NULL;
306
307 if (keyinfo->from) {
308 KMALLOC(secassoc->from, SOCKADDR *, keyinfo->from->sa_len);
309 if (!secassoc->from) {
310 DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for from\n"));
311 return(-1);
312 }
313 bcopy((char *)keyinfo->from, (char *)secassoc->from,
314 keyinfo->from->sa_len);
315 } else
316 secassoc->from = NULL;
317
318 /*
319 * Make copies of key and iv
320 */
321 if (secassoc->ivlen) {
322 KMALLOC(secassoc->iv, caddr_t, secassoc->ivlen);
323 if (secassoc->iv == 0) {
324 DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for iv\n"));
325 return(-1);
326 }
327 bcopy((char *)keyinfo->iv, (char *)secassoc->iv, secassoc->ivlen);
328 } else
329 secassoc->iv = NULL;
330
331 if (secassoc->keylen) {
332 KMALLOC(secassoc->key, caddr_t, secassoc->keylen);
333 if (secassoc->key == 0) {
334 DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for key\n"));
335 if (secassoc->iv)
336 KFREE(secassoc->iv);
337 return(-1);
338 }
339 bcopy((char *)keyinfo->key, (char *)secassoc->key, secassoc->keylen);
340 } else
341 secassoc->key = NULL;
342 return(0);
343 }
344
345
346 /*----------------------------------------------------------------------
347 * addrpart_equal():
348 * Determine if the address portion of two sockaddrs are equal.
349 * Currently handles only AF_INET and AF_INET6 address families.
350 ----------------------------------------------------------------------*/
351 static int
352 addrpart_equal(SOCKADDR *sa1, SOCKADDR *sa2)
353 {
354 if ((sa1->sa_family != sa2->sa_family) ||
355 (sa1->sa_len != sa2->sa_len))
356 return 0;
357
358 switch(sa1->sa_family) {
359 case AF_INET:
360 return (((struct sockaddr_in *)sa1)->sin_addr.s_addr ==
361 ((struct sockaddr_in *)sa2)->sin_addr.s_addr);
362 #ifdef INET6
363 case AF_INET6:
364 return (IN6_ADDR_EQUAL(((struct sockaddr_in6 *)sa1)->sin6_addr,
365 ((struct sockaddr_in6 *)sa2)->sin6_addr));
366 #endif /* INET6 */
367 }
368 return(0);
369 }
370
371 /*----------------------------------------------------------------------
372 * key_inittables():
373 * Allocate space and initialize key engine tables
374 ----------------------------------------------------------------------*/
375 int
376 key_inittables(void)
377 {
378 int i;
379
380 KMALLOC(keyregtable, struct key_registry *, sizeof(struct key_registry));
381 if (!keyregtable)
382 return -1;
383 bzero((char *)keyregtable, sizeof(struct key_registry));
384 KMALLOC(key_acquirelist, struct key_acquirelist *,
385 sizeof(struct key_acquirelist));
386 if (!key_acquirelist)
387 return -1;
388 bzero((char *)key_acquirelist, sizeof(struct key_acquirelist));
389 for (i = 0; i < KEYTBLSIZE; i++)
390 bzero((char *)&keytable[i], sizeof(struct key_tblnode));
391 for (i = 0; i < KEYALLOCTBLSIZE; i++)
392 bzero((char *)&keyalloctbl[i], sizeof(struct key_allocnode));
393 for (i = 0; i < SO2SPITBLSIZE; i++)
394 bzero((char *)&so2spitbl[i], sizeof(struct key_so2spinode));
395
396 return 0;
397 }
398
399 static int
400 key_freetables(void)
401 {
402 KFREE(keyregtable);
403 keyregtable = NULL;
404 KFREE(key_acquirelist);
405 key_acquirelist = NULL;
406 return 0;
407 }
408
409 /*----------------------------------------------------------------------
410 * key_gethashval():
411 * Determine keytable hash value.
412 ----------------------------------------------------------------------*/
413 static int
414 key_gethashval(char *buf, int len, int tblsize)
415 {
416 int i, j = 0;
417
418 /*
419 * Todo: Use word size xor and check for alignment
420 * and zero pad if necessary. Need to also pick
421 * a good hash function and table size.
422 */
423 if (len <= 0) {
424 DPRINTF(IDL_ERROR,("key_gethashval got bogus len!\n"));
425 return(-1);
426 }
427 for(i = 0; i < len; i++) {
428 j ^= (u_int8_t)(*(buf + i));
429 }
430 return (j % tblsize);
431 }
432
433
434 /*----------------------------------------------------------------------
435 * key_createkey():
436 * Create hash key for hash function
437 * key is: type+src+dst if keytype = 1
438 * type+src+dst+spi if keytype = 0
439 * Uses only the address portion of the src and dst sockaddrs to
440 * form key. Currently handles only AF_INET and AF_INET6 sockaddrs
441 ----------------------------------------------------------------------*/
442 static int
443 key_createkey(char *buf, u_int type, SOCKADDR *src, SOCKADDR *dst,
444 u_int32_t spi, u_int keytype)
445 {
446 char *cp, *p;
447
448 DPRINTF(IDL_FINISHED,("Entering key_createkey\n"));
449
450 if (!buf || !src || !dst)
451 return(-1);
452
453 cp = buf;
454 bcopy((char *)&type, cp, sizeof(type));
455 cp += sizeof(type);
456
457 #ifdef INET6
458 /*
459 * Assume only IPv4 and IPv6 addresses.
460 */
461 #define ADDRPART(a) \
462 ((a)->sa_family == AF_INET6) ? \
463 (char *)&(((struct sockaddr_in6 *)(a))->sin6_addr) : \
464 (char *)&(((struct sockaddr_in *)(a))->sin_addr)
465
466 #define ADDRSIZE(a) \
467 ((a)->sa_family == AF_INET6) ? sizeof(struct in_addr6) : \
468 sizeof(struct in_addr)
469 #else /* INET6 */
470 #define ADDRPART(a) (char *)&(((struct sockaddr_in *)(a))->sin_addr)
471 #define ADDRSIZE(a) sizeof(struct in_addr)
472 #endif /* INET6 */
473
474 DPRINTF(IDL_FINISHED,("src addr:\n"));
475 DDO(IDL_FINISHED,dump_smart_sockaddr(src));
476 DPRINTF(IDL_FINISHED,("dst addr:\n"));
477 DDO(IDL_FINISHED,dump_smart_sockaddr(dst));
478
479 p = ADDRPART(src);
480 bcopy(p, cp, ADDRSIZE(src));
481 cp += ADDRSIZE(src);
482
483 p = ADDRPART(dst);
484 bcopy(p, cp, ADDRSIZE(dst));
485 cp += ADDRSIZE(dst);
486
487 #undef ADDRPART
488 #undef ADDRSIZE
489
490 if (keytype == 0) {
491 bcopy((char *)&spi, cp, sizeof(spi));
492 cp += sizeof(spi);
493 }
494
495 DPRINTF(IDL_FINISHED,("hash key:\n"));
496 DDO(IDL_FINISHED, dump_buf(buf, cp - buf));
497 return(cp - buf);
498 }
499
500
501 /*----------------------------------------------------------------------
502 * key_sosearch():
503 * Search the so2spi table for the security association allocated to
504 * the socket. Returns pointer to a struct key_so2spinode which can
505 * be used to locate the security association entry in the keytable.
506 ----------------------------------------------------------------------*/
507 static struct key_so2spinode *
508 key_sosearch(u_int type, SOCKADDR *src, SOCKADDR *dst, struct socket *so)
509 {
510 struct key_so2spinode *np = 0;
511
512 if (!(src && dst)) {
513 DPRINTF(IDL_ERROR,("key_sosearch: got null src or dst pointer!\n"));
514 return(NULL);
515 }
516
517 for (np = so2spitbl[((u_int32_t)so) % SO2SPITBLSIZE].next; np; np = np->next) {
518 if ((so == np->socket) && (type == np->keynode->secassoc->type)
519 && addrpart_equal(src, np->keynode->secassoc->src)
520 && addrpart_equal(dst, np->keynode->secassoc->dst))
521 return(np);
522 }
523 return(NULL);
524 }
525
526
527 /*----------------------------------------------------------------------
528 * key_sodelete():
529 * Delete entries from the so2spi table.
530 * flag = 1 purge all entries
531 * flag = 0 delete entries with socket pointer matching socket
532 ----------------------------------------------------------------------*/
533 static void
534 key_sodelete(struct socket *socket, int flag)
535 {
536 struct key_so2spinode *prevnp, *np;
537 CRITICAL_DCL
538
539 CRITICAL_START;
540
541 DPRINTF(IDL_EVENT,("Entering keysodelete w/so=0x%x flag=%d\n",
542 (unsigned int)socket,flag));
543
544 if (flag) {
545 int i;
546
547 for (i = 0; i < SO2SPITBLSIZE; i++)
548 for(np = so2spitbl[i].next; np; np = np->next) {
549 KFREE(np);
550 }
551 CRITICAL_END;
552 return;
553 }
554
555 prevnp = &so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE];
556 for(np = prevnp->next; np; np = np->next) {
557 if (np->socket == socket) {
558 struct socketlist *socklp, *prevsocklp;
559
560 (np->keynode->alloc_count)--;
561
562 /*
563 * If this socket maps to a unique secassoc,
564 * we go ahead and delete the secassoc, since it
565 * can no longer be allocated or used by any other
566 * socket.
567 */
568 if (np->keynode->secassoc->state & K_UNIQUE) {
569 if (key_delete(np->keynode->secassoc) != 0)
570 panic("key_sodelete");
571 np = prevnp;
572 continue;
573 }
574
575 /*
576 * We traverse the socketlist and remove the entry
577 * for this socket
578 */
579 DPRINTF(IDL_FINISHED,("keysodelete: deleting from socklist..."));
580 prevsocklp = np->keynode->solist;
581 for (socklp = prevsocklp->next; socklp; socklp = socklp->next) {
582 if (socklp->socket == socket) {
583 prevsocklp->next = socklp->next;
584 KFREE(socklp);
585 break;
586 }
587 prevsocklp = socklp;
588 }
589 DPRINTF(IDL_FINISHED,("done\n"));
590 prevnp->next = np->next;
591 KFREE(np);
592 np = prevnp;
593 }
594 prevnp = np;
595 }
596 CRITICAL_END;
597 }
598
599
600 /*----------------------------------------------------------------------
601 * key_deleteacquire():
602 * Delete an entry from the key_acquirelist
603 ----------------------------------------------------------------------*/
604 static void
605 key_deleteacquire(u_int type, SOCKADDR *target)
606 {
607 struct key_acquirelist *ap, *prev;
608
609 prev = key_acquirelist;
610 for(ap = key_acquirelist->next; ap; ap = ap->next) {
611 if (addrpart_equal(target, (SOCKADDR *)&(ap->target)) &&
612 (type == ap->type)) {
613 DPRINTF(IDL_EVENT,("Deleting entry from acquire list!\n"));
614 prev->next = ap->next;
615 KFREE(ap);
616 ap = prev;
617 }
618 prev = ap;
619 }
620 }
621
622
623 /*----------------------------------------------------------------------
624 * key_search():
625 * Search the key table for an entry with same type, src addr, dest
626 * addr, and spi. Returns a pointer to struct key_tblnode if found
627 * else returns null.
628 ----------------------------------------------------------------------*/
629 static struct key_tblnode *
630 key_search(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi,
631 int indx, struct key_tblnode **prevkeynode)
632 {
633 struct key_tblnode *keynode, *prevnode;
634
635 if (indx > KEYTBLSIZE || indx < 0)
636 return (NULL);
637 if (!(&keytable[indx]))
638 return (NULL);
639
640 #define sec_type keynode->secassoc->type
641 #define sec_spi keynode->secassoc->spi
642 #define sec_src keynode->secassoc->src
643 #define sec_dst keynode->secassoc->dst
644
645 prevnode = &keytable[indx];
646 for (keynode = keytable[indx].next; keynode; keynode = keynode->next) {
647 if ((type == sec_type) && (spi == sec_spi) &&
648 addrpart_equal(src, sec_src)
649 && addrpart_equal(dst, sec_dst))
650 break;
651 prevnode = keynode;
652 }
653 *prevkeynode = prevnode;
654 return(keynode);
655 }
656
657
658 /*----------------------------------------------------------------------
659 * key_addnode():
660 * Insert a key_tblnode entry into the key table. Returns a pointer
661 * to the newly created key_tblnode.
662 ----------------------------------------------------------------------*/
663 static struct key_tblnode *
664 key_addnode(int indx, struct key_secassoc *secassoc)
665 {
666 struct key_tblnode *keynode;
667
668 DPRINTF(IDL_FINISHED,("Entering key_addnode w/indx=%d secassoc=0x%x\n",
669 indx, (unsigned int)secassoc));
670
671 if (!(&keytable[indx]))
672 return(NULL);
673 if (!secassoc) {
674 panic("key_addnode: Someone passed in a null secassoc!\n");
675 }
676
677 KMALLOC(keynode, struct key_tblnode *, sizeof(struct key_tblnode));
678 if (keynode == 0)
679 return(NULL);
680 bzero((char *)keynode, sizeof(struct key_tblnode));
681
682 KMALLOC(keynode->solist, struct socketlist *, sizeof(struct socketlist));
683 if (keynode->solist == 0) {
684 KFREE(keynode);
685 return(NULL);
686 }
687 bzero((char *)(keynode->solist), sizeof(struct socketlist));
688
689 keynode->secassoc = secassoc;
690 keynode->solist->next = NULL;
691 keynode->next = keytable[indx].next;
692 keytable[indx].next = keynode;
693 return(keynode);
694 }
695
696
697 /*----------------------------------------------------------------------
698 * key_add():
699 * Add a new security association to the key table. Caller is
700 * responsible for allocating memory for the key_secassoc as
701 * well as the buffer space for the key, iv. Assumes the security
702 * association passed in is well-formed.
703 ----------------------------------------------------------------------*/
704 int
705 key_add(struct key_secassoc *secassoc)
706 {
707 char buf[MAXHASHKEYLEN];
708 int len, indx;
709 int inbound = 0;
710 int outbound = 0;
711 struct key_tblnode *keynode, *prevkeynode;
712 struct key_allocnode *np = NULL;
713 CRITICAL_DCL
714
715 DPRINTF(IDL_FINISHED, ("Entering key_add w/secassoc=0x%x\n",
716 (unsigned int)secassoc));
717
718 if (!secassoc) {
719 panic("key_add: who the hell is passing me a null pointer");
720 }
721
722 /*
723 * Should we allow a null key to be inserted into the table ?
724 * or can we use null key to indicate some policy action...
725 */
726
727 #if 0
728 /*
729 * For esp using des-cbc or tripple-des we call
730 * des_set_odd_parity.
731 */
732 if (secassoc->key && (secassoc->type == KEY_TYPE_ESP) &&
733 ((secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) ||
734 (secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES)))
735 des_set_odd_parity(secassoc->key);
736 #endif /* 0 */
737
738 /*
739 * Check if secassoc with same spi exists before adding
740 */
741 bzero((char *)&buf, sizeof(buf));
742 len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
743 secassoc->dst, secassoc->spi, 0);
744 indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
745 DPRINTF(IDL_FINISHED,("keyadd: keytbl hash position=%d\n", indx));
746 keynode = key_search(secassoc->type, secassoc->src, secassoc->dst,
747 secassoc->spi, indx, &prevkeynode);
748 if (keynode) {
749 DPRINTF(IDL_EVENT,("keyadd: secassoc already exists!\n"));
750 return(-2);
751 }
752
753 inbound = my_addr(secassoc->dst);
754 outbound = my_addr(secassoc->src);
755 DPRINTF(IDL_FINISHED,("inbound=%d outbound=%d\n", inbound, outbound));
756
757 /*
758 * We allocate mem for an allocation entry if needed.
759 * This is done here instead of in the allocaton code
760 * segment so that we can easily recover/cleanup from a
761 * memory allocation error.
762 */
763 if (outbound || (!inbound && !outbound)) {
764 KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode));
765 if (np == 0) {
766 DPRINTF(IDL_ERROR,("keyadd: can't allocate allocnode!\n"));
767 return(-1);
768 }
769 }
770
771 CRITICAL_START;
772
773 if ((keynode = key_addnode(indx, secassoc)) == NULL) {
774 DPRINTF(IDL_ERROR,("keyadd: key_addnode failed!\n"));
775 if (np)
776 KFREE(np);
777 CRITICAL_END;
778 return(-1);
779 }
780 DPRINTF(IDL_GROSS_EVENT,("Added new keynode:\n"));
781 DDO(IDL_FINISHED, dump_keytblnode(keynode));
782 DDO(IDL_FINISHED, dump_secassoc(keynode->secassoc));
783
784 /*
785 * We add an entry to the allocation table for
786 * this secassoc if the interfaces are up,
787 * the secassoc is outbound. In the case
788 * where the interfaces are not up, we go ahead
789 * , do it anyways. This wastes an allocation
790 * entry if the secassoc later turned out to be
791 * inbound when the interfaces are ifconfig up.
792 */
793 if (outbound || (!inbound && !outbound)) {
794 len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
795 secassoc->dst, 0, 1);
796 indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
797 DPRINTF(IDL_FINISHED,("keyadd: keyalloc hash position=%d\n", indx));
798 np->keynode = keynode;
799 np->next = keyalloctbl[indx].next;
800 keyalloctbl[indx].next = np;
801 }
802 if (inbound)
803 secassoc->state |= K_INBOUND;
804 if (outbound)
805 secassoc->state |= K_OUTBOUND;
806
807 key_deleteacquire(secassoc->type, secassoc->dst);
808
809 CRITICAL_END;
810 return 0;
811 }
812
813
814 /*----------------------------------------------------------------------
815 * key_get():
816 * Get a security association from the key table.
817 ----------------------------------------------------------------------*/
818 int
819 key_get(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi,
820 struct key_secassoc **secassoc)
821 {
822 char buf[MAXHASHKEYLEN];
823 struct key_tblnode *keynode, *prevkeynode;
824 int len, indx;
825
826 bzero(&buf, sizeof(buf));
827 *secassoc = NULL;
828 len = key_createkey((char *)&buf, type, src, dst, spi, 0);
829 indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
830 DPRINTF(IDL_FINISHED,("keyget: indx=%d\n",indx));
831 keynode = key_search(type, src, dst, spi, indx, &prevkeynode);
832 if (keynode) {
833 DPRINTF(IDL_GROSS_EVENT,("keyget: found it! keynode=0x%x",
834 (unsigned int)keynode));
835 *secassoc = keynode->secassoc;
836 return(0);
837 } else
838 return(-1); /* Not found */
839 }
840
841
842 /*----------------------------------------------------------------------
843 * key_dump():
844 * Dump all valid entries in the keytable to a pf_key socket. Each
845 * security associaiton is sent one at a time in a pf_key message. A
846 * message with seqno = 0 signifies the end of the dump transaction.
847 ----------------------------------------------------------------------*/
848 int
849 key_dump(struct socket *so)
850 {
851 int len, i;
852 int seq = 1;
853 struct key_msgdata keyinfo;
854 struct key_msghdr *km;
855 struct key_tblnode *keynode;
856
857 /*
858 * Routine to dump the key table to a routing socket
859 * Use for debugging only!
860 */
861
862 KMALLOC(km, struct key_msghdr *, sizeof(struct key_msghdr) +
863 3 * MAX_SOCKADDR_SZ + MAX_KEY_SZ + MAX_IV_SZ);
864 if (!km)
865 return(ENOBUFS);
866
867 DPRINTF(IDL_FINISHED,("Entering key_dump()"));
868 /*
869 * We need to speed this up later. Fortunately, key_dump
870 * messages are not sent often.
871 */
872 for (i = 0; i < KEYTBLSIZE; i++) {
873 for (keynode = keytable[i].next; keynode; keynode = keynode->next) {
874 /*
875 * We exclude dead/larval/zombie security associations for now
876 * but it may be useful to also send these up for debugging purposes
877 */
878 if (keynode->secassoc->state & (K_DEAD | K_LARVAL | K_ZOMBIE))
879 continue;
880
881 len = (sizeof(struct key_msghdr) +
882 ROUNDUP(keynode->secassoc->src->sa_len) +
883 ROUNDUP(keynode->secassoc->dst->sa_len) +
884 ROUNDUP(keynode->secassoc->from->sa_len) +
885 ROUNDUP(keynode->secassoc->keylen) +
886 ROUNDUP(keynode->secassoc->ivlen));
887
888 if (key_secassoc2msghdr(keynode->secassoc, km, &keyinfo) != 0)
889 panic("key_dump");
890
891 km->key_msglen = len;
892 km->key_msgvers = KEY_VERSION;
893 km->key_msgtype = KEY_DUMP;
894 km->key_pid = CURRENT_PID;
895 km->key_seq = seq++;
896 km->key_errno = 0;
897
898 key_sendup(so, km);
899 }
900 }
901 bzero((char *)km, sizeof(struct key_msghdr));
902 km->key_msglen = sizeof(struct key_msghdr);
903 km->key_msgvers = KEY_VERSION;
904 km->key_msgtype = KEY_DUMP;
905 km->key_pid = CURRENT_PID;
906 km->key_seq = 0;
907 km->key_errno = 0;
908
909 key_sendup(so, km);
910 KFREE(km);
911 DPRINTF(IDL_FINISHED,("Leaving key_dump()\n"));
912 return(0);
913 }
914
915 /*----------------------------------------------------------------------
916 * key_delete():
917 * Delete a security association from the key table.
918 ----------------------------------------------------------------------*/
919 int
920 key_delete(struct key_secassoc *secassoc)
921 {
922 char buf[MAXHASHKEYLEN];
923 int len, indx;
924 struct key_tblnode *keynode = 0;
925 struct key_tblnode *prevkeynode = 0;
926 struct socketlist *socklp, *deadsocklp;
927 struct key_so2spinode *np, *prevnp;
928 struct key_allocnode *ap, *prevap;
929 CRITICAL_DCL
930
931 DPRINTF(IDL_FINISHED,("Entering key_delete w/secassoc=0x%x\n",
932 (unsigned int)secassoc));
933
934 bzero((char *)&buf, sizeof(buf));
935 len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
936 secassoc->dst, secassoc->spi, 0);
937 indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
938 DPRINTF(IDL_FINISHED,("keydelete: keytbl hash position=%d\n", indx));
939 keynode = key_search(secassoc->type, secassoc->src, secassoc->dst,
940 secassoc->spi, indx, &prevkeynode);
941
942 if (keynode) {
943 CRITICAL_START;
944 DPRINTF(IDL_GROSS_EVENT,("keydelete: found keynode to delete\n"));
945 keynode->secassoc->state |= K_DEAD;
946
947 if (keynode->ref_count > 0) {
948 DPRINTF(IDL_EVENT,("keydelete: secassoc still held, marking for deletion only!\n"));
949 CRITICAL_END;
950 return(0);
951 }
952
953 prevkeynode->next = keynode->next;
954
955 /*
956 * Walk the socketlist, delete the
957 * entries mapping sockets to this secassoc
958 * from the so2spi table.
959 */
960 DPRINTF(IDL_FINISHED,("keydelete: deleting socklist..."));
961 for(socklp = keynode->solist->next; socklp; ) {
962 prevnp = &so2spitbl[((u_int32_t)(socklp->socket)) % SO2SPITBLSIZE];
963 for(np = prevnp->next; np; np = np->next) {
964 if ((np->socket == socklp->socket) && (np->keynode == keynode)) {
965 prevnp->next = np->next;
966 KFREE(np);
967 break;
968 }
969 prevnp = np;
970 }
971 deadsocklp = socklp;
972 socklp = socklp->next;
973 KFREE(deadsocklp);
974 }
975 DPRINTF(IDL_FINISHED,("done\n"));
976 /*
977 * If an allocation entry exist for this
978 * secassoc, delete it.
979 */
980 bzero((char *)&buf, sizeof(buf));
981 len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
982 secassoc->dst, 0, 1);
983 indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
984 DPRINTF(IDL_FINISHED,("keydelete: alloctbl hash position=%d\n", indx));
985 prevap = &keyalloctbl[indx];
986 for (ap = prevap->next; ap; ap = ap->next) {
987 if (ap->keynode == keynode) {
988 prevap->next = ap->next;
989 KFREE(ap);
990 break;
991 }
992 prevap = ap;
993 }
994
995 if (keynode->secassoc->iv)
996 KFREE(keynode->secassoc->iv);
997 if (keynode->secassoc->key)
998 KFREE(keynode->secassoc->key);
999 KFREE(keynode->secassoc);
1000 if (keynode->solist)
1001 KFREE(keynode->solist);
1002 KFREE(keynode);
1003 CRITICAL_END;
1004 return(0);
1005 }
1006 return(-1);
1007 }
1008
1009
1010 /*----------------------------------------------------------------------
1011 * key_flush():
1012 * Delete all entries from the key table.
1013 ----------------------------------------------------------------------*/
1014 void
1015 key_flush(void)
1016 {
1017 struct key_tblnode *keynode;
1018 int i;
1019
1020 /*
1021 * This is slow, but simple.
1022 */
1023 DPRINTF(IDL_FINISHED,("Flushing key table..."));
1024 for (i = 0; i < KEYTBLSIZE; i++) {
1025 while ((keynode = keytable[i].next))
1026 if (key_delete(keynode->secassoc) != 0)
1027 panic("key_flush");
1028 }
1029 DPRINTF(IDL_FINISHED,("done\n"));
1030 }
1031
1032
1033 /*----------------------------------------------------------------------
1034 * key_getspi():
1035 * Get a unique spi value for a key management daemon/program. The
1036 * spi value, once assigned, cannot be assigned again (as long as the
1037 * entry with that same spi value remains in the table).
1038 ----------------------------------------------------------------------*/
1039 int
1040 key_getspi(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t lowval,
1041 u_int32_t highval, u_int32_t *spi)
1042 {
1043 struct key_secassoc *secassoc;
1044 struct key_tblnode *keynode, *prevkeynode;
1045 int count, done, len, indx;
1046 int maxcount = 1000;
1047 u_int32_t val;
1048 char buf[MAXHASHKEYLEN];
1049 CRITICAL_DCL
1050
1051 DPRINTF(IDL_EVENT,("Entering getspi w/type=%d,low=%u,high=%u\n",
1052 type, lowval, highval));
1053 if (!(src && dst))
1054 return(EINVAL);
1055
1056 if ((lowval == 0) || (highval == 0))
1057 return(EINVAL);
1058
1059 if (lowval > highval) {
1060 u_int32_t temp;
1061 temp = lowval;
1062 lowval = highval;
1063 highval = lowval;
1064 }
1065
1066 done = count = 0;
1067 do {
1068 count++;
1069 /*
1070 * This may not be "random enough".
1071 */
1072 val = lowval + (random() % (highval - lowval + 1));
1073
1074 if (lowval == highval)
1075 count = maxcount;
1076 DPRINTF(IDL_FINISHED,("%u ",val));
1077 if (val) {
1078 DPRINTF(IDL_FINISHED,("\n"));
1079 bzero(&buf, sizeof(buf));
1080 len = key_createkey((char *)&buf, type, src, dst, val, 0);
1081 indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
1082 if (!key_search(type, src, dst, val, indx, &prevkeynode)) {
1083 CRITICAL_START;
1084 KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc));
1085 if (secassoc == 0) {
1086 DPRINTF(IDL_ERROR,("key_getspi: can't allocate memory\n"));
1087 CRITICAL_END;
1088 return(ENOBUFS);
1089 }
1090 bzero((char *)secassoc, sizeof(*secassoc));
1091
1092 DPRINTF(IDL_FINISHED,("getspi: indx=%d\n",indx));
1093 secassoc->len = sizeof(struct key_secassoc);
1094 secassoc->type = type;
1095 secassoc->spi = val;
1096 secassoc->state |= K_LARVAL;
1097 if (my_addr(secassoc->dst))
1098 secassoc->state |= K_INBOUND;
1099 if (my_addr(secassoc->src))
1100 secassoc->state |= K_OUTBOUND;
1101
1102 bcopy((char *)src, (char *)secassoc->src, src->sa_len);
1103 bcopy((char *)dst, (char *)secassoc->dst, dst->sa_len);
1104
1105 /* We fill this in with a plausable value now to insure
1106 that other routines don't break. These will get
1107 overwritten later with the correct values. */
1108 #ifdef INET6
1109 secassoc->from->sa_family = AF_INET6;
1110 secassoc->from->sa_len = sizeof(struct sockaddr_in6);
1111 #else /* INET6 */
1112 secassoc->from->sa_family = AF_INET;
1113 secassoc->from->sa_len = sizeof(struct sockaddr_in);
1114 #endif /* INET6 */
1115
1116 /*
1117 * We need to add code to age these larval key table
1118 * entries so they don't linger forever waiting for
1119 * a KEY_UPDATE message that may not come for various
1120 * reasons. This is another task that key_reaper can
1121 * do once we have it coded.
1122 */
1123 secassoc->lifetime1 += TIME_SECONDS + maxlarvallifetime;
1124
1125 if (!(keynode = key_addnode(indx, secassoc))) {
1126 DPRINTF(IDL_ERROR,("key_getspi: can't add node\n"));
1127 CRITICAL_END;
1128 return(ENOBUFS);
1129 }
1130 DPRINTF(IDL_FINISHED,("key_getspi: added node 0x%x\n",
1131 (unsigned int)keynode));
1132 done++;
1133 CRITICAL_END;
1134 }
1135 }
1136 } while ((count < maxcount) && !done);
1137 DPRINTF(IDL_EVENT,("getspi returns w/spi=%u,count=%d\n",val,count));
1138 if (done) {
1139 *spi = val;
1140 return(0);
1141 } else {
1142 *spi = 0;
1143 return(EADDRNOTAVAIL);
1144 }
1145 }
1146
1147
1148 /*----------------------------------------------------------------------
1149 * key_update():
1150 * Update a keytable entry that has an spi value assigned but is
1151 * incomplete (e.g. no key/iv).
1152 ----------------------------------------------------------------------*/
1153 int
1154 key_update(struct key_secassoc *secassoc)
1155 {
1156 struct key_tblnode *keynode, *prevkeynode;
1157 struct key_allocnode *np = 0;
1158 u_int8_t newstate;
1159 int len, indx, inbound, outbound;
1160 char buf[MAXHASHKEYLEN];
1161 CRITICAL_DCL
1162
1163 bzero(&buf, sizeof(buf));
1164 len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
1165 secassoc->dst, secassoc->spi, 0);
1166 indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
1167 if(!(keynode = key_search(secassoc->type, secassoc->src, secassoc->dst,
1168 secassoc->spi, indx, &prevkeynode))) {
1169 return(ESRCH);
1170 }
1171 if (keynode->secassoc->state & K_DEAD)
1172 return(ESRCH);
1173
1174 /* Should we also restrict updating of only LARVAL entries ? */
1175
1176 CRITICAL_START;
1177
1178 inbound = my_addr(secassoc->dst);
1179 outbound = my_addr(secassoc->src);
1180
1181 newstate = keynode->secassoc->state;
1182 newstate &= ~K_LARVAL;
1183
1184 if (inbound)
1185 newstate |= K_INBOUND;
1186 if (outbound)
1187 newstate |= K_OUTBOUND;
1188
1189 if (outbound || (!inbound && !outbound)) {
1190 KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode));
1191 if (np == 0) {
1192 DPRINTF(IDL_ERROR,("keyupdate: can't allocate allocnode!\n"));
1193 CRITICAL_END;
1194 return(ENOBUFS);
1195 }
1196 }
1197
1198 /*
1199 * Free the old key, iv if they're there.
1200 */
1201 if (keynode->secassoc->key)
1202 KFREE(keynode->secassoc->key);
1203 if (keynode->secassoc->iv)
1204 KFREE(keynode->secassoc->iv);
1205
1206 /*
1207 * We now copy the secassoc over. We don't need to copy
1208 * the key, iv into new buffers since the calling routine
1209 * does that already.
1210 */
1211
1212 *(keynode->secassoc) = *secassoc;
1213 keynode->secassoc->state = newstate;
1214
1215 /*
1216 * Should we allow a null key to be inserted into the table ?
1217 * or can we use null key to indicate some policy action...
1218 */
1219
1220 #if 0
1221 if (keynode->secassoc->key &&
1222 (keynode->secassoc->type == KEY_TYPE_ESP) &&
1223 ((keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) ||
1224 (keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES)))
1225 des_set_odd_parity(keynode->secassoc->key);
1226 #endif /* 0 */
1227
1228 /*
1229 * We now add an entry to the allocation table for this
1230 * updated key table entry.
1231 */
1232 if (outbound || (!inbound && !outbound)) {
1233 len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
1234 secassoc->dst, 0, 1);
1235 indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
1236 DPRINTF(IDL_FINISHED,("keyupdate: keyalloc hash position=%d\n", indx));
1237 np->keynode = keynode;
1238 np->next = keyalloctbl[indx].next;
1239 keyalloctbl[indx].next = np;
1240 }
1241
1242 key_deleteacquire(secassoc->type, (SOCKADDR *)&(secassoc->dst));
1243
1244 CRITICAL_END;
1245 return(0);
1246 }
1247
1248 /*----------------------------------------------------------------------
1249 * key_register():
1250 * Register a socket as one capable of acquiring security associations
1251 * for the kernel.
1252 ----------------------------------------------------------------------*/
1253 int
1254 key_register(struct socket *socket, u_int type)
1255 {
1256 struct key_registry *p, *new;
1257 CRITICAL_DCL
1258
1259 CRITICAL_START;
1260
1261 DPRINTF(IDL_EVENT,("Entering key_register w/so=0x%x,type=%d\n",
1262 (unsigned int)socket,type));
1263
1264 if (!(keyregtable && socket))
1265 panic("key_register");
1266
1267 /*
1268 * Make sure entry is not already in table
1269 */
1270 for(p = keyregtable->next; p; p = p->next) {
1271 if ((p->type == type) && (p->socket == socket)) {
1272 CRITICAL_END;
1273 return(EEXIST);
1274 }
1275 }
1276
1277 KMALLOC(new, struct key_registry *, sizeof(struct key_registry));
1278 if (new == 0) {
1279 CRITICAL_END;
1280 return(ENOBUFS);
1281 }
1282 new->type = type;
1283 new->socket = socket;
1284 new->next = keyregtable->next;
1285 keyregtable->next = new;
1286 CRITICAL_END;
1287 return(0);
1288 }
1289
1290 /*----------------------------------------------------------------------
1291 * key_unregister():
1292 * Delete entries from the registry list.
1293 * allflag = 1 : delete all entries with matching socket
1294 * allflag = 0 : delete only the entry matching socket, type
1295 ----------------------------------------------------------------------*/
1296 void
1297 key_unregister(struct socket *socket, u_int type, int allflag)
1298 {
1299 struct key_registry *p, *prev;
1300 CRITICAL_DCL
1301
1302 CRITICAL_START;
1303
1304 DPRINTF(IDL_EVENT,("Entering key_unregister w/so=0x%x,type=%d,flag=%d\n",
1305 (unsigned int)socket, type, allflag));
1306
1307 if (!(keyregtable && socket))
1308 panic("key_register");
1309 prev = keyregtable;
1310 for(p = keyregtable->next; p; p = p->next) {
1311 if ((allflag && (p->socket == socket)) ||
1312 ((p->type == type) && (p->socket == socket))) {
1313 prev->next = p->next;
1314 KFREE(p);
1315 p = prev;
1316 }
1317 prev = p;
1318 }
1319 CRITICAL_END;
1320 }
1321
1322
1323 /*----------------------------------------------------------------------
1324 * key_acquire():
1325 * Send a key_acquire message to all registered key mgnt daemons
1326 * capable of acquire security association of type type.
1327 *
1328 * Return: 0 if succesfully called key mgnt. daemon(s)
1329 * -1 if not successfull.
1330 ----------------------------------------------------------------------*/
1331 int
1332 key_acquire(u_int type, SOCKADDR *src, SOCKADDR *dst)
1333 {
1334 struct key_registry *p;
1335 struct key_acquirelist *ap, *prevap;
1336 int success = 0, created = 0;
1337 u_int etype;
1338 struct key_msghdr *km = NULL;
1339 int len;
1340
1341 DPRINTF(IDL_EVENT,("Entering key_acquire()\n"));
1342
1343 if (!keyregtable || !src || !dst)
1344 return (-1);
1345
1346 /*
1347 * We first check the acquirelist to see if a key_acquire
1348 * message has been sent for this destination.
1349 */
1350 etype = type;
1351 prevap = key_acquirelist;
1352 for(ap = key_acquirelist->next; ap; ap = ap->next) {
1353 if (addrpart_equal(dst, ap->target) &&
1354 (etype == ap->type)) {
1355 DPRINTF(IDL_EVENT,("acquire message previously sent!\n"));
1356 if (ap->expiretime < TIME_SECONDS) {
1357 DPRINTF(IDL_EVENT,("acquire message has expired!\n"));
1358 ap->count = 0;
1359 break;
1360 }
1361 if (ap->count < maxkeyacquire) {
1362 DPRINTF(IDL_EVENT,("max acquire messages not yet exceeded!\n"));
1363 break;
1364 }
1365 return(0);
1366 } else if (ap->expiretime < TIME_SECONDS) {
1367 /*
1368 * Since we're already looking at the list, we may as
1369 * well delete expired entries as we scan through the list.
1370 * This should really be done by a function like key_reaper()
1371 * but until we code key_reaper(), this is a quick, dirty
1372 * hack.
1373 */
1374 DPRINTF(IDL_EVENT,("found an expired entry...deleting it!\n"));
1375 prevap->next = ap->next;
1376 KFREE(ap);
1377 ap = prevap;
1378 }
1379 prevap = ap;
1380 }
1381
1382 /*
1383 * Scan registry, send KEY_ACQUIRE message to
1384 * appropriate key management daemons.
1385 */
1386 for(p = keyregtable->next; p; p = p->next) {
1387 if (p->type != type)
1388 continue;
1389
1390 if (!created) {
1391 len = sizeof(struct key_msghdr) + ROUNDUP(src->sa_len) +
1392 ROUNDUP(dst->sa_len);
1393 KMALLOC(km, struct key_msghdr *, len);
1394 if (!km) {
1395 DPRINTF(IDL_ERROR,("key_acquire: no memory\n"));
1396 return(-1);
1397 }
1398 DPRINTF(IDL_FINISHED,("key_acquire/created: 1\n"));
1399 bzero((char *)km, len);
1400 km->key_msglen = len;
1401 km->key_msgvers = KEY_VERSION;
1402 km->key_msgtype = KEY_ACQUIRE;
1403 km->type = type;
1404 DPRINTF(IDL_FINISHED,("key_acquire/created: 2\n"));
1405 /*
1406 * This is inefficient, slow.
1407 */
1408
1409 /*
1410 * We zero out sin_zero here for AF_INET addresses because
1411 * ip_output() currently does not do it for performance reasons.
1412 */
1413 if (src->sa_family == AF_INET)
1414 bzero((char *)(((struct sockaddr_in *)src)->sin_zero),
1415 sizeof(((struct sockaddr_in *)src)->sin_zero));
1416 if (dst->sa_family == AF_INET)
1417 bzero((char *)(((struct sockaddr_in *)dst)->sin_zero),
1418 sizeof(((struct sockaddr_in *)dst)->sin_zero));
1419
1420 bcopy((char *)src, (char *)(km + 1), src->sa_len);
1421 bcopy((char *)dst, (char *)((int)(km + 1) + ROUNDUP(src->sa_len)),
1422 dst->sa_len);
1423 DPRINTF(IDL_FINISHED,("key_acquire/created: 3\n"));
1424 created++;
1425 }
1426 if (key_sendup(p->socket, km))
1427 success++;
1428 }
1429
1430 if (km)
1431 KFREE(km);
1432
1433 /*
1434 * Update the acquirelist
1435 */
1436 if (success) {
1437 if (!ap) {
1438 DPRINTF(IDL_EVENT,("Adding new entry in acquirelist\n"));
1439 KMALLOC(ap, struct key_acquirelist *, sizeof(struct key_acquirelist));
1440 if (ap == 0)
1441 return(success ? 0 : -1);
1442 bzero((char *)ap, sizeof(struct key_acquirelist));
1443 bcopy((char *)dst, (char *)ap->target, dst->sa_len);
1444 ap->type = etype;
1445 ap->next = key_acquirelist->next;
1446 key_acquirelist->next = ap;
1447 }
1448 DPRINTF(IDL_GROSS_EVENT,("Updating acquire counter, expiration time\n"));
1449 ap->count++;
1450 ap->expiretime = TIME_SECONDS + maxacquiretime;
1451 }
1452 DPRINTF(IDL_EVENT,("key_acquire: done! success=%d\n",success));
1453 return(success ? 0 : -1);
1454 }
1455
1456 /*----------------------------------------------------------------------
1457 * key_alloc():
1458 * Allocate a security association to a socket. A socket requesting
1459 * unique keying (per-socket keying) is assigned a security assocation
1460 * exclusively for its use. Sockets not requiring unique keying are
1461 * assigned the first security association which may or may not be
1462 * used by another socket.
1463 ----------------------------------------------------------------------*/
1464 static int
1465 key_alloc(u_int type, SOCKADDR *src, SOCKADDR *dst, struct socket *socket,
1466 u_int unique_key, struct key_tblnode **keynodep)
1467 {
1468 struct key_tblnode *keynode;
1469 char buf[MAXHASHKEYLEN];
1470 struct key_allocnode *np, *prevnp;
1471 struct key_so2spinode *newnp;
1472 int len;
1473 int indx;
1474
1475 DPRINTF(IDL_FINISHED,("Entering key_alloc w/type=%u!\n",type));
1476 if (!(src && dst)) {
1477 DPRINTF(IDL_ERROR,("key_alloc: received null src or dst!\n"));
1478 return(-1);
1479 }
1480
1481 /*
1482 * Search key allocation table
1483 */
1484 bzero((char *)&buf, sizeof(buf));
1485 len = key_createkey((char *)&buf, type, src, dst, 0, 1);
1486 indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
1487
1488 #define np_type np->keynode->secassoc->type
1489 #define np_state np->keynode->secassoc->state
1490 #define np_src np->keynode->secassoc->src
1491 #define np_dst np->keynode->secassoc->dst
1492
1493 prevnp = &keyalloctbl[indx];
1494 for (np = keyalloctbl[indx].next; np; np = np->next) {
1495 if ((type == np_type) && addrpart_equal(src, np_src) &&
1496 addrpart_equal(dst, np_dst) &&
1497 !(np_state & (K_LARVAL | K_DEAD | K_UNIQUE))) {
1498 if (!(unique_key))
1499 break;
1500 if (!(np_state & K_USED))
1501 break;
1502 }
1503 prevnp = np;
1504 }
1505
1506 if (np) {
1507 struct socketlist *newsp;
1508 CRITICAL_DCL
1509
1510 CRITICAL_START;
1511
1512 DPRINTF(IDL_EVENT,("key_alloc: found node to allocate\n"));
1513 keynode = np->keynode;
1514
1515 KMALLOC(newnp, struct key_so2spinode *, sizeof(struct key_so2spinode));
1516 if (newnp == 0) {
1517 DPRINTF(IDL_ERROR,("key_alloc: Can't alloc mem for so2spi node!\n"));
1518 CRITICAL_END;
1519 return(ENOBUFS);
1520 }
1521 KMALLOC(newsp, struct socketlist *, sizeof(struct socketlist));
1522 if (newsp == 0) {
1523 DPRINTF(IDL_ERROR,("key_alloc: Can't alloc mem for socketlist!\n"));
1524 if (newnp)
1525 KFREE(newnp);
1526 CRITICAL_END;
1527 return(ENOBUFS);
1528 }
1529
1530 /*
1531 * Add a hash entry into the so2spi table to
1532 * map socket to allocated secassoc.
1533 */
1534 DPRINTF(IDL_FINISHED,("key_alloc: adding entry to so2spi table..."));
1535 newnp->keynode = keynode;
1536 newnp->socket = socket;
1537 newnp->next = so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE].next;
1538 so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE].next = newnp;
1539 DPRINTF(IDL_FINISHED,("done\n"));
1540
1541 if (unique_key) {
1542 /*
1543 * Need to remove the allocation entry
1544 * since the secassoc is now unique,
1545 * can't be allocated to any other socket
1546 */
1547 DPRINTF(IDL_EVENT,("key_alloc: making keynode unique..."));
1548 keynode->secassoc->state |= K_UNIQUE;
1549 prevnp->next = np->next;
1550 KFREE(np);
1551 DPRINTF(IDL_EVENT,("done\n"));
1552 }
1553 keynode->secassoc->state |= K_USED;
1554 keynode->secassoc->state |= K_OUTBOUND;
1555 keynode->alloc_count++;
1556
1557 /*
1558 * Add socket to list of socket using secassoc.
1559 */
1560 DPRINTF(IDL_FINISHED,("key_alloc: adding so to solist..."));
1561 newsp->socket = socket;
1562 newsp->next = keynode->solist->next;
1563 keynode->solist->next = newsp;
1564 DPRINTF(IDL_FINISHED,("done\n"));
1565 *keynodep = keynode;
1566 CRITICAL_END;
1567 return(0);
1568 }
1569 *keynodep = NULL;
1570 return(0);
1571 }
1572
1573
1574 /*----------------------------------------------------------------------
1575 * key_free():
1576 * Decrement the refcount for a key table entry. If the entry is
1577 * marked dead,, the refcount is zero, we go ahead, delete it.
1578 ----------------------------------------------------------------------*/
1579 void
1580 key_free(struct key_tblnode *keynode)
1581 {
1582 DPRINTF(IDL_GROSS_EVENT,("Entering key_free w/keynode=0x%x\n",
1583 (unsigned int)keynode));
1584 if (!keynode) {
1585 DPRINTF(IDL_ERROR,("Warning: key_free got null pointer\n"));
1586 return;
1587 }
1588 (keynode->ref_count)--;
1589 if (keynode->ref_count < 0) {
1590 DPRINTF(IDL_ERROR,("Warning: key_free decremented refcount to %d\n",keynode->ref_count));
1591 }
1592 if ((keynode->secassoc->state & K_DEAD) && (keynode->ref_count <= 0)) {
1593 DPRINTF(IDL_GROSS_EVENT,("key_free: calling key_delete\n"));
1594 key_delete(keynode->secassoc);
1595 }
1596 }
1597
1598 /*----------------------------------------------------------------------
1599 * getassocbyspi():
1600 * Get a security association for a given type, src, dst,, spi.
1601 *
1602 * Returns: 0 if sucessfull
1603 * -1 if error/not found
1604 *
1605 * Caller must convert spi to host order. Function assumes spi is
1606 * in host order!
1607 ----------------------------------------------------------------------*/
1608 int
1609 getassocbyspi(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi,
1610 struct key_tblnode **keyentry)
1611 {
1612 char buf[MAXHASHKEYLEN];
1613 int len, indx;
1614 struct key_tblnode *keynode, *prevkeynode = 0;
1615
1616 DPRINTF(IDL_FINISHED,("Entering getassocbyspi w/type=%u spi=%u\n",type,spi));
1617
1618 *keyentry = NULL;
1619 bzero(&buf, sizeof(buf));
1620 len = key_createkey((char *)&buf, type, src, dst, spi, 0);
1621 indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
1622 DPRINTF(IDL_FINISHED,("getassocbyspi: indx=%d\n",indx));
1623 DDO(IDL_FINISHED,dump_sockaddr(src);dump_sockaddr(dst));
1624 keynode = key_search(type, src, dst, spi, indx, &prevkeynode);
1625 DPRINTF(IDL_FINISHED,("getassocbyspi: keysearch ret=0x%x\n",
1626 (unsigned int)keynode));
1627 if (keynode && !(keynode->secassoc->state & (K_DEAD | K_LARVAL))) {
1628 DPRINTF(IDL_GROSS_EVENT,("getassocbyspi: found secassoc!\n"));
1629 (keynode->ref_count)++;
1630 keynode->secassoc->state |= K_USED;
1631 *keyentry = keynode;
1632 } else {
1633 DPRINTF(IDL_EVENT,("getassocbyspi: secassoc not found!\n"));
1634 return (-1);
1635 }
1636 return(0);
1637 }
1638
1639
1640 /*----------------------------------------------------------------------
1641 * getassocbysocket():
1642 * Get a security association for a given type, src, dst,, socket.
1643 * If not found, try to allocate one.
1644 * Returns: 0 if successfull
1645 * -1 if error condition/secassoc not found (*keyentry = NULL)
1646 * 1 if secassoc temporarily unavailable (*keynetry = NULL)
1647 * (e.g., key mgnt. daemon(s) called)
1648 ----------------------------------------------------------------------*/
1649 int
1650 getassocbysocket(u_int type, SOCKADDR *src, SOCKADDR *dst,
1651 struct socket *socket, u_int unique_key,
1652 struct key_tblnode **keyentry)
1653 {
1654 struct key_tblnode *keynode = 0;
1655 struct key_so2spinode *np;
1656 u_int realtype;
1657
1658 DPRINTF(IDL_FINISHED,("Entering getassocbysocket w/type=%u so=0x%x\n",
1659 type,(unsigned int)socket));
1660
1661 /*
1662 * We treat esp-transport mode, esp-tunnel mode
1663 * as a single type in the keytable. This has a side
1664 * effect that socket using both esp-transport,
1665 * esp-tunnel will use the same security association
1666 * for both modes. Is this a problem?
1667 */
1668 realtype = type;
1669 if ((np = key_sosearch(type, src, dst, socket))) {
1670 if (np->keynode && np->keynode->secassoc &&
1671 !(np->keynode->secassoc->state & (K_DEAD | K_LARVAL))) {
1672 DPRINTF(IDL_FINISHED,("getassocbysocket: found secassoc!\n"));
1673 (np->keynode->ref_count)++;
1674 *keyentry = np->keynode;
1675 return(0);
1676 }
1677 }
1678
1679 /*
1680 * No secassoc has been allocated to socket,
1681 * so allocate one, if available
1682 */
1683 DPRINTF(IDL_GROSS_EVENT,("getassocbyso: can't find it, trying to allocate!\n"));
1684 if (key_alloc(realtype, src, dst, socket, unique_key, &keynode) == 0) {
1685 if (keynode) {
1686 DPRINTF(IDL_GROSS_EVENT,("getassocbyso: key_alloc found secassoc!\n"));
1687 keynode->ref_count++;
1688 *keyentry = keynode;
1689 return(0);
1690 } else {
1691 /*
1692 * Kick key mgnt. daemon(s)
1693 * (this should be done in ipsec_output_policy() instead or
1694 * selectively called based on a flag value)
1695 */
1696 DPRINTF(IDL_FINISHED,("getassocbyso: calling key mgnt daemons!\n"));
1697 *keyentry = NULL;
1698 if (key_acquire(realtype, src, dst) == 0)
1699 return (1);
1700 else
1701 return(-1);
1702 }
1703 }
1704 *keyentry = NULL;
1705 return(-1);
1706 }
1707
1708 /*----------------------------------------------------------------------
1709 * key_xdata():
1710 * Parse message buffer for src/dst/from/iv/key if parseflag = 0
1711 * else parse for src/dst only.
1712 ----------------------------------------------------------------------*/
1713 static int
1714 key_xdata(struct key_msghdr *km, struct key_msgdata *kip, int parseflag)
1715 {
1716 char *cp, *cpmax;
1717
1718 if (!km || (km->key_msglen <= 0))
1719 return (-1);
1720
1721 cp = (caddr_t)(km + 1);
1722 cpmax = (caddr_t)km + km->key_msglen;
1723
1724 /*
1725 * Assumes user process passes message with
1726 * correct word alignment.
1727 */
1728
1729 /*
1730 * Need to clean up this code later.
1731 */
1732
1733 /* Grab src addr */
1734 kip->src = (SOCKADDR *)cp;
1735 if (!kip->src->sa_len) {
1736 DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse src addr\n"));
1737 return(-1);
1738 }
1739
1740 ADVANCE(cp, kip->src->sa_len);
1741
1742 /* Grab dest addr */
1743 kip->dst = (SOCKADDR *)cp;
1744 if (!kip->dst->sa_len) {
1745 DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse dest addr\n"));
1746 return(-1);
1747 }
1748
1749 ADVANCE(cp, kip->dst->sa_len);
1750 if (parseflag == 1) {
1751 kip->from = 0;
1752 kip->key = kip->iv = 0;
1753 kip->keylen = kip->ivlen = 0;
1754 return(0);
1755 }
1756
1757 /* Grab from addr */
1758 kip->from = (SOCKADDR *)cp;
1759 if (!kip->from->sa_len) {
1760 DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse from addr\n"));
1761 return(-1);
1762 }
1763
1764 ADVANCE(cp, kip->from->sa_len);
1765
1766 /* Grab key */
1767 if ((kip->keylen = km->keylen)) {
1768 kip->key = cp;
1769 ADVANCE(cp, km->keylen);
1770 } else
1771 kip->key = 0;
1772
1773 /* Grab iv */
1774 if ((kip->ivlen = km->ivlen))
1775 kip->iv = cp;
1776 else
1777 kip->iv = 0;
1778
1779 return (0);
1780 }
1781
1782
1783 int
1784 key_parse(struct key_msghdr **kmp, struct socket *so, int *dstfamily)
1785 {
1786 int error = 0, keyerror = 0;
1787 struct key_msgdata keyinfo;
1788 struct key_secassoc *secassoc = NULL;
1789 struct key_msghdr *km = *kmp;
1790
1791 DPRINTF(IDL_MAJOR_EVENT, ("Entering key_parse\n"));
1792
1793 #define senderr(e) \
1794 { error = (e); goto flush; }
1795
1796 if (km->key_msgvers != KEY_VERSION) {
1797 DPRINTF(IDL_CRITICAL,("keyoutput: Unsupported key message version!\n"));
1798 senderr(EPROTONOSUPPORT);
1799 }
1800
1801 km->key_pid = CURRENT_PID;
1802
1803 DDO(IDL_MAJOR_EVENT, printf("keymsghdr:\n"); dump_keymsghdr(km));
1804
1805 /*
1806 * Parse buffer for src addr, dest addr, from addr, key, iv
1807 */
1808 bzero((char *)&keyinfo, sizeof(keyinfo));
1809
1810 switch (km->key_msgtype) {
1811 case KEY_ADD:
1812 DPRINTF(IDL_MAJOR_EVENT,("key_output got KEY_ADD msg\n"));
1813
1814 if (key_xdata(km, &keyinfo, 0) < 0)
1815 goto parsefail;
1816
1817 /*
1818 * Allocate the secassoc structure to insert
1819 * into key table here.
1820 */
1821 KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc));
1822 if (secassoc == 0) {
1823 DPRINTF(IDL_CRITICAL,("keyoutput: No more memory!\n"));
1824 senderr(ENOBUFS);
1825 }
1826
1827 if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
1828 DPRINTF(IDL_CRITICAL,("keyoutput: key_msghdr2secassoc failed!\n"));
1829 KFREE(secassoc);
1830 senderr(EINVAL);
1831 }
1832 DPRINTF(IDL_MAJOR_EVENT,("secassoc to add:\n"));
1833 DDO(IDL_MAJOR_EVENT,dump_secassoc(secassoc));
1834
1835 if ((keyerror = key_add(secassoc)) != 0) {
1836 DPRINTF(IDL_CRITICAL,("keyoutput: key_add failed\n"));
1837 if (secassoc->key)
1838 KFREE(secassoc->key);
1839 if (secassoc->iv)
1840 KFREE(secassoc->iv);
1841 KFREE(secassoc);
1842 if (keyerror == -2) {
1843 senderr(EEXIST);
1844 } else {
1845 senderr(ENOBUFS);
1846 }
1847 }
1848 break;
1849 case KEY_DELETE:
1850 DPRINTF(IDL_MAJOR_EVENT,("key_output got KEY_DELETE msg\n"));
1851
1852 if (key_xdata(km, &keyinfo, 1) < 0)
1853 goto parsefail;
1854
1855 KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc));
1856 if (secassoc == 0) {
1857 senderr(ENOBUFS);
1858 }
1859 if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
1860 KFREE(secassoc);
1861 senderr(EINVAL);
1862 }
1863 if (key_delete(secassoc) != 0) {
1864 if (secassoc->iv)
1865 KFREE(secassoc->iv);
1866 if (secassoc->key)
1867 KFREE(secassoc->key);
1868 KFREE(secassoc);
1869 senderr(ESRCH);
1870 }
1871 if (secassoc->iv)
1872 KFREE(secassoc->iv);
1873 if (secassoc->key)
1874 KFREE(secassoc->key);
1875 KFREE(secassoc);
1876 break;
1877 case KEY_UPDATE:
1878 DPRINTF(IDL_EVENT,("key_output got KEY_UPDATE msg\n"));
1879
1880 if (key_xdata(km, &keyinfo, 0) < 0)
1881 goto parsefail;
1882
1883 KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc));
1884 if (secassoc == 0) {
1885 senderr(ENOBUFS);
1886 }
1887 if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
1888 KFREE(secassoc);
1889 senderr(EINVAL);
1890 }
1891 if ((keyerror = key_update(secassoc)) != 0) {
1892 DPRINTF(IDL_CRITICAL,("Error updating key entry\n"));
1893 if (secassoc->iv)
1894 KFREE(secassoc->iv);
1895 if (secassoc->key)
1896 KFREE(secassoc->key);
1897 KFREE(secassoc);
1898 senderr(keyerror);
1899 }
1900 KFREE(secassoc);
1901 break;
1902 case KEY_GET:
1903 DPRINTF(IDL_EVENT,("key_output got KEY_GET msg\n"));
1904
1905 if (key_xdata(km, &keyinfo, 1) < 0)
1906 goto parsefail;
1907
1908 if (key_get(km->type, (SOCKADDR *)keyinfo.src,
1909 (SOCKADDR *)keyinfo.dst,
1910 km->spi, &secassoc) != 0) {
1911 DPRINTF(IDL_EVENT,("keyoutput: can't get key\n"));
1912 senderr(ESRCH);
1913 }
1914
1915 if (secassoc) {
1916 int newlen;
1917
1918 DPRINTF(IDL_EVENT,("keyoutput: Found secassoc!\n"));
1919 newlen = sizeof(struct key_msghdr) + ROUNDUP(secassoc->src->sa_len) +
1920 ROUNDUP(secassoc->dst->sa_len) + ROUNDUP(secassoc->from->sa_len) +
1921 ROUNDUP(secassoc->keylen) + ROUNDUP(secassoc->ivlen);
1922 DPRINTF(IDL_EVENT,("keyoutput: newlen=%d\n", newlen));
1923 if (newlen > km->key_msglen) {
1924 struct key_msghdr *newkm;
1925
1926 DPRINTF(IDL_EVENT,("keyoutput: Allocating new buffer!\n"));
1927 KMALLOC(newkm, struct key_msghdr *, newlen);
1928 if (newkm == 0) {
1929 senderr(ENOBUFS);
1930 }
1931 bcopy((char *)km, (char *)newkm, km->key_msglen);
1932 DPRINTF(IDL_FINISHED,("keyoutput: 1\n"));
1933 KFREE(km);
1934 *kmp = km = newkm;
1935 DPRINTF(IDL_CRITICAL, ("km->key_msglen = %d, newlen = %d\n",
1936 km->key_msglen, newlen));
1937 km->key_msglen = newlen;
1938 }
1939 DPRINTF(IDL_FINISHED,("keyoutput: 2\n"));
1940 if (key_secassoc2msghdr(secassoc, km, &keyinfo)) {
1941 DPRINTF(IDL_CRITICAL,("keyoutput: Can't create msghdr!\n"));
1942 senderr(EINVAL);
1943 }
1944 DPRINTF(IDL_FINISHED,("keyoutput: 3\n"));
1945 }
1946 break;
1947 case KEY_GETSPI:
1948 DPRINTF(IDL_EVENT,("key_output got KEY_GETSPI msg\n"));
1949
1950 if (key_xdata(km, &keyinfo, 1) < 0)
1951 goto parsefail;
1952
1953 if ((keyerror = key_getspi(km->type, keyinfo.src, keyinfo.dst,
1954 km->lifetime1, km->lifetime2,
1955 &(km->spi))) != 0) {
1956 DPRINTF(IDL_CRITICAL,("keyoutput: getspi failed error=%d\n", keyerror));
1957 senderr(keyerror);
1958 }
1959 break;
1960 case KEY_REGISTER:
1961 DPRINTF(IDL_EVENT,("key_output got KEY_REGISTER msg\n"));
1962 key_register(so, km->type);
1963 break;
1964 case KEY_DUMP:
1965 DPRINTF(IDL_EVENT,("key_output got KEY_DUMP msg\n"));
1966 error = key_dump(so);
1967 return(error);
1968 break;
1969 case KEY_FLUSH:
1970 DPRINTF(IDL_EVENT,("key_output got KEY_FLUSH msg\n"));
1971 key_flush();
1972 break;
1973 default:
1974 DPRINTF(IDL_CRITICAL,("key_output got unsupported msg type=%d\n",
1975 km->key_msgtype));
1976 senderr(EOPNOTSUPP);
1977 }
1978
1979 goto flush;
1980
1981 parsefail:
1982 keyinfo.dst = NULL;
1983 error = EINVAL;
1984
1985 flush:
1986 if (km)
1987 km->key_errno = error;
1988
1989 if (dstfamily)
1990 *dstfamily = keyinfo.dst ? keyinfo.dst->sa_family : 0;
1991
1992 DPRINTF(IDL_MAJOR_EVENT, ("key_parse exiting with error=%d\n", error));
1993 return error;
1994 }
1995
1996 /*
1997 * Definitions of protocols supported in the KEY domain.
1998 */
1999
2000 struct sockaddr key_addr = { 2, PF_KEY, };
2001 struct sockproto key_proto = { PF_KEY, };
2002
2003 #define KEYREAPERINT 120
2004
2005 #define ROUNDUP(a) \
2006 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
2007
2008 static int
2009 key_sendup(s, km)
2010 struct socket *s;
2011 struct key_msghdr *km;
2012 {
2013 struct mbuf *m;
2014 MGETHDR(m, M_WAIT, MT_DATA);
2015 m->m_len = m->m_pkthdr.len = 0;
2016 m->m_next = 0;
2017 m->m_nextpkt = 0;
2018 m->m_pkthdr.rcvif = 0;
2019 m_copyback(m, 0, km->key_msglen, (caddr_t)km);
2020
2021 if (sbappendaddr(&(s->so_rcv), &key_addr, m, NULL)) {
2022 sorwakeup(s);
2023 return 1;
2024 } else
2025 m_freem(m);
2026
2027 return(0);
2028 }
2029
2030 #ifdef notyet
2031 /*----------------------------------------------------------------------
2032 * key_reaper():
2033 * Scan key table, nuke unwanted entries
2034 ----------------------------------------------------------------------*/
2035 static void
2036 key_reaper(whocares)
2037 void *whocares;
2038 {
2039 DPRINTF(IDL_GROSS_EVENT,("Entering key_reaper()\n"));
2040
2041 timeout(key_reaper, NULL, KEYREAPERINT * HZ);
2042 }
2043 #endif /* notyet */
2044
2045 /*----------------------------------------------------------------------
2046 * key_init():
2047 * Init routine for key socket, key engine
2048 ----------------------------------------------------------------------*/
2049 static void
2050 key_init(void)
2051 {
2052 DPRINTF(IDL_EVENT,("Called key_init().\n"));
2053 if (key_inittables())
2054 panic("key_inittables failed!\n");
2055 #ifdef notyet
2056 timeout(key_reaper, NULL, HZ);
2057 #endif /* notyet */
2058 bzero((char *)&keyso_cb, sizeof(keyso_cb));
2059 }
2060
2061 /*----------------------------------------------------------------------
2062 * my_addr():
2063 * Determine if an address belongs to one of my configured interfaces.
2064 * Currently handles only AF_INET, AF_INET6 addresses.
2065 ----------------------------------------------------------------------*/
2066 static int
2067 my_addr(sa)
2068 SOCKADDR *sa;
2069 {
2070 struct in6_ifaddr *i6a = 0;
2071 struct in_ifaddr *ia = 0;
2072
2073 switch(sa->sa_family) {
2074 #ifdef INET6
2075 case AF_INET6:
2076 for (i6a = in6_ifaddr; i6a; i6a = i6a->i6a_next) {
2077 if (IN6_ADDR_EQUAL(((struct sockaddr_in6 *)sa)->sin6_addr,
2078 i6a->i6a_addr.sin6_addr))
2079 return(1);
2080 }
2081 break;
2082 #endif /* INET6 */
2083 case AF_INET:
2084 for (ia = in_ifaddr; ia; ia = ia->ia_next) {
2085 if (((struct sockaddr_in *)sa)->sin_addr.s_addr ==
2086 ia->ia_addr.sin_addr.s_addr)
2087 return(1);
2088 }
2089 break;
2090 }
2091 return(0);
2092 }
2093
2094 /*----------------------------------------------------------------------
2095 * key_output():
2096 * Process outbound pf_key message.
2097 ----------------------------------------------------------------------*/
2098 static int
2099 key_output(struct mbuf *m, struct socket *so)
2100 {
2101 struct key_msghdr *km = 0;
2102 caddr_t cp, cplimit;
2103 int len;
2104 int error = 0;
2105 int dstfamily = 0;
2106
2107 DPRINTF(IDL_EVENT,("key_output() got a message len=%d.\n", m->m_pkthdr.len));
2108
2109 #undef senderr
2110 #define senderr(e) \
2111 { error = (e); if (km) km->key_errno = error; goto flush; }
2112
2113 if (m == 0 || ((m->m_len < sizeof(long)) &&
2114 (m = m_pullup(m, sizeof(long))) == 0)) {
2115 DPRINTF(IDL_CRITICAL,("key_output can't pullup mbuf\n"));
2116 return (ENOBUFS);
2117 }
2118 if ((m->m_flags & M_PKTHDR) == 0)
2119 panic("key_output");
2120
2121 DDO(IDL_FINISHED,dump_mbuf(m));
2122
2123 len = m->m_pkthdr.len;
2124 if (len < sizeof(*km) || len != mtod(m, struct key_msghdr *)->key_msglen) {
2125 DPRINTF(IDL_CRITICAL,("keyout: Invalid length field/length mismatch!\n"));
2126 senderr(EINVAL);
2127 }
2128 KMALLOC(km, struct key_msghdr *, len);
2129 if (km == 0) {
2130 DPRINTF(IDL_CRITICAL,("keyoutput: Can't malloc memory!\n"));
2131 senderr(ENOBUFS);
2132 }
2133
2134 m_copydata(m, 0, len, (caddr_t)km);
2135
2136 km->key_errno = error = key_parse(&km, so, &dstfamily);
2137 DPRINTF(IDL_MAJOR_EVENT, ("Back from key_parse\n"));
2138 flush:
2139 key_sendup(so, km);
2140 #if 0
2141 {
2142 struct rawcb *rp = 0;
2143 struct mbuf *m;
2144
2145 if ((so->so_options & SO_USELOOPBACK) == 0) {
2146 if (keyso_cb.any_count <= 1) {
2147 if (km)
2148 KFREE(km);
2149 return (error);
2150 }
2151 rp = sotorawcb(so);
2152 }
2153
2154 DPRINTF(IDL_MAJOR_EVENT, ("key_output: foo\n"));
2155 key_proto.sp_protocol = dstfamily;
2156
2157 if (km) {
2158 m = m_devget(km, len, 0, NULL, NULL);
2159 KFREE(km);
2160 }
2161
2162 DPRINTF(IDL_MAJOR_EVENT, ("key_output: bar\n"));
2163 if (rp)
2164 rp->rcb_proto.sp_family = 0; /* Prevent us from receiving message */
2165
2166 raw_input(m, &key_proto, &key_addr, &key_addr);
2167
2168 if (rp)
2169 rp->rcb_proto.sp_family = PF_KEY;
2170 }
2171 DPRINTF(IDL_MAJOR_EVENT, ("key_output: baz\n"));
2172 #endif /* 0 */
2173 return (error);
2174 }
2175
2176
2177 /*----------------------------------------------------------------------
2178 * key_usrreq():
2179 * Handles PRU_* for pf_key sockets.
2180 ----------------------------------------------------------------------*/
2181 static int
2182 key_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
2183 struct mbuf *control)
2184 {
2185 register int error = 0;
2186 register struct rawcb *rp = sotorawcb(so);
2187 int s;
2188
2189 DPRINTF(IDL_EVENT,("Entering key_usrreq, req = %d.\n",req));
2190
2191 if (req == PRU_ATTACH) {
2192 MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
2193 if (so->so_pcb = (caddr_t)rp)
2194 bzero(so->so_pcb, sizeof(*rp));
2195 }
2196
2197 if (req == PRU_DETACH && rp) {
2198 int af = rp->rcb_proto.sp_protocol;
2199 if (af == AF_INET)
2200 keyso_cb.ip4_count--;
2201 #ifdef INET6
2202 else if (af == AF_INET6)
2203 keyso_cb.ip6_count--;
2204 #endif /* INET6 */
2205 keyso_cb.any_count--;
2206 }
2207 s = splnet();
2208 error = raw_usrreq(so, req, m, nam, control);
2209 rp = sotorawcb(so);
2210
2211 if (req == PRU_ATTACH && rp) {
2212 int af = rp->rcb_proto.sp_protocol;
2213 if (error) {
2214 free((caddr_t)rp, M_PCB);
2215 splx(s);
2216 return error;
2217 }
2218 if (af == AF_INET)
2219 keyso_cb.ip4_count++;
2220 #ifdef INET6
2221 else if (af == AF_INET6)
2222 keyso_cb.ip6_count++;
2223 #endif /* INET6 */
2224 keyso_cb.any_count++;
2225 rp->rcb_faddr = &key_addr;
2226 soisconnected(so); /* Key socket, like routing socket, must be
2227 connected. */
2228
2229 /* Possibly set other needed flags/options at creation time in here. */
2230 so->so_options |= SO_USELOOPBACK; /* Like routing socket, we turn this */
2231 /* on by default */
2232 }
2233 splx(s);
2234 return error;
2235 }
2236
2237 /*----------------------------------------------------------------------
2238 * key_cbinit():
2239 * Control block init routine for key socket
2240 ----------------------------------------------------------------------*/
2241 static void
2242 key_cbinit(void)
2243 {
2244 /*
2245 * This is equivalent to raw_init for the routing socket.
2246 * The key socket uses the same control block as the routing
2247 * socket.
2248 */
2249 DPRINTF(IDL_EVENT,("Called key_cbinit().\n"));
2250 }
2251
2252 /*
2253 * Protoswitch entry for pf_key
2254 */
2255
2256 extern struct domain keydomain; /* or at least forward */
2257
2258 struct protosw keysw[] = {
2259 { SOCK_RAW, &keydomain, 0, PR_ATOMIC|PR_ADDR,
2260 raw_input, key_output, raw_ctlinput, 0,
2261 key_usrreq,
2262 key_cbinit
2263 }
2264 };
2265
2266 struct domain keydomain =
2267 { PF_KEY, "key", key_init, 0, 0,
2268 keysw, &keysw[sizeof(keysw)/sizeof(keysw[0])] };
2269
2270 DOMAIN_SET(key)
Cache object: d52cf1147617ec37b2b65b63466b650b
|