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)
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
#else /* linux */
#include
#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
#else /* linux */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
1.:)4
#define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in6))
.1 S
#ifdef INET6
#include
#include
#endif /* INET6 */
#include
~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 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?