Bedrock Computer Technologies, LLC v. Softlayer Technologies, Inc. et al

Filing 846

Additional Attachments to Main Document: #845 MOTION for Judgment as a Matter of Law Regarding Invalidity (Renewed) MOTION for Judgment as a Matter of Law Regarding Invalidity (Renewed) MOTION for Judgment as a Matter of Law Regarding Invalidity (Renewed) MOTION for Judgment as a Matter of Law Regarding Invalidity (Renewed) MOTION for Judgment as a Matter of Law Regarding Invalidity (Renewed).. (Attachments: #1 Exhibit 13 - U.S. Patent 5,893,120 - PX-1, #2 Exhibit 14 - 1996 NRL IPv6 code key.c - DX-36, #3 Exhibit 15 - NRL Source Code - key.h - DX-35, #4 Exhibit 16 - Information Disclosure Statement - 6/2010 - DX-147C, #5 Exhibit 17 - Information Disclosure Statement -12-2010 - DX-147E, #6 Exhibit 18 - Transaction History for Patent Application - DX-147G, #7 Exhibit 19 - USPTO Notice of Intent to Issue - DX-147F, #8 Exhibit 20 - Ex Parte Reexamination Certificate for the '120 Patent - DX-147H, #9 Exhibit 21 - US. Patent 5,287,499 - DX-66, #10 Exhibit 22 - Telcordia documents re: patent application - DX-56, #11 Exhibit 23 - Yahoo!'s 2004 10K Annual Statement - PX-248)(Doan, Jennifer)

