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