Download PDF
Exhibit 14 1 /*------------------------------------------------------------------- 2 * key.h : 3 * * 4 5 6 7 Declarations and Definitions for Key Engine for BSD. ~. Copyright 1995 by Bao Phan, Randall Atkinson, & Dan MCDonald, * All Rights Reserved. All rights have been assigned to the US * Naval Research Laboratory (NRL). The NRL Copyright Notice and * License Agreement governs distribution and use of this software. f] * 9 10 11 12 13 14 * * * * * * 15 16 Patents are pending on this technology. NRL grants a license to use this technology at no cost under the terms below with the additional requirement that software, hardware, and documentation relating to use of this technology must,include the note that: This product includes technology developed at and licensed from the Information Technology Division, * * US Naval Research Laboratory. 17 * 18 19 ----------------------------------------------------------------------*/ /*-------------------- ------------------------------------------------- 20 # @(#)COPYRIGHT 1.la (NRL) 17 August 1995 2J 22 COPYRIGHT NOTICE 23 24 2S 26 All of the documentation and software included in this software distribution from the US Naval Research Laboratory (NRL) are copyrighted by their respective developers. 27 28 29 30 31 32 33 This software and documentation were developed at NRL by various people. Those developers have each copyrighted the portions that they developed at NRL and have assigned All Rights for those portions to NRL. Outside the USA, NRL also has copyright on the software developed at NRL. The affected files all contain specific copyright notices and those notices must be retained in any derived work. 34 35 NRL LICENSE 36 37 38 39 NRL grants permission for redistribution and use in source and binary forms, with or without modification, of the software and documentation created at NRL provided that the following conditions are met: 4.0 41 42 43 44 45 46 47 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use af this software must display the following acknowledgement: 48 49 50 This product includes software developed at the Information Technology Division, US Naval Research Laboratory . . 51 52 4. Neither the name of the NRL nor the names of its contributors be used to endorse or derived from this software 54 without specific prior written permission. 55 56 57 58 59 60 61 62 63 64 65 66 THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 68 69 70 71 The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the US Naval Research Laboratory (NRL). 72 73 74 ----------------------------------------------------------------------*/ 75 76 77 78 #ifdef linux #include <netkey/osdep_linux.h> #else /* linux */ #include <netkey/osdep_44bsd.h> #endif /* linux */ 3 /* 82 * PF KEY messages 83 84 */ 85 86 87 88 89 90 91 92 93 9(0 #define #define #define #define #define #define #define #define #define #define KEY ADD KEY DELETE KEY UPDATE KEY GET KEY_ACQUIRE KEY GETSPI KEY REGISTER KEY EXPIRE KEY DUMP KEY FLUSH #define KEY VERSION 1 2 3 4 5 6 7 8 9 10 1 1 97 #define POLICY VERSION 98 99 #define SECURITY- TYPE - NONE 100 101 #define KEY- TYPE- AH 1 102 #define KEY- TYPE- ESP 2 J03 #define KEY TYPE RSVP #define KEY- TYPE- OSPF 105 #define KEY- TYPE - RIPV2 3 104 4 0 5 6 107 #define KEY_TYPE_MIPV6 108 #define KEY TYPE MAX 7 7 109 110 /* 111 112 113 114 115 116 117 118 119 * Security association state */ #define #define #define #define #define #define #define K USED K_UNIQUE K LARVAL K ZOMBIE K DEAD K INBOUND K OUTBOUND Oxl ox2 Ox4 OxS Ox10 Ox20 Ox40 /* /* /* /* /* /* /* Key used/not used */ Key unique/reusable */ SPI assigned, but sa incomplete */ sa expired but still useable */ sa marked for deletion, ready for reaping */ sa for inbound packets, ie. dst=myhost */ sa for outbound packets, ie. src=myhost */ 122 123 124 125 126 127 128 #ifndef MAX_SOCKADDR_SZ #ifdef INET6 #define MAX_SOCKADDR_SZ (sizeof(struct sockaddr_in6» #else /* INET6 */ #define MAX_SOCKADDR_SZ (sizeof(struct sockaddr_in» #endif /* INET6 */ 129 #endif /* MAX_SOCKADDR_SZ * / L:n #ifndef MAX_KEY_SZ 132 #define MAX_KEY_SZ 16 133 #endif /* MAX_KEY_SZ * / 134 135 #ifndef MAX_IV_SZ 136 #define MAX_IV_SZ 16 /* MAX_IV_SZ * / 137 #endif 138 139 /* Security association data for IP Security */ 140 struct key_secassoc { ::.41 u ints len; /* Length of the data (for radix) */ u - intS type; /* Type of association */ 142 1,-13 u intS state; /* State of the association */ u - intB label; /* sensitivity label (unused) */ 145 u - int32 spi; /* SPI */ u intB keylen; /* Key length */ 146 /* Initialization vector length */ u intB ivlen; 147 /* Algorithm switch index */ u - intB algorithm; 148 149 u intS lifetype; /* Type of lifetime */ caddr t iv; Initialization vector */ /* caddr t key; /* Key */ 151 /* Lifetime value 1 */ u int32 lifetime1; 152 153 u int32 lifetime2 ; /* Lifetime value 2 */ SOCKADDR *src; /* Source host address */ 154 /* Destination host address */ SOCKADDR *dst; 155 SOCKADDR *from; /* Originator of association */ 156 157 }; 158 160 * structure for key message header. 161 * PF_KEY message consists of key_msghdr followed by 162 * src sockaddr, dest sockaddr, from sockaddr, key, and iv. 163 * Assumes size of key message header less than MHLEN. 164 */ 165 166 struct key_msghdr { u short key_msglen; 167 /* length of message including src/dst/from/key/iv */ u char key_msgvers; /* key version number */ 168 u char key_msgtype; 169 /* key message type, ego KEY_ADD */ 170 pid t keYJlid; /* process id of message sender */ int key_seq; /* message sequence number */ 171 int key_errno; 172 /* error code */ u ints type; 173 /* type of security association */ 174 u intS state; /* state of security association */ u intS label; /* sensitivity level */ 175 u - intS pad; 176 /* padding for allignment */ 177 u int32 spi; /* spi value */ u ints keylen; 178 /* key length */ u intS ivlen; /* iv length */ 179 u intS algorithm; /* algorithm identifier */ 180 u intS lifetype; 181 /* type of lifetime */ 182 u - int32 lifetimel; /* lifetime value 1 */ u - int32 lifetime2; 1.83 /* lifetime value 2 */ }; 1(,6 187 1,38 189 190 191 192 struct key_msgdata { SOCKADDR *src; /* source host address */ SOCKADDR *ds t; /* destination host address */ SOCKADDR *from; /* originator of security association */ caddr_t iv; /* initialization vector */ caddr_t key; /* key */ int ivlen; /* key length */ int keylen; /* iv length */ 194 }; 195 196 struct policy_msghdr { 197 u short policy_msglen; 198 u char policy_msgvers; u char policy_msgtype; 199 int policy_seq; 200 int policy_errno; 201 message length */ message version */ message type */ message sequence number */ error code */ /* /* /* /* /* 202 }; 203 204 #ifdef KERNEL 205 206 /* 207 * Key engine table structures 208 */ 20S> 210 struct socketlist { 211 struct socket *socket; struct socket list /* pointer to socket */ 213 }; 214 215 struct key_tblnode { int alloc_count; /* number of sockets allocated to secas soc */ 216 217 int ref_count; /* number of sockets referencing secassoc */ 218 struct socketlist *solist; /* list of sockets allocated to secas soc */ 219 struct key_secassoc *secassoc; /* security association */ 220 struct key_tblnode *next; /* next node */ 221 }i 222 223 struct key_allocnode { 224 struct key_tblnode *keynode; 225 struct key_allocnode *next; 226 }; 227 228 struct key_so2spinode { 229 struct socket *socket; /* socket pointer */ 230 struct key_tblnode *keynode; /* pointer to tblnode containing secassoc */ 231 /* info for socket */ 232 struct key_so2spinode *next; 233 }; 234 235 struct key_registry { 236 u intB type; /* secas soc type that key mgnt. daemon can acquire */ 237 struct socket *socket; /* key management daemon socket pointer */ 238 struct key_registry *next; 23 }i 240 2-1 '] 243 244 245 246 struct key_acquirelist { u_intB type; SOCKADDR *target; u_int32 count; u_long expiretime; struct key_acquirelist *next; /* secassoc type to acquire */ /* destination address of secas soc */ /* number of acquire messages sent */ /* expiration time for acquire message */ 247 }; 248 249 struct keyso_cb { 250 int ip4_count; 251 #ifdef INET6 252 int ip6_count; 253 #endif /* INET6 */ int any_count; 254 /* IPv4 */ /* IPv6 */ /* Sum of above counters */ 255 }; 256 2:)7 #endif 258 259 /* 260 * Useful macros 261 */ 262 263 #if 0 264 #define n) (p (t) malloc( (unsigned int) (n») 266 267 268 269 270 271 272 273 274 275 276 2'77 278 279 28C 281 282 283 284. 285 286 287 288 289 29C 291 292 293 294 295 296 #endif /* 0 */ #ifdef #ifdef void void int int KERNEL P key_init __ P«void»i key_cbinit __ P «void» i key_inittables __ P«void»i key_secassoc2msghdr __ p«struct key_secassoc *, struct key_msghdr *, struct key_msgdata *»i int key_msghdr2secassoc P«struct key_secassoc *, struct key_msghdr *, struct key_msgdata *»i int key_add __ P«struct key_secassoc *»i int key_delete __ P«struct key_secassoc *»; int key_get __ P«u_int, SOCKADDR *, SOCKADDR *, u_int32, struct key_secassoc **»i key_flush __P( (void» i void int key_dump __ P«struct socket *»i key_getspi __ p«u_int, SOCKADDR *, SOCKADDR *, int u_int32, u_int32, u_int32 *» i key_update __ P«struct key_secassoc *»i int key_register __ P«struct socket *, u_int»i int void key_unregister __ P«struct socket *, u_int, int»i int key_acquire __ p«u_int, SOCKADDR *, SOCKADDR *»i getassocbyspi __ P«u_int, SOCKADDR *, SOCKADDR *, int u_int32, struct key_tblnode **»i int getassocbysocket __ P«u_int, SOCKADDR *, SOCKADDR *, struct socket *, u_int, struct key_tblnode **» i void key_free __ P«struct key_tblnode *»i int keyyarse __ P «struct key_msghdr **km, struct socket *so, int *» i #endif /* P */ #endif 1 /*---------------------------------------------------------------------- key.c : Key Management Engine for BSD 3 4 5 6 7 copyright 1995 by Bao Phan, Randall Atkinson, & Dan McDonald, All Rights Reserved. All Rights have been assigned to the US Naval Research Laboratory (NRL). The NRL Copyright Notice and License governs distribution and use of this software. 8 9 10 11 12 1:3 14 15 Hi Patents are pending on this technology. NRL grants a license to use this technology at no cost under the terms below with the additional requirement that software, hardware, and documentation relating to use of this technology must include the note that: This product includes technology developed at and licensed from the Information Technology Division, US Naval Research Laboratory. 1B ----------------------------------------------------------------------*/ 19 /*---------------------------------------------------------------------- 20 # @(#) 22 COPYRIGHT NOTICE COPYRIGHT lola (NRL) 17 August 1995 23 24 :~5 26 All of the documentation and software included in this software distribution from the US Naval Research Laboratory (NRL) are copyrighted by their respective developers. 27 28 29 30 3.1 :n This software and documentation were developed at NRL by various people. Those developers have each copyrighted the portions that they developed at NRL and have assigned All Rights for those portions to NRL. outside the USA, NRL also has copyright on the software developed at NRL. The affected files all contain specific copyright notices and those notices must be retained in any derived work. :3:; NRL LICENSE :36 37 38 39 NRL grants permission for redistribution and use in source and binary forms, with or without modification, of the software and documentation created at NRL provided that the following conditions are met: "10 41 4') ~3 44 45 4f. ~7 49 50 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed at the Information Technology Division, US Naval Research Laboratory. 51 52 4. Neither the name of the NRL nor the names of its contributors 54 without specific prior written permission. S5 56 57 58 .59 60 61 62 63 64 65 66 THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 68 69 70 71 The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the US Naval Research Laboratory (NRL). 72 73 74 ----------------------------------------------------------------------*/ 75 76 77 7il 79 HO #ifdef linux #include <netkey/osdep_linux.h> #else /* linux */ #include <sys/param.h> #include <sys/proc.h> #include <sys/mbuf.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/time.h> #include <sys/kernel.h> #include <net/raw_cb.h> #include <net/if.h> #include <net/if_types.h> #include <net/if_dl.h> #include <net/route.h> #include <netkey/osdep_44bsd. h> #include <netinet/in_var.h> #include <netinet/if_ether.h> #endif / * linux * / 8:1 8~ 8 84 85 86 87 88 89 'JO 91 92 9.3 94 95 96 97 98 99 100 101 102 #include <netkey/key_debug.h> 1.:)4 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in6)) .1 S #ifdef INET6 #include <netinet6/in6.h> #include <netinet6/in6_var.h> #endif /* INET6 */ #include <netkey/key.h> ~L07 /* 103 109 * Not clear whether these values should be * tweakable at kernel config time. */ #define KEYTBLSIZE 61 #define KEYALLOCTBLSIZE 61 #define S02SPITBLSIZE 61 110 111 112 113 114 115 /* 116 11.7 * * 118 */ These values should be tweakable ... perhaps by using sysctl 1.19 121 #define MAXLARVALTIME 240i #define MAXKEYACQUIRE Ii 122 123 #define MAXACQUIRETIME 15; 120 12--l 125 126 127 128 129 DO J.31 /* Lifetime of a larval key table entry */ /* Max number of key acquire messages sent */ /* per destination address */ /* Lifetime of acquire message */ /* * Key engine tables and global variables */ struct key_tblnode keytable[KEYTBLSIZE]i struct key_allocnode keyalloctbl [KEYALLOCTBLSIZE] struct key_so2spinode s02spitbl [S02SPITBLSIZE] i i 32 :,3.0\ L:.4 J35 136 137 138 139 struct keyso_cb keyso_cbi struct key_tblnode nullkeynode = { a, a, a, a, a }i struct key_registry *keyregtablei struct key_acquirelist *key_acquirelisti u_Iong maxlarvallifetime = MAXLARVALTIME; int maxkeyacquire = MAXKEYACQUIREi u_Iong maxacquiretime = MAXACQUIRETIMEi 14.0 141 14·2 1-13 ;A5 146 extern SOCKADDR key_addri #define ROUNDUP (a) \ «a) > a ? (1 + « (a) #define ADVANCE (x, n) \ { x += ROUNDUP(n)i } 1) (sizeof(long) - 1») sizeof(long» H7 148 149 150 151 152 153 154 155 156 157 158 int my_addr __ P«SOCKADDR *»i int key_sendup __ P«struct socket *, struct key_msghdr *»i /*---------------------------------------------------------------------* key_secassoc2msghdr(): Copy info from a security association into a key message buffer. * Assume message buffer is sufficiently large to hold all security * * association information including src, dst, from, key and iv. ----------------------------------------------------------------------*/ int key_secassoc2msghdr DEFARGS«secassoc, km, keyinfo), struct key_secassoc *secassoc AND *km AND 160 .161 .162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 17'7 178 173 180 181 struct key_msgdata *keyinfo) { char *cp; DPRINTF(IDL_FINISHED, ("Entering key_secassoc2msghdr\n"»; if «km == 0) return(-l); II (keyinfo == 0) II (secassoc == 0» km->type = secassoc->type; km->state = secassoc->state; km->label = secassoc->label; km->spi = secassoc->spi; km->keylen = secassoc->keylen; km->ivlen = secassoc->ivleni km->algorithm = secassoc->algorithmi km->lifetype = secassoc->lifetypei km->lifetime1 secassoc->lifetime1i km->lifetime2 = secassoc->lifetime2i /* * * 1. 8~? Stuff src/dst/from/key/iv in buffer after the message header. */ = 18 cp 1>35 191 192 DPRINTF(IDL_FINISHED, ("sa2msghdr: l\n"»i keyinfo->src = (SOCKADDR *) CPi if (secassoc->src->sa_len) { bcopy(secassoc->src, cp, secassoc->src->sa_len)i ADVANCE (cp, secassoc->src->sa_len); } else { bzero(cp, MAX_SOCKADDR_SZ)i ADVANCE (cp, MAX_SOCKADDR_SZ)i 193 } ii.56 187 188 189 190 (char *) (km + l)i 1 :;'4 1')5 196 197 198 199 200 201 202 203 204 205 206 207 208 2()'j 21G 211 DPRINTF (IDL_FINISHED, ("sa2msghdr: 2\n"» i keyinfo->dst = (SOCKADDR *)CPi if (secassoc->dst->sa_len) { bcopy(secassoc->dst, cp, secassoc->dst->sa_len)i ADVANCE (cp, secassoc->dst->sa_len); } else { bzero(cp, MAX_SOCKADDR_SZ); ADVANCE (cp, MAX_SOCKADDR_SZ)i } DPRINTF(IDL_FINISHED, ("sa2msghdr: 3\n"»i keyinfo->from = (SOCKADDR *)cp; if (secassoc->from->sa_len) { bcopy(secassoc->from, cp, secassoc->from->sa_len)i ADVANCE (cp, secassoc->from->sa_len) i } else { MAX_SOCKADDR_SZ)i 213 } 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 DPRINTF(IDL_FINISHED, keyinfo->key = cp; keyinfo->keylen = secassoc->keylen; if (secassoc->keylen) { bcopy«char *) (secassoc->key), cp, secassoc->keylen); ADVANCE (cp, secassoc->keylen); } DPRINTF(IDL_FINISHED, ("sa2msghdr: 5\n ll »; keyinfo->iv = cp; keyinfo->ivlen = secassoc->ivlen; if (secassoc->ivlen) { bcopy( (char *) (secassoc->iv), cp, secassoc->ivlen); ADVANCE (cp, secassoc->ivlen); } DDO (IDL_FINISHED,printf (IImsgbuf (len=%d) : \n", (char *) cp - (char *)km»; DDO(IDL_FINISHED,dump_buf«char *)km, (char *)cp - (char *)km»; DPRINTF(IDL_FINISHED, ("sa2msghdr: 6\n ll »; return(O); 233 234 ") ') r:: L.._' .) 236 (IIsa2msghdr: 4\n ll »; } 237 238 239 /*---------------------------------------------------------------------- 240 * key_msghdr2secassoc(): 2/11 * * 242 243 244 245 246 247 248 2,:[ 9 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 Copy info from a key message buffer into a key_secassoc structure ----------------------------------------------------------------------*/ int key_msghdr2secassoc DEFARGS«secassoc, km, keyinfo), struct key_secassoc *secassoc AND struct key_msghdr *km AND struct key_msgdata *keyinfo) { DPRINTF (IDL_FINISHED, ("Entering key_msghdr2secassoc\n"»; if «km == 0) return(-l); II (keyinfo == 0) II (secassoc == 0» secassoc->len = sizeof(*secassoc); secassoc->type = km->type; secassoc->state = km->state; secassoc->label = km->label; secassoc->spi = km->spi; secassoc->keylen = km->keylen; secassoc->ivlen = km->ivlen; secassoc->algorithm = km->algorithm; secassoc->lifetype = km->lifetype; secassoc->lifetimel km- >lifetimel; secassoc->lifetime2 = km->lifetime2; 266 267 268 if 269 270 271 272 273 274 275 276 277 278 279 280 281 282 28? 2134 285 286 287 2SfJ 289 290 291 292 } bcopy«char *)keyinfo->src, (char *)secassoc->src, keyinfo->src->sa_len); } else secassoc->src = NULL; if (keyinfo->dst) { KMALLOC(secassoc->dst, SOCKADDR *, keyinfo->dst->sa_len); if (!secassoc->dst) { DPRINTF (IDL_ERROR, ("msghdr2secassoc: can't allocate mem for dst\n"»; return(-l); } bcopy«char *)keyinfo->dst, (char *)secassoc->dst, keyinfo->dst->sa_len); } else secassoc->dst = NULL; if 293 294 295 S>t': 297 (keyinfo->src) { KMALLOC(secassoc->src, SOCKADDR *, keyinfo->src->sa_len); if (!secassoc->src) { DPRINTF (IDL_ERROR, ("msghdr2secassoc: can't allocate mem for src\n"»; return(-l); (keyinfo->from) { KMALLOC(secassoc->from, SOCKADDR *, keyinfo->from->sa_len); if (!secassoc->from) { DPRINTF (IDL_ERROR, ("msghdr2secassoc: can't allocate mem for from\n"»; return(-l); } bcopy( (char *)keyinfo->from, keyinfo->from->sa_len); } else secassoc->from = NULL; (char *) secassoc->from, 29}3 299 30G 301 3G2 303 ~04 305 3D6 307 /* * Make copies of key and iv */ if (secassoc->ivlen) { KMALLOC(secassoc->iv, caddr t, secassoc->ivlen); if (secassoc->iv == 0) { DPRINTF (IDL_ERROR, ("msghdr2secassoc: can't allocate mem for iv\n"»; return(-l); } 308 309 310 bcopy( (char *)keyinfo->iv, } else secassoc->iv " NULL; 312 if (secassoc->keylen) { KMALLOC (secas soc ->key, caddr_t, secassoc->keylen); if (secassoc->key "" 0) { DPRINTF(IDL_ERROR, ("msghdr2secassoc: can't allocate mem for key\n"»; if (secassoc->iv) KFREE(secassoc->iv); J.3 314 315 316 317 (char *) secassoc->iv, secassoc->ivlen); 319 320 321 322 323 324 } bcopy«char *)keyinfo->key, (char *)secassoc->key, secassoc->keylen)i } else secassoc->key = NULL; return(O); } 325 326 327 /*---------------------------------------------------------------------- 328 329 * addrpart_equal(): * Determine if the address portion of two sockaddrs are equal. * Currently handles only AF_INET and AF_INET6 address families. 3~.O ----------------------------------------------------------------------*/ 33] "'2 333 334 335 336 int addrpart_equal DEFARGS «sal, sa2), SOCKADDR *sal AND SOCKADDR *sa2) { if «sal->sa_family != sa2->sa_family) 338 II return 0; 339 .340 341 34 JeLl 34~ 345 346 3·.17 348 switch (sal->sa_family) { case AF INET: return «(struct sockaddr_in *)Sal)->sin_addr.s_addr «struct sockaddr_in *) sa2) ->sin_addr.s_addr); #ifdef INET6 case AF INET6: return (IN6_ADDR_EQUAL«(struct sockaddr in6 *)sal)->sin6 addr, «struct sockaddr_in6 *) sa2) ->sin6_addr» ; #endif /* INET6 */ 349 } 350 return(O); 351 } 352 353 354 355 356 357 358 359 /*---------------------------------------------------------------------- * key_inittables(): * Allocate space and initialize key engine tables ----------------------------------------------------------------------*/ int key_inittables { _P( (void» int ii 360 361 362 363 364 365 366 367 368 369 :>.70 KMALLOC(keyregtable, struct key_registry *, sizeof(struct key_registry»; if (!keyregtable) return -1; bzero«char *)keyregtable, sizeof(struct key_registry»; KMALLOC(key_acquirelist, struct key_acquirelist *, sizeof(struct key_acquirelist»; if (!key_acquirelist) return -1; bzero«char *)key_acquirelist, sizeof(struct key_acquirelist»; for (i = < KEYTBLSIZE; i++) 375 for (i = 0; i bzero«char for (i = 0; i bzero«char 376 377 return 0; 372 373 374 < KEYALLOCTBLSIZE; i++) *)&keyalloctbl[i], sizeof(struct key_allocnode»; < S02SPITBLSIZE; i++) *)&so2spitbl[i], sizeof(struct key_so2spinode»; 378 379 } 380 int key_freetables __ P«void» fll { 382 KFREE(keyregtable); keyregtable = NULL; KFREE(key_acquirelist); key_acquirelist = NULL; return 0; 3,)3 384 385 386 387 } 388 389 /*---------------------------------------------------------------------* key_gethashval () : 390 391 * '392 ----------------------------------------------------------------------*/ Determine key table hash value. 396 int key_gethashval DEFARGS «buf, len, tblsize), char *buf AND int len AND int tblsize) 397 { 393 .3 ';'-; 3 in t 3'" 8 i, j = 0; 399 400 01 402 40'3 404 /* * Todo: Use word size xor and check for alignment * and zero pad if necessary. Need to also pick * a good hash function and table size. */ 4G5 if 406 407 408 ,aG,; (len <= 0) { DPRINTF(IDL_ERROR, ("key_gethashval got bogus len!\n"»; return (-1) ; } for (i 410 j 411 412 A = 0; i < len; i++) { (u_int8) (* (buf + i»; } return (j % tblsize); 413 } 414 415 416 /*---------------------------------------------------------------------- 417 418 419 420 * key_createkey(): Create hash key for hash function * key is: type+src+dst if keytype = 1 * type+src+dst+spi if keytype = 0 Uses only the address portion of the src and dst sockaddrs to form key. Currently handles only AF_INET and AF_INET6 sockaddrs 422 * * * 423 ----------------------------------------------------------------------*/ 421 425 426 427 428 429 430 4c'.1 char *buf AND u_int type AND SOCKADDR *src AND SOCKADDR *dst AND u_int32 spi AND u_int keytype) { 432 char *cp, *p; 433 ..D4 DPRINTF (IDL_FINISHED, ("Entering key_createkey\n"»; 435 436 437 if (!buf II ! src return(-1); II ! dst) 438 439 440 441 442 443 444 445 ·146 :;'4';' 4 8 449 450 cp = buf; bcopy«char *)&type, cp, sizeof(type»; cp += sizeof(type); #ifdef INET6 /* * Assume only IPv4 and IPv6 addresses. */ #define ADDRPART (a) \ «a)->sa_family == AF_INET6) ? \ (char *)&«(struct sockaddr_in6 *) (a»->sin6 addr) (char *)&«(struct sockaddr in *) (a»->sin_addr) \ 451 452 453 454 455 4.56 457 458 #define ADDRSIZE(a) \ «a)->sa_family == AF_INET6) ? sizeof(struct in_addr6) \ sizeof(struct in_addr) #else /* INET6 */ #define ADDRPART (a) (char *) &« (struct sockaddr in *) (a» ->sin_addr) #define ADDRSIZE(a) sizeof(struct in_addr) #endif /* INET6 */ ·J.59 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 DPRINTF(IDL_FINISHED, ("src addr:\n"»; DDO(IDL_FINISHED,dump_smart_sockaddr(src»; DPRINTF (IDL_FINISHED, ("dst addr: \n"» ; DDO(IDL_FINISHED,dump_smart_sockaddr(dst»; P = ADDRPART(src); bcopy(p, cp, ADDRSIZE(src»; cp += ADDRSIZE(src); P = ADDRPART(dst) ; bcopy(p, cp, ADDRSIZE(dst»; cp += ADDRSIZE(dst); #undef ADDRPART #undef ADDRSIZE if (keytype 0) { cp += sizeof(spi); 478 479 480 } 481 482 483 DPRINTF (IDL_FINISHED, ("hash key: \n"» ; DDO(IDL_FINISHED, dump_buf(buf, cp - buf»; return(cp - buf); 484 485 } 486 487 488 489 490 491 492 493 494 4(;,~) 496 497 498 /*---------------------------------------------------------------------* key_sosearch(): * Search the s02spi table for the security association allocated to * the socket. Returns pointer to a struct key_sofspinode which can * be used to locate the security association entry in the key table. ----------------------------------------------------------------------*/ struct key_s02spinode *key_sosearch DEFARGS«type, u_int type AND SOCKADDR *src AND SOCKADDR *dst AND struct socket *so) { struct key_s02spinode *np 0; src, dst, so), .500 503 if (! (src && dst» { DPRINTF (IDL_ERROR, ("key_sosearch: got null src or dst pointer! \n"»; return(NULL); 50'l } 501 502 50S 506 for (np = s02spitbl[«u_int32)so) % S02SPITBLSIZE] . next; np; np = np->next) { if «so == np->socket) && (type == np->keynode->secassoc->type) && addrpart_equal(src, np->keynode->secassoc->src) && addrpart_equal (dst, np->keynode->secassoc->dst» return(np) ; 5(n 508 509 510 511 } 512 513 return(NULL); } 514 51..5 516 /*---------------------------------------------------------------------- 517 * key_sodelete(): Delete entries from the s02spi table. * flag = 1 purge all entries * * flag = 0 delete entries with socket pointer matching socket 518 519 520 521 522 523 524 525 526 527 528 529 ----------------------------------------------------------------------*/ void key_sodelete DEFARGS«socket, flag), struct socket *socket AND int flag) { struct key_s02spinode *prevnp, *np; CRITICAL_DCL CRITICAL_START; 531 532 DPRINTF(IDL_EVENT, ("Entering keysodelete w/so=Ox%x flag=%d\n", (unsigned int) socket, flag)); 533 534 if (flag) { int i; 535 536 538 539 540 541 (i 0; i < S02SPITBLSIZE; i++) for(np = so2spitbl[i] . next; np; np KFREE (np) ; } CRITICAL_END; 542 543 } 537 544 545 546 547 548 549 550 551 for np->next) { return; prevnp = &so2spitbl[«u_int32)socket) % S02SPITBLSIZE]; for(np = prevnp->next; np; np = np->next) { if (np->socket == socket) { struct socketlist *socklp, *prevsocklp; (np->keynode->alloc_count)--; /* 552 553 * If this socket maps to a unique secassoc, * we go ahead and delete the secassoc, since it * can no longer be allocated or used by any other * socket. 5'54 555 SSG */ S";? 558 if (np->keynode->secassoc->state & K_UNIQUE) 56J. (key_delete (np->keynode->secassoc) panic ("key_sodelete"); np = prevnp; :362 } 'oCO if * We traverse the socketlist and remove the entry * for this socket 567 */ 568 57(\ 571 572 573 574 DPRINTF (IDL_FINISHED, ("keysodelete: deleting from socklist ... ")) ; prevsocklp = np->keynode->solist; for (socklp = prevsocklp->next; socklp; socklp = socklp->next) { if (socklp->socket == socket) { prevsocklp->next = socklp->next; KFREE(socklp); break; 575 576 577 } prevsocklp = socklp; 578 } 579 DPRINTF (IDL_FINISHED, ("done\n")); prevnp->next = np->next; KFREE(np); np = prevnp; 580 581 582 0) /* 566 569 ! = { continue; 563 564 565 ",')9 584 prevnp 585 586 587 588 589 590 np; CRITICAL_END; } /*---------------------------------------------------------------------- 591 592 * key_deleteacquire(}: * Delete an entry from the key_acquirelist 593 594 595 596 5:,,7 ::;98 599 600 601 602 603 = } ----------------------------------------------------------------------*/ void key_deleteacquire DEFARGS«type, target}, u_int type AND SOCKADDR *target} { struct key_acquirelist *ap, *prev; prev = key_acquirelist; for(ap = key_acquirelist->next; ap; ap = ap->next} { if (addrpart_equal(target, (SOCKADDR *)&(ap->target}} && (type == ap->type)} { DPRINTF (IDL_EVENT, ("Deleting entry from acquire list! \n") } ; prev->next = ap->next; KFREE (ap) ; prev; ap bOLl- 607 GOil } 609 610 prev 611 ap; } } 612 613 614 615 616 6J7 618 619 620 621. 622 623 624 6~~ 626 627 628 629 630 631 632 633 634 635 /*---------------------------------------------------------------------* key_search () : Search the key table for an entry with same type, src addr, dest addr, and spi. Returns a pointer to struct key_tblnode if found * else returns null. * * ----------------------------------------------------------------------*/ struct key_tblnode *key_search DEFARGS( (type, src, dst, spi, indx, prevkeynode), u_int type AND SOCKADDR *src AND SOCKADDR *dst AND u_int32 spi AND int indx AND struct key_tblnode **prevkeynode} { struct key_tblnode *keynode, *prevnode; if (indx > KEYTBLSIZE I I indx < O) return (NULL); if (! (&keytable[indx]}) return (NULL); 537 638 639 #define sec_spi keynode->secassoc->spi #define sec src keynode->secassoc->src #define sec dst keynode->secassoc->dst 640 54:L prevnode = &keytable [indx] ; for (keynode = key table [indx] .next; keynode; keynode if ((type == sec_type) && (spi sec_spi) && addrpart_equal (src, sec_src) && addrpart_equal(dst, sec_dst» break; prevnode = keynode; } *prevkeynode = prevnode; return(keynode); 642 64.3 64S 646 647 648 649 650 651 keynode->next) { } 652 65.3 654 655 /*---------------------------------------------------------------------* key_addnode(): 656 * 6':)7 658 659 660 * Insert a key_tblnode entry into the key table. to the newly created key_tblnode. Returns a pointer ----------------------------------------------------------------------*/ 66:1. struct key_tblnode *key_addnode DEFARGS((indx, secassoc), int indx AND struct key_secassoc *secassoc) 61(,2 { 663 struct key_tblnode *keynode; 664 6<';5 566 667 658 669 570 671 672 DPRINTF (IDL_FINISHED, ("Entering key_addnode w/indx=%d secassoc=Ox%x\n", indx, (unsigned int)secassoc»; (! (&keytable[indx]» return (NULL) ; if (!secassoc) { panic("key_addnode: Someone passed in a null secassoc!\n"); } if 673 574 675 676 677 KMALLOC(keynode, struct key_tblnode *, sizeof(struct key_tblnode»; if (keynode == 0) return (NULL) ; bzero((char *)keynode, sizeof(struct key_tblnode»; 578 679 684 KMALLOC(keynode->solist, struct socketlist *, sizeof(struct socketlist»; if (keynode->solist == 0) { KFREE(keynode); return(NULL); } bzero ((char *) (keynode->solist), sizeof (struct socketlist»; 685 686 687 6S8 keynode->secassoc = secassoc; keynode->solist->next = NULL; keynode->next = key table [indx] .next; 680 681 582 583 690 691 return(keynode); } 692 693 694 695 6% 697 698 699 700 701 702 70:3 704 7 () 5 06 7(,7 70S 7" 'II!) 711 /*---------------------------------------------------------------------* key_add () : Add a new security association to the key table. Caller is * responsible for allocating memory for the key_secassoc as * well as the buffer space for the key and iv. Assumes the security * * association passed in is well-formed. ----------------------------------------------------------------------*/ int key_add DEFARGS«secassoc), struct key_secassoc *secassoc) { char buf [MAXHASHKEYLEN] ; int len, indx; int inbound = 0; int outbound = 0; struct key_tblnode *keynode, *prevkeynode; struct key_allocnode *np = NULL; CRITICAL DCL 712 713 714 DPRINTF (IDL_FINISHED, ("Entering key_add w/secassoc=Ox%x\n", (unsigned int) secassoc) ) ; 71~) 716 7j 7 if (!secassoc) { panic ("key_add: who the hell is passing me a null pointer"); 'lItl } 719 720 721 722 723 724 725 726 727 728 729 730 731 '732 733 734 /* * Should we allow a null key to be inserted into the table ? * or can we use null key to indicate some policy action ... */ #if 0 /* * For esp using des-cbc or tripple-des we call * des_set_odd.Jlarity. */ if (secassoc->key && (secassoc->type == KEY_TYPE_ESP) && «secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) II (secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES») des_set_odd.Jlarity(secassoc->key); #endif /* 0 */ 735 736 /* 737 * 738 */ 739 740 741 Check if secas soc with same spi exists before adding bzero ( (char *) &buf, sizeof (buf) ) ; len = key_createkey«char *)&buf, secassoc->type, secassoc->src, secassoc->dst, 0) ; KEYTBLSIZE 743 744 745 746 747 748 749 DPRINTF{IDL_FINISHED, (Ilkeyadd: keytbl hash position=%d\n", indx»; keynode = key_search{secassoc->type, secassoc->src, secassoc->dst, secassoc->spi, indx, &prevkeynode); if (keynode) { DPRINTF{IDL_EVENT, (Ilkeyadd: secas soc already exists!\n"»; return{-2); } 750 751 752 753 inbound = my_addr{secassoc->dst); outbound = my_addr{secassoc->src); DPRINTF{IDL_FINISHED, (llinbound=%d outbound=%d\n", inbound, outbound»; 754 755 756 757 7~) /* * * * * >3 759 We allocate mem for an allocation entry if needed. This is done here instead of in the allocaton code segment so that we can easily recover/cleanup from a memory allocation error. */ 760 766 if {outbound I I (!inbound && !outbound» { KMALLOC{np, struct key_allocnode *, sizeof{struct key_allocnode»; i f (np == 0) { DPRINTF{IDL_ERROR, (Ilkeyadd: can't allocate allocnode!\n ll »; return ( -1) ; } 7(:'7 } 761 762 763 764 <-J,"r:: I Q ,.J 768 769 ,~. ; CRITICAL_START; "7 t', ,l.; 771 Tn 773 774 775 776 777 778 779 780 if {{keynode = key_addnode (indx, secassoc» == NULL) { DPRINTF{IDL_ERROR, (Ilkeyadd: key_addnode failed!\n"»; i f (np) KFREE (np) ; CRITICAL_END; return{-l); } DPRINTF {IDL_GROSS_EVENT, (IIAdded new keynode: \n"» ; DDO{IDL_FINISHED, dump_keytblnode{keynode»; DDO{IDL_FINISHED, dump_secassoc{keynode->secassoc»; 7>31 782 783 784 785 786 78'7 '788 789 790 791 792 793 794 /* * * * * * * * We add an entry to the allocation table for this secas soc if the interfaces are up and the secassoc is outbound. In the case where the interfaces are not up, we go ahead and do it anyways. This wastes an allocation entry if the secassoc later turned out to be inbound when the interfaces are ifconfig up. */ if {outbound I I (!inbound && !outbound» { len = key_createkey{{char *)&buf, secassoc->type, secassoc->src, secassoc->dst, 0, 1); indx = key_gethashval ({char *) &buf, len, KEYALLOCTBLSIZE); DPRINTF 796 797 798 799 np- >keynode = keynode; np->next = keyalloctbl[indx] . next; keyalloctbl [indx] .next = np; } (inbound) secassoc->state 1= K_INBOUND; if (outbound) secassoc->state 1= K_OUTBOUND; if 800 801 802 803 804 805 806 key_deleteacquire(secassoc->type, secassoc->dst}; 07 CRITICAL_END; return 0; 808 809 810 811 812 fn:; 814 815 816 817 818 8}9 ii20 E;:~: } /*---------------------------------------------------------------------* key_get () : * Get a security association from the key table. ----------------------------------------------------------------------*/ int key_get DEFARGS«type, src, dst, spi, secassoc}, u_int type AND SOCKADDR *src AND SOCKADDR *dst AND u_int32 spi AND struct key_secassoc **secassoc} char buf[MAXHASHKEYLEN]; struct key_tblnode *keynode, *prevkeynode; int len, indx; 823 1324 82:; B26 827 828 829 830 bzero(&buf, sizeof(buf}}; *secassoc = NULL; len = key_createkey«char *}&buf, type, src, dst, spi, O}; indx = key_gethashval «char *) &buf, len, KEYTBLSIZE}; DPRINTF(IDL_FINISHED, ("keyget: indx=%d\n",indx)}; keynode = key_search(type, src, dst, spi, indx, &prevkeynode}; if (keynode) { DPRINTF(IDL_GROSS_EVENT, ("keyget: found it! keynode=Ox%x", (unsigned int) keynode) } ; *secassoc = keynode->secassoc; 831 832 333 83·± 8 35 836 837 838 return (O) ; } else return(-l}; 839 840 /* Not found */ } 841 842 843 844 846 847 /*---------------------------------------------------------------------- * key_dump(): Dump all valid entries in the key table to a pf_key socket. Each * security associaiton is sent one at a time in a pf_key message. A * message with seqno = 0 signifies the end of the dump transaction. * 850 849 int key_dump DEFARGS ((so), struct socket *so) 8.")1 { 852 853 85~ 855 856 857 int len, i; int seq = 1; struct key_msgdata keyinfo; struct key_msghdr *km; struct key_tblnode *keynode; extern SOCKADDR key_addr; 858 859 860 861 862 863 864 865 866 867 868 869 870 871 8'r~ 8'73 874 875 876 /* * Routine to dump the key table to a routing socket * Use for debugging only! */ KMALLOC(km, struct key_msghdr *, sizeof(struct key_msghdr) + 3 * MAX SOCKADDR_SZ + MAX KEY_SZ + MAX_IV_SZ); if (!km) return (ENOBUFS); DPRINTF(IDL_FINISHED, ("Entering key_dump() II»~; /* * We need to speed this up later. Fortunately, key_dump * messages are not sent often. */ for (i = 0; i < KEYTBLSIZE; i++) { for (keynode = keytable[iJ .next; keynode; keynode = keynode->next) { /* [3'77 * We exclude dead/larval/zombie security associations for now 878 * but it may be useful to also send these up for debugging purposes */ 879 880 881 if (keynode->secassoc->state & (K_DEAD continue; K LARVAL 882 883 884 886 888 len = (sizeof(struct key_msghdr) + ROUNDUP (keynode->secassoc->src->sa_len) + ROUNDUP (keynode->secassoc->dst->sa_len) + ROUNDUP (keynode->secassoc->from->sa_len) + ROUNDUP (keynode->secassoc->keylen) + ROUNDUP(keynode->secassoc->ivlen»; 889 890 891 892 893 894 895 8% 897 il9il if (key_secassoc2msghdr(keynode->secassoc, km, &keyinfo) panic ("key_dump"); km->key_msglen = len; km->key_msgvers = KEY_VERSION; km->key_msgtype = KEY_DUMP; km->key-pid = CURRENT_PID; km->key_seq = seq++; km->key_errno = 0; 8 90() key_sendup(so, km); != 0) 902 } 903 904 905 906 907 908 909 bzero«char *)km, sizeof(struct key_msghdr»; km->key_msglen = sizeof(struct key_msghdr); km->key_msgvers; KEY_VERSION; km->key_msgtype ; KEY_DUMP; km->key~id = CURRENT_PID; km->key_seq = 0; km->key_errno = 0; 910 911 912 913 914 key_sendup(so, km); KFREE(km); DPRINTF(IDL_FINISHED, (IlLeaving key_dump()\n"»; return(O); 915 916 } 917 /*---------------------------------------------------------------------* key_delete (): * Delete a security association from the key table. 9l.8 919 920 921 922 int key_delete DEFARGS( (secassoc), struct key_secassoc *secassoc) 9:23 { 924 92':> 926 927 92E 9~~9 930 931 ----------------------------------------------------------------------*/ char buf [MAXHASHKEYLEN] ; int len, indx; struct key_tblnode *keynode = 0; struct key_tblnode *prevkeynode = 0; struct socketlist *socklp, *deadsocklp; struct key_so2spinode *np, *prevnp; struct key_allocnode *ap, *prevap; CRITICAL DCL 93 933 934 DPRINTF(IDL_FINISHED, (IlEntering key_delete w/secassoc=ox%x\n", (unsigned int)secassoc»; 935 936 937 938 (;39 940 941 942 bzero«char *)&buf, sizeof(buf»; len = key_createkey«char *)&buf, secassoc->type, secassoc->src, secassoc->dst, secassoc->spi, 0); indx = key_gethashval «char *) &buf, len, KEYTBLSIZE); DPRINTF(IDL_FINISHED, (Ilkeydelete: keytbl hash position=%d\n", indx»; keynode = key_search(secassoc->type, secassoc->src, secassoc->dst, secassoc->spi, indx, &prevkeynode); 943 944 945 946 947 if (keynode) { CRITICAL_START; DPRINTF(IDL_GROSS_EVENT, ("keydelete: found keynode to delete\n"»; keynode->secassoc->state 1= K_DEAD; 948 949 950 951 952 if (keynode->ref_count > 0) { DPRINTF(IDL_EVENT, (Ilkeydelete: secas soc still held, marking for deletion only!\n"»; CRITICAL_END; return(O); prevkeynode->next 955 keynode- >next; ~;S6 /* * Walk the socketlist and delete the * entries mapping sockets to this secassoc * from the so2spi table. */ 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 DPRINTF (IDL_FINISHED, ("keydelete: deleting socklist ... II» ; for(socklp = keynode->solist->next; socklp; ) { prevnp = &so2spitbl [( (u_int32) (socklp->socket» % S02SPITBLSIZE]; for(np = prevnp->next; np; np = np->next) { if «np->socket == socklp->socket) && (np->keynode == keynode» { prevnp ->next = np->next; KFREE (np) ; break; } prevnp = np; } deadsocklp = socklp; socklp = socklp->next; KFREE(deadsocklp); 976 } sn DPRINTF (IDL_FINISHED, ("done\n"»; Sl7i:l /* * If an allocation entry exist for this * secassoc, delete it. */ 979 980 981 9il2 98:3 984 985 986 987 98e 989 990 991 992 993 994 995 bzero «char *) &buf, sizeof (buf» ; len = key_createkey( (char *) &buf, secassoc->type, secassoc->src, secassoc->dst, 0, 1); indx = key_gethashval«char *)&buf, len, KEYALLOCTBLSIZE); DPRINTF (IDL_FINISHED, (likeydelete: alloctbl hash position=%d\n", indx»; prevap = &keyalloctbl[indx]; for (ap = prevap->next; ap; ap = ap->next) { if (ap->keynode == keynode) { prevap->next = ap->next; KFREE(ap); break; } prevap ap; } 996 997 998 9Sl e) 1000 1.001 l002 1003 1004 1.005 if (keynode->secassoc->iv) KFREE(keynode->secassoc->iv); if (keynode->secassoc->key) KFREE(keynode->secassoc->key); KFREE(keynode->secassoc); if (keynode->solist) KFREE(keynode->solist); KFREE (keynode) ; CRITICAL_END; } return (-1) ; 1007 1.008 1009 } 1010 1011 1012 /*---------------------------------------------------------------------- 1013 1014 * key_ flush () : * Delete all entries from the key table. 1015 ----------------------------------------------------------------------*/ 1016 void key_flush _P( (void)) 1017 { 1018 1019 struct key_tblnode *keynode; int i; 1020 /* * This is slow, but simple. 1022 */ J.023 1027 1028 DPRINTF(IDL_FINISHED, ("Flushing key table ... ")); for (i = 0; i < KEYTBLSIZE; i++) { while «keynode = keytable[i].next)) if (key_delete (keynode->secassoc) != 0) panic ("key_flush"); 1030 DPRINTF(IDL_FINISHED, ("done\n")); J.024 1025 1026 } n:n } 1033 1034 1035 /*---------------------------------------------------------------------- 1036 * key_getspi(): Get a unique spi value for a key management daemon/program. The * spi value, once assigned, cannot be assigned again (as long as the * entry with that same spi value remains in the table) . * 1.037 1038 1039 ----------------------------------------------------------------------*/ 1040 int key_getspi DEFARGS«type, src, dst, lowval, highval, spi), J.OrL u_int type AND 10l.J2 SOCKADDR *src AND lG43 SOCKADDR *dst AND 1.()44 u int32 lowval AND (J·E; u int32 highval AND 1046 u int32 *spi) 1047 { 1048 1049 1.050 1051 ".1052 1053 10.54 struct key_secassoc *secassoc; struct key_tblnode *keynode, *prevkeynode; int count, done, len, indx; int maxcount = 1000; u_int32 val; char buf[MAXHASHKEYLEN]; CRITICAL DCL 1055 1.056 1057 1058 DPRINTF(IDL_EVENT, ("Entering getspi w/type=%d,low=%u,high=%u\n", type, lowval, highval)); if (! (src && dst)) 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 ~L072 1073 .1.074 1075 1076 if «lowval == 0) return (EINVAL) ; II if (lowval > highval) u_int32 temp; temp = lowval; lowval = highval; highval = lowval; } done = count do { count++; (highval 0» { 0; /* * This may not be "random enough". */ val 10'7'7 = lowval + (random() % (highval - lowval + 1»; lon 1079 1080 1081 1082 .1080 1087 108B 1089 1090 1091 1092 lOS3 if (lowval == highval) count = maxcount; DPRINTF (IDL_FINISHED, (" %u ",val); i f (val) { DPRINTF (IDL_FINISHED, (" \n") ) ; bzero(&buf, sizeof(buf»; len = key_createkey«char *)&buf, type, src, dst, val, 0); indx = key_gethashval«char *)&buf, len, KEYTBLSIZE); if (lkey_search(type, src, dst, val, indx, &prevkeynode» { CRITICAL_START; KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc»; if (secassoc == 0) { DPRINTF (IDL_ERROR, ("key_getspi: can't allocate memory\n"»; CRITICAL_END; return(ENOBUFS); 1094 } 1095 1096 10';7 109S 1099 1100 1101 1102 1103 1104 1105 bzero«char *)secassoc, sizeof(*secassoc»; DPRINTF (IDL_FINISHED, ("getspi: indx=%d\n", indx) ) ; secassoc->len = sizeof(struct key_secassoc); secassoc->type = type; secassoc->spi = val; secassoc->state 1= K_LARVAL; if (my_addr(secassoc->dst» secassoc->state 1= K_INBOUND; if (my_addr(secassoc->src» secassoc->state 1= K_OUTBOUND; J.I06 lJ. 07 1108 1109 J.110 ll11 bcopy«char *)src, bcopy( (char *) dst, (char *)secassoc->src, src->sa_Ien); (char *)secassoc->dst, dst->sa_Ien); /* We fill this in with a plausable value now to insure that other routines don't break. These will get overwritten later with the correct values. * 1113 #ifdef INET6 1114 secassoc->from->sa_family = AF_INET6; 1115 secassoc->from->sa_len = sizeof(struct sockaddr_in6); 1116 #else /* INET6 */ 111'1 secassoc->from->sa_family = AF_INET; 1118 secassoc->from->sa_len = sizeof(struct sockaddr_in); 1119 #endif /* INET6 */ 1120 1121 /* 1.122 * * * * * 1123 1124. J..1.25 1126 We need to add code to age these larval key table entries so they don't linger forever waiting for a KEY_UPDATE message that may not come for various reasons. This is another task that key_reaper can do once we have it coded. */ 1127 1128 secassoc->lifetimel += TIME SECONDS + maxlarvallifetime; 1130 lL31 if 1132 J.133 J.134 U36 1137 1138 1139 } DPRINTF(IDL_FINISHED, (lIkey_getspi: added node Ox%x\n", (unsigned int)keynode»; done++; CRITICAL_END; } } 114 () 11·12 1.143 1144 1145 1 J.46 1147 1148 (! (keynode = key_addnode(indx, secassoc») { DPRINTF(IDL_ERROR, (lIkey_getspi: can't add node\n"»; CRITICAL_END; return(ENOBUFS); } while «count < maxcount) && !done); DPRINTF(IDL_EVENT, (llgetspi returns w/spi=%u,count=%d\n",val,count»; i f (done) { *spi = val; return(O); } else { *spi = 0; return(EADDRNOTAVAIL); } 1149 1150 } 1151 1152 1153 /*---------------------------------------------------------------------- 1154 * key_update(): 1155 * Update a key table entry that has an spi value assigned but is 1156 * incomplete (e.g. no key/iv) . 1157 ----------------------------------------------------------------------*/ 1.158 int key_update DEFARGS«secassoc), 1159 struct key_secassoc *secassoc) 1160 { 1161 1162 1163 1164 struct key_tblnode *keynode, *prevkeynode; struct key_allocnode *np = 0; u int8 news tate; int len, indx, inbound, outbound; char buf 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 CRITICAL DCL bzero(&buf, sizeof(buf»i len = key_createkey((char *)&buf, secassoc->type, secassoc->src, secassoc->dst, secassoc->spi, O)i indx = key_gethashval((char *)&buf, len, KEYTBLSIZE)i if(! (keynode = key_search(secassoc->type, secassoc->src, secassoc->dst, secassoc->spi, indx, &prevkeynode») { return(ESRCH)i } if 1177 (keynode->secassoc->state & K_DEAD) return (ESRCH) i LL 78 1179 J.J_80 /* Should we also restrict updating of only LARVAL entries? */ 1181 CRITICAL_STARTi 1.182 11.B3 118 '0 11g6 1187 inbound = my_addr(secassoc->dst)i outbound my_addr(secassoc->src)i news tate = keynode->secassoc->statei news tate &= -K_LARVALi 1192 (inbound) news tate /= K_INBOUNDi if (outbound) news tate /= K_OUTBOUNDi 1193 119 t J if 2..89 if 1195 11% 1197 1199 l200 120~L 1202 1203 1204 1205 1206 1207 1208 1209 1210 (outbound / / (!inbound && !outbound» { KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode»i i f (np == 0) { DPRINTF (IDL_ERROR, ("keyupdate: can't allocate allocnode! \nll) ) i CRITICAL_ENDi return(ENOBUFS)i } } /* * Free the old key and iv if they're there. */ if (keynode->secassoc->key) KFREE(keynode->secassoc->keY)i if (keynode->secassoc->iv) KFREE(keynode->secassoc->iv)i 1211 1212 /* 1213 * * 1214 * 1215 1216 1217 We now copy the secassoc over. We don't need to copy the key and iv into new buffers since the calling routine does that already. */ * (keynode->secassoc) = *secassoci 1219 1220 /* 1221 * Should we allow a null key to be inserted into the table ? * or can we use null key to indicate some policy action ... 1222 */ 1223 1224 1225 #if 0 1226 if (keynode->secassoc->key && 1227 (keynode->secassoc->type == KEY_TYPE_ESP) && 1228 «keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) 1229 (keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES») 1230 des_set_oddyarity(keynode->secassoc->key); 1231 #endif /* 0 */ II 1232 1233 123--1 1236 1237 1238 J.239 1240 1241 1242 1243 1244 1245 /* * * We now add an entry to the allocation table for this updated key table entry. */ if (outbound I I (!inbound && !outbound» { len = key_createkey«char *)&buf, secassoc->type, secassoc->src, secassoc->dst, 0, 1); indx = key_gethashval«char *)&buf, len, KEYALLOCTBLSIZE); DPRINTF(IDL_FINISHED, ("keyupdate: keyalloc hash position=%d\n", indx}); np->keynode = keynode; np->next = keyalloctbl[indx] . next; keyalloctbl[indx] .next = np; } 1:246 1247 key_deleteacquire (secassoc->type, 1249 CRITICAL_END; return (0) ; 1250 (SOCKADDR *) &(secassoc->dst) ) ; 12:")1 } 1252 1253 /*---------------------------------------------------------------------1254 * key_register(): 1255 * Register a socket as one capable of acquiring security associations 1256 * for the kernel. 1257 ----------------------------------------------------------------------*/ 1258 int key_register DEFARGS «socket, type), struct socket *socket AND 1259 u_int type) 1260 1262 1263 1264 1265 1266 1267 struct key_registry *p, *new; CRITICAL DCL CRITICAL_START; l268 DPRINTF(IDL_EVENT, ("Entering key_register w/so=Ox%x,type=%d\n", (unsigned int)socket,type»; 1269 1270 if (! (keyregtable && socket» 1272 1273 /* 1274 * Make sure entry is not already in table 1275 */ for(p = keyregtable->next; p; p = p->next) { if «p->type == type) && (p->socket == socket» CRITICAL_END; return(EEXIST); 1276 1277 1278 1279 } l280 1281 1282 } KMALLOC(new, struct key_registry *, sizeof(struct key_registry»; (new == 0) { CRITICAL_END; return(ENOBUFS); 12H3 1284 if 1285 J..286 } 1287 1288 1289 new->type = type; new- >socket = socket; new->next = keyregtable->next; keyregtable->next = new; CRITICAL_END; return(O); 1290 1:291 L29;~ 1;~ 93 1'::-:,94 { } 1296 /*---------------------------------------------------------------------- 1297 1298 1299 1:,00 * key_unregister(): Delete entries from the registry list. * allflag = 1 : delete all entries with matching socket * * allflag = 0 : delete only the entry matching socket and type 1301 ----------------------------------------------------------------------*/ 1302 void key_unregister DEFARGS( (socket, type, allflag), 1303 struct socket *socket AND 130-1 u_int type AND 1305 int allflag) 1306 { 1307 1308 309 struct key_registry *p, *prev; CRITICAL DCL 1:510 CRITICAL_START; 1311 1312 1313 1314 DPRINTF (IDL_EVENT, ("Entering key_unregister w/so=Ox%x, type=%d, flag=%d\n", (unsigned int) socket, type, allflag»; 1315 if 1316 len 7 1318 1319 1.320 1321 1322 1.323 (I (keyregtable && socket» panic ("key_register"); prev = keyregtable; for(p = keyregtable->next; p; p = p->next) { if «allflag && (p->socket == socket» II «p->type == type) && (p->socket == socket») { prev->next = p->next; KFREE (p); p = prev; prey 1325 = p; 1326 } 1327 CRITICAL_END; 1328 } 1329 1330 1331 l332 /*---------------------------------------------------------------------- 1335 * key_acquire(): Send a key_acquire message to all registered key mgnt daemons * capable of acquire security association of type type. * * 1336 * 1337 * 1338 ----------------------------------------------------------------------*/ 1333 :L334 Return: 0 if succesfully called key mgnt. daemon(s) -1 if not successfull. 1.339 int key_acquire DEFARGS «type, src, dst) , 1340 u_int type AND 1341 SOCKADDR *src AND SOCKADDR *dst) 1342 13,,*3 { 1344 1345 1346 13·J.7 1351 struct key_registry *p; struct key_acquirelist *ap, *prevap; int success = 0, created = 0; u_int etype; struct key_msghdr *km = NULL; int len; DPRINTF(IDL_EVENT, ("Entering key_acquire()\n"»; 1.352 II if (!keyregtable return (-1); 12 Sf) /* * We first check the acquirelist to see if a key_acquire * message has been sent for this destination. */ 13~) 3 13:>9 1360 1361 1362 1363 1364 1365 1366 .1367 1368 1369 1370 1371 1.372 1373 1374. 1375 1376 ! src II 1353 1354 13SS !dst) etype = type; prevap = key_acquirelist; for(ap = key_acquirelist->next; ap; ap = ap->next) { if (addrpart_equal(dst, ap->target) && (etype == ap->type» { DPRINTF <rDL_EVENT, ("acquire message previously sent! \n"»; if (ap->expiretime < TIME_SECONDS) { DPRINTF(IDL_EVENT, ("acquire message has expired!\n"»; ap->count = 0; break; } if (ap->count < maxkeyacquire) { DPRINTF(IDL_EVENT, ("max acquire messages not yet exceeded!\n"»; break; } return(O); } else if (ap->expiretime < TIME_SECONDS) { 1378 * 1379 * 1380 * * * 1381 1382 Since we're already looking at the list, we may as well delete expired entries as we scan through the list. This should really be done by a function like key_reaper() but until we code key_reaper(), this is a quick and dirty hack. */ 13<33 1384 DPRINTF(IDL_EVENT,("found an expired entry ... deleting it!\n"»; prevap->next = ap->next; KFREE (ap) ; ap = prevap; 1385 l386 13<37 1388 } 1389 1390 prevap = ap; } 1391 1.392 /* 1393 1-394. 1395 1397 1398 * Scan registry and send KEY_ACQUIRE message to * appropriate key management daemons. */ for(p = keyregtable->next; p; p if (p->type != type) continue; = p->next) { 1399 1400 1401 1402 1403 :L404 1··106 JAC7 .1.408 1409 1-110 1411 1412 1413 1-114 1415 if (! created) { len = sizeof(struct key_msghdr) + ROUNDUP(src->sa_len) ROUNDUP(dst->sa_len); KMALLOC(km, struct key_msghdr *, len); i f (! km) { DPRINTF(IDL_ERROR, (IIkey_acquire: no memory\n"»; return (-1) ; } DPRINTF (IDL_FINISHED, (IIkey_acquire/created: 1 \n"»; bzero ( (char *) km, len); km->key_msglen = len; km->key_msgvers = KEY_VERSION; km->key_msgtype = KEY_ACQUIRE; km->type = type; DPRINTF (IDL_FINISHED, (IIkey_acquire/created: 2\n"»; + /* 1416 * This is inefficient and slow. 1417 */ 141.~3 14.19 1420 '.1421 1422 iA23 1424 1425 1426 1427 1428 1429 /* * We zero out sin zero here for AF INET addresses because * ip_output() currently does not do it for performance reasons. */ if (src->sa_family == AF_INET) bzero«char *) «(struct sockaddr_in *)src)->sin_zero), sizeof«(struct sockaddr_in *)src)->sin_zero»; if (dst->sa_family == AF_INET) bzero«char *) «(struct sockaddr_in *)dst)->sin_zero), sizeof«(struct sockaddr in *)dst)->sin_zero»; bcopy«char *)dst, (char *) «int) (km + 1) + ROUNDUP(src->sa_Ien», dst->sa_Ien) ; DPRINTF(IDL_FINISHED, ("key_acquire/created: 3\n"»; created++; 1431 1432 1433 H34 1435 1436 1437 1438 1439 1440 14-41 1442 1443 1444 1445 1446 1447 } if (key_sendup(p->socket, km» success++; } if (km) KFREE (km) ; /* * Update the acquirelist */ if (success) { i f (lap) { DPRINTF(IDL_EVENT, ("Adding new entry in acquirelist\n"»; KMALLOC(ap, struct key_acquirelist *, sizeof(struct key_acquirelist»; i f (ap == 0) return(success? 0 : -1); bzero«char *)ap, sizeof(struct key_acquirelist»; bcopy«char *)dst, (char *)ap->target, dst->sa_Ien); ap->type = etype; ap->next = key_acquirelist->next; key_acquirelist->next = apt } DPRINTF(IDL_GROSS_EVENT, ("Updating acquire counter and expiration time\n"»; ap->count++; ap->expiretime = TIME SECONDS + maxacquiretime; JA·'U3 1449 1450 14~~1 1452 1453 1454 1455 1456 1457 1458 1459 1460 146l } DPRINTF(IDL_EVENT, ("key_acquire: done! success=%d\n",success»; 1462 return(success? 0 : -1); 1-163 1464 } 1465 1466 /*---------------------------------------------------------------------1467 * key_alloc(): 1468 * 1469 1;171 * * * 1472 * J..470 Allocate a security association to a socket. A socket requesting unique keying (per-socket keying) is assigned a security assocation exclusively for its use. Sockets not requiring unique keying are assigned the first security association which mayor may not be used by another socket. 1473 ----------------------------------------------------------------------*/ 1474 int key_alloc DEFARGS«type, src, dst, socket, unique_key, keynodep), 1475 1476 1477 1478 1479 u_int type AND SOCKADDR *src AND SOCKADDR * ds t AND struct socket *socket AND u_int unique_key AND struct key_tblnode **keynodep) 1480 1481 { 1482 struct key_tblnode *keynode; 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 struct key_alloenode *np, *prevnp; struct key_so2spinode *newnp; int len; int indx; DPRINTF(IDL_FINISHED, ("Entering key_alloe w/type=%u!\n",type»; (! (sre && dst» { DPRINTF(IDL_ERROR, ("key_alloe: received null sre or dst!\n"»; return (-1) ; } if 1494 1495 /* 1496 * Search key allocation table 1497 1498 1499 1500 */ 1 bzero«char *)&buf, sizeof(buf»; len = key_ereatekey«char *)&buf, type, sre, dst, 0, 1); indx = key_gethashval«char *)&buf, len, KEYALLOCTBLSIZE); ~)Ol 1502 #define np_type np->keynode->seeassoe->type 1.503 #define np_state np->keynode->seeassoe->state 1504 #define np_src np->keynode->seeassoe->sre 1505 #define np_dst np->keynode->seeassoe->dst 1506 prevnp = &keyalloetbl[indx]; 1507 1.508 E09 1.51..0 1511 1512 1513 1514 1.515 1516 for (np = keyalloetbl[indx].next; np; np = np->next) { if «type == np_type) && addrpart_equal(sre, np_sre) && addrpart_equal(dst, np_dst) && ! (np_state & (K_LARVAL I K DEAD if (! (unique_key) ) break; if (! (np_state & K_USED» break; } prevnp 1.517 1518 1519 1520 1521 1:,22 152-1 np; } if (np) { struct socket list *newsp; CRITICAL DCL CRITICAL_START; 1525 1526 1527 1528 1529 1530 1531 1532 1533 J.534 1535 DPRINTF (IDL_EVENT, ("key_alloe: found node to alloeate\n"»; keynode = np->keynode; KMALLOC(newnp, struct key_so2spinode *, sizeof(struct key_so2spinode»i if (newnp == 0) { DPRINTF(IDL_ERROR, ("key_alloe: Can't alloe mem for so2spi node!\n"»; CRITICAL_END; return(ENOBUFS); } struct soeketlist *, sizeof(struct soeketlist»; 153'7 1538 1539 1540 1541 1542 1543 154-4: DPRINTF(IDL_ERROR, (IIkey_alloc: Can't alloc mem for socketlist!\n"»; if (newnp) KFREE (newnp) ; CRITICAL_END; return(ENOBUFS); } /* * Add a hash entry into the s02spi table to * map socket to allocated secassoc. 1545 15-16 1547 1548 1549 1550 1551 1553 1554 :~. 5 55 */ DPRINTF(IDL_FINISHED, (IIkey_alloc: adding entry to S02spi table ... II»; newnp->keynode = keynode; newnp->socket = socket; newnp->next = s02spitbl[«u_int32) socket) % S02SPITBLSIZE] . next; s02spitbl[«u_int32)socket) % S02SPITBLSIZE] . next = newnp; DPRINTF (IDL_FINISHED, (lldone\n ll » ; if (unique_key) * Need to remove the allocation entry * since the secas soc is now unique and * can't be allocated to any other socket .1.559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 { /* 1556 1557 1558 */ DPRINTF (IDL_EVENT, (Ilkey_alloc: making keynode unique ... II» keynode->secassoc->state 1= K_UNIQUE; prevnp->next = np->next; KFREE (np); DPRINTF (IDL_EVENT, (lldone\n ll » ; ; } keynode->secassoc->state keynode->secassoc->state keynode->alloc_count++; 1= 1= K_USED; K_OUTBOUND; /* * Add socket to list of socket using secassoc. */ DPRINTF(IDL_FINISHED, ("key_alloc: adding so to solist ... 11»; newsp->socket = socket; newsp->next = keynode->solist->next; keynode->solist->next = newsp; DPRINTF (IDL_FINISHED, ("done\n"» ; *keynodep = keynode; CRITICAL_END; return (0) ; 1579 1580 1581 } 1582 1583 *keynodep = NULL; return (0); 1584 1585 } 1586 1587 1588 /*---------------------------------------------------------------------- * * 1590 1591 Decrement the refcount for a key table entry. If the entry is marked dead, and the refcount is zero, we go ahead and delete it. IS92 ----------------------------------------------------------------------*/ 1593 void key_free DEFARGS«keynode), struct key_tblnode *keynode) J.594 1~)95 { DPRINTF (IDL_GROSS_EVENT, ("Entering key_free w/keynode=Ox%x\n", (unsigned int)keynode»; if (!keynode) { DPRINTF(IDL_ERROR, ("Warning: key_free got null pointer\n"»; return; } (keynode->ref_count)--; if (keynode->ref_count < 0) { DPRINTF(IDL_ERROR, ("Warning: key_free decremented refcount to %d\n",keynode->ref_count»; } if «keynode->secassoc->state & K_DEAD) && (keynode->ref_count <= 0» DPRINTF(IDL_GROSS_EVENT, ("key_free: calling key_delete\n"»; key_delete(keynode->secassoc); } 1596 159'7 l598 1600 1601 2.602 1603 J..604 160'? 1608 1609 { 1610 } 1.6.1.1 1612 /*---------------------------------------------------------------------- 1613 1614 16.1..5 J.616 1617 1618 1619 1620 * getassocbyspi(): Get a security association for a given type, src, dst, and spi. * * Returns: 0 if sucessfull * -1 if error/not found * * * * Caller must convert spi to host order. in host order! Function assumes spi is 1621 ----------------------------------------------------------------------*/ 1622 int getassocbyspi DEFARGS ( (type, src, dst, spi, keyentry), 1623 u_int type AND 1624 SOCKADDR *src AND 1625 SOCKADDR *dst AND 1.626 u_int32 spi AND 1627 struct key_tblnode **keyentry) 1628 { char buf[MAXHASHKEYLEN); 1629 int len, indx; J.6.3C struct key_tblnode *keynode, *prevkeynode = 0; 1631 1632 1633 DPRINTF(IDL_FINISHED, ("Entering getassocbyspi w/type=%u spi=%u\n",type,spi»; 1634 1635 1636 1637 1638 1639 1640 *keyentry = NULL; bzero(&buf, sizeof(buf»; len = key_createkey«char *)&buf, type, src, dst, spi, 0); indx = key_gethashval«char *)&buf, len, KEYTBLSIZE); DPRINTF (IDL_FINISHED, ("getassocbyspi: indx=%d\n", indx» ; DDO(IDL_FINISHED,dump_sockaddr(src);dump_sockaddr(dst)); DPRINTF(IDL_FINISHED, (llgetassocbyspi: keysearch ret=Ox%x\n", 1642 (unsigned int)keynode»; 1643 1644 if (keynode && ! (keynode->secassoc->state & (K_DEAD 1 K_LARVAL») { DPRINTF(IDL_GROSS_EVENT, (llgetassocbyspi: found secassoc!\n"»; 164-5 (keynode->ref_count)++; 1646 1647 keynode->secassoc->state 1= K_USED; 1648 *keyentry = keynode; } else { 1649 DPRINTF(IDL_EVENT, (llgetassocbyspi: secassoc not found!\n"»; 1650 return (-1); 1651 1652 } return(O); 1653 1654 } 1655 1656 1657 /*---------------------------------------------------------------------1658 * getassocbysocket(): Get a security association for a given type, src, dst, and socket. 1659 * 1660 If not found, try to allocate one. * Returns: 0 if successfull 1661 * -1 if error condition/secassoc not found (*keyentry = NULL) 1662 * 1663 * 1 if secas soc temporarily unavailable (*keynetry = NULL) 1664 * (e.g., key mgnt. daemon(s) called) 1665 ----------------------------------------------------------------------*/ 1666 int getassocbysocket DEFARGS«type, src, dst, socket, unique_key, keyentry), 1667 u_int type AND 166H 1.67 SOCKADDR *src AND SOCKADDR *dst AND struct socket *socket AND u_int unique_key AND struct key_tblnode **keyentry) 1671 1672 1673 { struct key_tblnode *keynode = 0; 1674 1675 struct key_so2spinode *np; u_int real type; 1676 1677 DPRINTF(IDL_FINISHED, ("Entering getassocbysocket w/type=%u so=Ox%x\n", 1678 type, (unsigned int) socket»; 1679 1680 1681 /* 16'32 * We treat esp-transport mode and esp-tunnel mode 1683 * as a single type in the keytable. This has a side 1634 * effect that socket using both esp-transport and 1685 * esp-tunnel will use the same security association 1686 * for both modes. Is this a problem? 1687 */ 1688 real type = type; if «np = key_sosearch(type, src, dst, socket») { 1689 if (np->keynode && np->keynode->secassoc && 1690 1691 ! (np->keynode->secassoc->state & (K_DEAD 1 K_LARVAL») { l692 DPRINTF (IDL_FINISHED, ("getassocbysocket: found secassoc! \n") ) ; (np->keynode->ref_count)++; 1693 return(O); 1695 } 1696 1697 1698 1699 } /* * No secas soc has been allocated to sockett * so allocate one t if available 17()O 1701 1702 1703 1704 */ DPRINTF(IDL_GROSS_EVENT, (llgetassocbyso: can't find itt trying to allocate!\n"»; if (key_alloc(realtype, src, dst, socket, unique_key, &keynode) == 0) { i f ( keynode) { DPRINTF(IDL_GROSS_EVENT, (llgetassocbyso: key_alloc found secassoc!\n"»; keynode->ref_count++; *keyentry = keynode; return(O); } else { 1705 1706 1707 1.708 .l7(j::; 1710 /* J.711 * Kick key mgnt. daemon(s) * (this should be done in ipsec_output-policy() instead or * selectively called based on a flag value) 1712 1713 1714 1715 1716 1717 1718 , 719 */ DPRINTF(IDL_FINISHED, (llgetassocbyso: calling key mgnt daemons!\n"»; *keyentry = NULL; if (key_acquire(realtype, src, dst) == 0) return (1); else return (-1) ; } } NULL; *keyentry return (-1) ; 1720 17~~J_ 1722 1723 1724 1725 1726 } 1727 1728 1729 1.730 1731 /*---------------- --------- ------------------------------------------* key_xdata(): * Parse message buffer for src/dst/from/iv/key if parseflag * else parse for src/dst only. = 0 ------------------------------------------*/ 1732 --------------------------}733 int key_xdata DEFARGS «km, kip, parseflag), J.734 struct key_msghdr *km AND 1735 struct key_msgdata *kip AND 1736 int parseflag) 1737 { char *cp, *cpmax; 1738 1739 1'740 if (!km II (km->key_msglen <= 0» 1741 return (-1); 1742 1743 1744 cp = (caddr_t) (km + 1); cpmax (caddr_t)km + km->key_msglen; 1745 1746 /* * correct word alignment. 1748 1749 1750 1751 */ /* 1752 * Need to clean up this code later. 1753 */ 1754 1755 1756 17'57 1758 1759 1760 1761 1762 /* Grab src addr */ kip->src = (SOCKADDR *) cp; if (lkip->src->sa_len) { DPRINTF(IDL_MAJOR_EVENT, (IIkey_xdata couldn't parse src addr\nll)); return (-1) ; } ADVANCE (cp, kip->src->sa_len); 1763 1764 1765 1766 1767 1768 1769 1770 1 Til :77? 1773 :'774 1776 1777 17713 1779 1'780 1'78J 1782 J783 /* Grab dest addr */ kip->dst = (SOCKADDR *)cp; i f (lkip->dst->sa_len) { DPRINTF(IDL_MAJOR_EVENT, (IIkey_xdata couldn't parse dest addr\nll)); return (-1) ; } ADVANCE (cp, kip->dst->sa_len); if (parseflag == 1) { kip->from = 0; kip->key = kip->iv = 0; kip->keylen = kip->ivlen 0; return (0) ; } /* Grab from addr */ kip->from = (SOCKADDR *)cp; if (lkip->from->sa_len) { DPRINTF(IDL_MAJOR_EVENT, (IIkey_xdata couldn't parse from addr\n")); return (-1) ; } 1785 1786 ADVANCE (cp, kip->from->sa_len); 17 8 7 1788 1789 1790 1791 1792 1793 1794 1795 1796 }797 ]798 1799 /* Grab key */ if «kip->keylen = km->keylen)) { kip->key = cp; ADVANCE (cp, km->keylen); } else kip- >key = 0; /* Grab iv */ if «kip - >i vlen kip->iv cp; else 0; kip->iv km->ivlen) ) 1802- return (0); 1802 } 1803 1804 1805 1806 1807 1803 1809 1810 1811 int key-parse DEFARGS ((kmp, so, dstfamily), struct key_msghdr **kmp AND struct socket *so AND int *dstfamily) { int error = 0, keyerror = 0; struct key_msgdata keyinfo; struct key_secassoc *secassoc NULL; struct key_msghdr *km = *kmp; 1813 1814 1.815 DPRINTF(IDL_MAJOR_EVENT, ("Entering key-parse\n"»; J.316 1817 #define senderr(e) \ 1818 {error = (e); goto flush; } 1819 if (km->key_msgvers != KEY_VERSION) { 1820 DPRINTF(IDL_CRITICAL, (likeyoutput: unsupported key message version!\n"»; 1821 senderr(EPROTONOSUPPORT); 1822 :1.. 823 } 1824 182~) km->key-p id 1826 In;n DDO(IDL_MAJOR_EVENT, printf(IIkeymsghdr:\nll); dump_keymsghdr(km»; 1828 Ig29 1830 183.1 1* * Parse buffer for src addr, dest addr, from addr, key, iv */ 1832 bzero((char *)&keyinfo, sizeof(keyinfo»; 1G3~; switch (km->key_msgtype) { case KEY ADD: DPRINTF(IDL_MAJOR_EVENT, ("key_output got KEY ADD msg\n"»; 1836 1(337 1839 1840 if (key_xdata(km, &keyinfo, 0) < 0) goto parsefail; 1841 1842 1843 1844 /* 1845 KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc»; if (secassoc == 0) { DPRINTF (IDL_CRITICAL, (likeyoutput: No more memory! \nll» ; senderr(ENOBUFS); 1..846 1847 1848 * Allocate the secas soc structure to insert * into key table here. */ 1849 1850 } 1851 1852 if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) { DPRINTF(IDL_CRITICAL, (likeyoutput: key_msghdr2secassoc failed!\n ll »; KFREE 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1866 1867 1868 1869 1870 1B71 IH72 1874 1B75 11376 1877 IB79 :L8BO 18B1 1882 1883 .lgg.q. 1885 18B6 1887 lf388 11389 1890 1891 1892 1893 1894 1895 18% 1897 1898 1899 1900 1901 1902 1903 1904 1905 senderr(EINVAL); } DPRINTF(IDL_MAJOR_EVENT, (nsecassoc to add:\nn»; DDO(IDL_MAJOR_EVENT,dump_secassoc(secassoc»; if «keyerror = key_add(secassoc» != 0) { DPRINTF(IDL_CRITICAL, (nkeyoutput: key_add failed\nn»; if (secassoc->key) KFREE(secassoc->key); if (secassoc->iv) KFREE(secassoc->iv); KFREE(secassoc); if (keyerror == -2) { senderr(EEXIST); } else { senderr(ENOBUFS); } } break; case KEY DELETE: DPRINTF(IDL_MAJOR_EVENT, (nkey_output got KEY DELETE msg\nn»; if (key_xdata(km, &keyinfo, 1) < 0) goto parsefail; KMALLOC(secassoc, struct key_secassoc *, if (secassoc == 0) { senderr(ENOBUFS); sizeof(struct key_secassoc»; } if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) { KFREE(secassoc); senderr(EINVAL); } if (key_delete (secassoc) if (secassoc->iv) KFREE(secassoc->iv); if (secassoc->key) KFREE(secassoc->key); KFREE(secassoc); senderr (ESRCH) ; != 0) { } if (secassoc->iv) KFREE(secassoc->iv); if (secassoc->key) KFREE(secassoc->key); KFREE(secassoc); break; case KEY UPDATE: DPRINTF(IDL_EVENT, ("key_output got KEY_UPDATE msg\n"»; if (key_xdata(km, &keyinfo, 0) < 0) goto parsefail; 1907 J.908 1909 KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc»; if (secassoc == 0) { senderr(ENOBUFS); 19~LO } 1911 if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) { KFREE(secassoc); senderr(EINVAL); :1.912 1913 191"! 1915 1916 191 7 1918 1919 1921 1922 1923 1924 1925 1926 1927 1928 .L 9~19 1930 1931 1933 1935 19.36 1937 1938 1939 1940 19·±1 1942 1943 1944 1945 194.6 1947 1948 1949 1950 1951 1952 1954 1955 l.95G 1957 1958 } if «keyerror = key_update(secassoc» 1= 0) { DPRINTF(IDL_CRITICAL, ("Error updating key entry\n"»; if (secassoc->iv) KFREE(secassoc->iv); if (secassoc->key) KFREE(secassoc->key); KFREE(secassoc); senderr(keyerror); } KFREE(secassoc); break; case KEY GET: DPRINTF(IDL_EVENT, ("key_output got KEY GET msg\n"»; if (key_xdata(km, &keyinfo, 1) < 0) goto parsefail; if (key_get (km->type, (SOCKADDR *)keyinfo.src, (SOCKADDR *)keyinfo.dst, km->spi, &secassoc) 1= 0) { DPRINTF(IDL_EVENT, ("keyoutput: can't get key\n"»; senderr (ESRCH) ; } if (secassoc) { int newlen; DPRINTF(IDL_EVENT, ("keyoutput: Found secassoc1\n"»; newlen = sizeof(struct key_msghdr) + ROUNDUP(secassoc->src->sa_len) + ROUNDUP (secassoc->dst->sa_len) + ROUNDUP(secassoc->from->sa_len) + ROUNDUP(secassoc->keylen) + ROUNDUP(secassoc->ivlen); DPRINTF(IDL_EVENT, ("keyoutput: newlen=%d\n", newlen»; if (newlen > km->key_msglen) { struct key_msghdr *newkm; DPRINTF(IDL_EVENT, ("keyoutput: Allocating new buffer!\n"»; KMALLOC(newkm, struct key_msghdr *, newlen); if (newkm == 0) { senderr(ENOBUFS); } bcopy«char *)km, (char *)newkm, km->key_msglen); DPRINTF (IDL_FINISHED, ("keyoutput: 1 \n"» ; KFREE(km) ; = newkm; 1960 l%1 km->key_msglen, newlen»; km->key_msglen = newlen; } 1962 1963 1964 1965 1%6 1967 DPRINTF (IDL_FINISHED, ("keyoutput: 2\n"»; if (key_secassoc2msghdr(secassoc, km, &keyinfo» { DPRINTF (IDL_CRITICAL, ("keyoutput: Can't create msghdr! \n"»; senderr(EINVAL); } DPRINTF(IDL_FINISHED, ("keyoutput: 3\n ll »; D68 1069 1970 1971 1972 1973 1974 1975 } break; case KEY_GETSPI: DPRINTF(IDL_EVENT, (lIkey_output got KEY_GETSPI msg\n"»; if (key_xdata(km, &keyinfo, 1) < 0) gata parsefail; J.976 if «keyerror = key_getspi(km->type, keyinfo.src, keyinfo.dst, km->lifetime1, km->lifetime2, &(km->spi») != 0) { DPRINTF(IDL_CRITICAL, ("keyoutput: getspi failed error=%d\n", keyerror»; senderr(keyerror); 19'77 19'78 1979 191:)0 1981 1982 } 1998 1999 2000 break; case KEY REGISTER: DPRINTF(IDL_EVENT, (lIkey_output got KEY REGISTER msg\n"»; key_register (so, km->type); break; case KEY_DUMP: DPRINTF (IDL_EVENT, (lIkey_output got KEY DUMP msg\n"»; error = key_dump (so); return(error); break; case KEY FLUSH: DPRINTF(IDL_EVENT, (lIkey_output got KEY FLUSH msg\n"»; key_flush () ; break; default: DPRINTF(IDL_CRITICAL, (lIkey_output got unsupported msg type=%d\n", km->key_msgtype»; senderr(EOPNOTSUPP); 2001 } 198:?, 198,1 1985 1986 1987 1988 1989 1090 IS9} 1992 1993 1994 1995 1996 1997 2002 2003 gata flush; 200·1 2C05 parsefail: 2006 keyinfo.dst = NULL; 2007 error = EINVAL; 2008 2009 flush: 2010 i f (km) 2011 km->key_errno error; if 2013 2014 2015 2016 2017 2018 (dstfamily) *dstfamily = keyinfo.dst ? keyinfo.dst->sa_family : 0; DPRINTF(IDL_MAJOR_EVENT, return error; } (lIkeyyarse exiting with error=%d\n", error»;

Disclaimer: Justia Dockets & Filings provides public litigation records from the federal appellate and district courts. These filings and docket sheets should not be considered findings of fact or liability, nor do they necessarily reflect the view of Justia.


Why Is My Information Online?