1 /* $OpenBSD: pfkeyv2_convert.c,v 1.18 2003/12/02 23:16:29 markus Exp $ */
2 /*
3 * The author of this code is Angelos D. Keromytis (angelos@keromytis.org)
4 *
5 * Part of this code is based on code written by Craig Metz (cmetz@inner.net)
6 * for NRL. Those licenses follow this one.
7 *
8 * Copyright (c) 2001 Angelos D. Keromytis.
9 *
10 * Permission to use, copy, and modify this software with or without fee
11 * is hereby granted, provided that this entire notice is included in
12 * all copies of any software which is or includes a copy or
13 * modification of this software.
14 * You may use this code under the GNU public license if you so wish. Please
15 * contribute changes back to the authors under this freer than GPL license
16 * so that we may further the use of strong encryption without limitations to
17 * all.
18 *
19 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
20 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
21 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
22 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
23 * PURPOSE.
24 */
25
26 /*
27 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
28 *
29 * NRL grants permission for redistribution and use in source and binary
30 * forms, with or without modification, of the software and documentation
31 * created at NRL provided that the following conditions are met:
32 *
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgements:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * This product includes software developed at the Information
43 * Technology Division, US Naval Research Laboratory.
44 * 4. Neither the name of the NRL nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
49 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
51 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 *
60 * The views and conclusions contained in the software and documentation
61 * are those of the authors and should not be interpreted as representing
62 * official policies, either expressed or implied, of the US Naval
63 * Research Laboratory (NRL).
64 */
65
66 /*
67 * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
68 *
69 * Redistribution and use in source and binary forms, with or without
70 * modification, are permitted provided that the following conditions
71 * are met:
72 * 1. Redistributions of source code must retain the above copyright
73 * notice, this list of conditions and the following disclaimer.
74 * 2. Redistributions in binary form must reproduce the above copyright
75 * notice, this list of conditions and the following disclaimer in the
76 * documentation and/or other materials provided with the distribution.
77 * 3. Neither the name of the author nor the names of any contributors
78 * may be used to endorse or promote products derived from this software
79 * without specific prior written permission.
80 *
81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * SUCH DAMAGE.
92 */
93
94 #include <sys/types.h>
95 #include <sys/param.h>
96 #include <sys/systm.h>
97 #include <sys/mbuf.h>
98 #include <sys/kernel.h>
99 #include <sys/socket.h>
100 #include <net/route.h>
101 #include <netinet/ip_ipsp.h>
102 #include <net/pfkeyv2.h>
103 #include <crypto/cryptodev.h>
104 #include <crypto/xform.h>
105
106 /*
107 * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
108 * of the TDB will be initialized by other import routines, and tdb_init().
109 */
110 void
import_sa(struct tdb * tdb,struct sadb_sa * sadb_sa,struct ipsecinit * ii)111 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
112 {
113 if (!sadb_sa)
114 return;
115
116 if (ii) {
117 ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
118 ii->ii_authalg = sadb_sa->sadb_sa_auth;
119 ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
120
121 tdb->tdb_spi = sadb_sa->sadb_sa_spi;
122 tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
123
124 if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
125 tdb->tdb_flags |= TDBF_PFS;
126
127 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV)
128 tdb->tdb_flags |= TDBF_HALFIV;
129
130 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
131 tdb->tdb_flags |= TDBF_TUNNELING;
132
133 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING)
134 tdb->tdb_flags |= TDBF_RANDOMPADDING;
135
136 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY)
137 tdb->tdb_flags |= TDBF_NOREPLAY;
138
139 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
140 tdb->tdb_flags |= TDBF_UDPENCAP;
141 }
142
143 if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
144 tdb->tdb_flags |= TDBF_INVALID;
145 }
146
147 /*
148 * Export some of the information on a TDB.
149 */
150 void
export_sa(void ** p,struct tdb * tdb)151 export_sa(void **p, struct tdb *tdb)
152 {
153 struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
154
155 sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
156
157 sadb_sa->sadb_sa_spi = tdb->tdb_spi;
158 sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
159
160 if (tdb->tdb_flags & TDBF_INVALID)
161 sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
162
163 if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
164 tdb->tdb_compalgxform != NULL) {
165 switch (tdb->tdb_compalgxform->type) {
166 case CRYPTO_DEFLATE_COMP:
167 sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
168 break;
169 case CRYPTO_LZS_COMP:
170 sadb_sa->sadb_sa_encrypt = SADB_X_CALG_LZS;
171 break;
172 }
173 }
174
175 if (tdb->tdb_authalgxform) {
176 switch (tdb->tdb_authalgxform->type) {
177 case CRYPTO_MD5_HMAC:
178 sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
179 break;
180
181 case CRYPTO_SHA1_HMAC:
182 sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
183 break;
184
185 case CRYPTO_RIPEMD160_HMAC:
186 sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
187 break;
188
189 case CRYPTO_SHA2_256_HMAC:
190 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
191 break;
192
193 case CRYPTO_SHA2_384_HMAC:
194 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
195 break;
196
197 case CRYPTO_SHA2_512_HMAC:
198 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
199 break;
200
201 case CRYPTO_MD5_KPDK:
202 sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5;
203 break;
204
205 case CRYPTO_SHA1_KPDK:
206 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1;
207 break;
208 }
209 }
210
211 if (tdb->tdb_encalgxform) {
212 switch (tdb->tdb_encalgxform->type) {
213 case CRYPTO_DES_CBC:
214 sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC;
215 break;
216
217 case CRYPTO_3DES_CBC:
218 sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
219 break;
220
221 case CRYPTO_AES_CBC:
222 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
223 break;
224
225 case CRYPTO_CAST_CBC:
226 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
227 break;
228
229 case CRYPTO_BLF_CBC:
230 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
231 break;
232
233 case CRYPTO_SKIPJACK_CBC:
234 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK;
235 break;
236 }
237 }
238
239 if (tdb->tdb_flags & TDBF_PFS)
240 sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
241
242 /* Only relevant for the "old" IPsec transforms. */
243 if (tdb->tdb_flags & TDBF_HALFIV)
244 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
245
246 if (tdb->tdb_flags & TDBF_TUNNELING)
247 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
248
249 if (tdb->tdb_flags & TDBF_RANDOMPADDING)
250 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING;
251
252 if (tdb->tdb_flags & TDBF_NOREPLAY)
253 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
254
255 *p += sizeof(struct sadb_sa);
256 }
257
258 /*
259 * Initialize expirations and counters based on lifetime payload.
260 */
261 void
import_lifetime(struct tdb * tdb,struct sadb_lifetime * sadb_lifetime,int type)262 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
263 {
264 struct timeval tv;
265 int s;
266
267 if (!sadb_lifetime)
268 return;
269
270 s = splhigh();
271 tv = time;
272 splx(s);
273
274 switch (type) {
275 case PFKEYV2_LIFETIME_HARD:
276 if ((tdb->tdb_exp_allocations =
277 sadb_lifetime->sadb_lifetime_allocations) != 0)
278 tdb->tdb_flags |= TDBF_ALLOCATIONS;
279 else
280 tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
281
282 if ((tdb->tdb_exp_bytes =
283 sadb_lifetime->sadb_lifetime_bytes) != 0)
284 tdb->tdb_flags |= TDBF_BYTES;
285 else
286 tdb->tdb_flags &= ~TDBF_BYTES;
287
288 if ((tdb->tdb_exp_timeout =
289 sadb_lifetime->sadb_lifetime_addtime) != 0) {
290 tdb->tdb_flags |= TDBF_TIMER;
291 if (tv.tv_sec + tdb->tdb_exp_timeout < tv.tv_sec)
292 tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
293 else
294 tv.tv_sec += tdb->tdb_exp_timeout;
295 timeout_add(&tdb->tdb_timer_tmo, hzto(&tv));
296 } else
297 tdb->tdb_flags &= ~TDBF_TIMER;
298
299 if ((tdb->tdb_exp_first_use =
300 sadb_lifetime->sadb_lifetime_usetime) != 0)
301 tdb->tdb_flags |= TDBF_FIRSTUSE;
302 else
303 tdb->tdb_flags &= ~TDBF_FIRSTUSE;
304 break;
305
306 case PFKEYV2_LIFETIME_SOFT:
307 if ((tdb->tdb_soft_allocations =
308 sadb_lifetime->sadb_lifetime_allocations) != 0)
309 tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
310 else
311 tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
312
313 if ((tdb->tdb_soft_bytes =
314 sadb_lifetime->sadb_lifetime_bytes) != 0)
315 tdb->tdb_flags |= TDBF_SOFT_BYTES;
316 else
317 tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
318
319 if ((tdb->tdb_soft_timeout =
320 sadb_lifetime->sadb_lifetime_addtime) != 0) {
321 tdb->tdb_flags |= TDBF_SOFT_TIMER;
322 if (tv.tv_sec + tdb->tdb_soft_timeout < tv.tv_sec)
323 tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
324 else
325 tv.tv_sec += tdb->tdb_soft_timeout;
326 timeout_add(&tdb->tdb_stimer_tmo, hzto(&tv));
327 } else
328 tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
329
330 if ((tdb->tdb_soft_first_use =
331 sadb_lifetime->sadb_lifetime_usetime) != 0)
332 tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
333 else
334 tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
335 break;
336
337 case PFKEYV2_LIFETIME_CURRENT: /* Nothing fancy here. */
338 tdb->tdb_cur_allocations =
339 sadb_lifetime->sadb_lifetime_allocations;
340 tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
341 tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
342 tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
343 }
344 }
345
346 /*
347 * Export TDB expiration information.
348 */
349 void
export_lifetime(void ** p,struct tdb * tdb,int type)350 export_lifetime(void **p, struct tdb *tdb, int type)
351 {
352 struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
353
354 sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
355 sizeof(uint64_t);
356
357 switch (type) {
358 case PFKEYV2_LIFETIME_HARD:
359 if (tdb->tdb_flags & TDBF_ALLOCATIONS)
360 sadb_lifetime->sadb_lifetime_allocations =
361 tdb->tdb_exp_allocations;
362
363 if (tdb->tdb_flags & TDBF_BYTES)
364 sadb_lifetime->sadb_lifetime_bytes =
365 tdb->tdb_exp_bytes;
366
367 if (tdb->tdb_flags & TDBF_TIMER)
368 sadb_lifetime->sadb_lifetime_addtime =
369 tdb->tdb_exp_timeout;
370
371 if (tdb->tdb_flags & TDBF_FIRSTUSE)
372 sadb_lifetime->sadb_lifetime_usetime =
373 tdb->tdb_exp_first_use;
374 break;
375
376 case PFKEYV2_LIFETIME_SOFT:
377 if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
378 sadb_lifetime->sadb_lifetime_allocations =
379 tdb->tdb_soft_allocations;
380
381 if (tdb->tdb_flags & TDBF_SOFT_BYTES)
382 sadb_lifetime->sadb_lifetime_bytes =
383 tdb->tdb_soft_bytes;
384
385 if (tdb->tdb_flags & TDBF_SOFT_TIMER)
386 sadb_lifetime->sadb_lifetime_addtime =
387 tdb->tdb_soft_timeout;
388
389 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
390 sadb_lifetime->sadb_lifetime_usetime =
391 tdb->tdb_soft_first_use;
392 break;
393
394 case PFKEYV2_LIFETIME_CURRENT:
395 sadb_lifetime->sadb_lifetime_allocations =
396 tdb->tdb_cur_allocations;
397 sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
398 sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
399 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
400 break;
401 }
402
403 *p += sizeof(struct sadb_lifetime);
404 }
405
406 /*
407 * Import flow information to two struct sockaddr_encap's. Either
408 * all or none of the address arguments are NULL.
409 */
410 void
import_flow(struct sockaddr_encap * flow,struct sockaddr_encap * flowmask,struct sadb_address * ssrc,struct sadb_address * ssrcmask,struct sadb_address * ddst,struct sadb_address * ddstmask,struct sadb_protocol * sab,struct sadb_protocol * ftype)411 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
412 struct sadb_address *ssrc, struct sadb_address *ssrcmask,
413 struct sadb_address *ddst, struct sadb_address *ddstmask,
414 struct sadb_protocol *sab, struct sadb_protocol *ftype)
415 {
416 u_int8_t transproto = 0;
417 union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1);
418 union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1);
419 union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1);
420 union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1);
421
422 if (ssrc == NULL)
423 return; /* There wasn't any information to begin with. */
424
425 bzero(flow, sizeof(*flow));
426 bzero(flowmask, sizeof(*flowmask));
427
428 if (sab != NULL)
429 transproto = sab->sadb_protocol_proto;
430
431 /*
432 * Check that all the address families match. We know they are
433 * valid and supported because pfkeyv2_parsemessage() checked that.
434 */
435 if ((src->sa.sa_family != dst->sa.sa_family) ||
436 (src->sa.sa_family != srcmask->sa.sa_family) ||
437 (src->sa.sa_family != dstmask->sa.sa_family))
438 return;
439
440 /* Generic netmask handling, works for IPv4 and IPv6. */
441 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
442 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
443
444 /*
445 * We set these as an indication that tdb_filter/tdb_filtermask are
446 * in fact initialized.
447 */
448 flow->sen_family = flowmask->sen_family = PF_KEY;
449 flow->sen_len = flowmask->sen_len = SENT_LEN;
450
451 switch (src->sa.sa_family)
452 {
453 #ifdef INET
454 case AF_INET:
455 flow->sen_type = SENT_IP4;
456 flow->sen_direction = ftype->sadb_protocol_direction;
457 flow->sen_ip_src = src->sin.sin_addr;
458 flow->sen_ip_dst = dst->sin.sin_addr;
459 flow->sen_proto = transproto;
460 flow->sen_sport = src->sin.sin_port;
461 flow->sen_dport = dst->sin.sin_port;
462
463 flowmask->sen_type = SENT_IP4;
464 flowmask->sen_direction = 0xff;
465 flowmask->sen_ip_src = srcmask->sin.sin_addr;
466 flowmask->sen_ip_dst = dstmask->sin.sin_addr;
467 flowmask->sen_sport = srcmask->sin.sin_port;
468 flowmask->sen_dport = dstmask->sin.sin_port;
469 if (transproto)
470 flowmask->sen_proto = 0xff;
471 break;
472 #endif /* INET */
473
474 #ifdef INET6
475 case AF_INET6:
476 flow->sen_type = SENT_IP6;
477 flow->sen_ip6_direction = ftype->sadb_protocol_direction;
478 flow->sen_ip6_src = src->sin6.sin6_addr;
479 flow->sen_ip6_dst = dst->sin6.sin6_addr;
480 flow->sen_ip6_proto = transproto;
481 flow->sen_ip6_sport = src->sin6.sin6_port;
482 flow->sen_ip6_dport = dst->sin6.sin6_port;
483
484 flowmask->sen_type = SENT_IP6;
485 flowmask->sen_ip6_direction = 0xff;
486 flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
487 flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
488 flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
489 flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
490 if (transproto)
491 flowmask->sen_ip6_proto = 0xff;
492 break;
493 #endif /* INET6 */
494 }
495 }
496
497 /*
498 * Copy an SADB_ADDRESS payload to a struct sockaddr.
499 */
500 void
import_address(struct sockaddr * sa,struct sadb_address * sadb_address)501 import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
502 {
503 int salen;
504 struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
505 sizeof(struct sadb_address));
506
507 if (!sadb_address)
508 return;
509
510 if (ssa->sa_len)
511 salen = ssa->sa_len;
512 else
513 switch (ssa->sa_family) {
514 #ifdef INET
515 case AF_INET:
516 salen = sizeof(struct sockaddr_in);
517 break;
518 #endif /* INET */
519
520 #if INET6
521 case AF_INET6:
522 salen = sizeof(struct sockaddr_in6);
523 break;
524 #endif /* INET6 */
525
526 default:
527 return;
528 }
529
530 bcopy(ssa, sa, salen);
531 sa->sa_len = salen;
532 }
533
534 /*
535 * Export a struct sockaddr as an SADB_ADDRESS payload.
536 */
537 void
export_address(void ** p,struct sockaddr * sa)538 export_address(void **p, struct sockaddr *sa)
539 {
540 struct sadb_address *sadb_address = (struct sadb_address *) *p;
541
542 sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
543 PADUP(SA_LEN(sa))) / sizeof(uint64_t);
544
545 *p += sizeof(struct sadb_address);
546 bcopy(sa, *p, SA_LEN(sa));
547 ((struct sockaddr *) *p)->sa_family = sa->sa_family;
548 *p += PADUP(SA_LEN(sa));
549 }
550
551 /*
552 * Import authentication information into the TDB.
553 */
554 void
import_auth(struct tdb * tdb,struct sadb_x_cred * sadb_auth,int dstauth)555 import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth)
556 {
557 struct ipsec_ref **ipr;
558
559 if (!sadb_auth)
560 return;
561
562 if (dstauth == PFKEYV2_AUTH_REMOTE)
563 ipr = &tdb->tdb_remote_auth;
564 else
565 ipr = &tdb->tdb_local_auth;
566
567 MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) -
568 sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
569 M_CREDENTIALS, M_WAITOK);
570 (*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred);
571
572 switch (sadb_auth->sadb_x_cred_type) {
573 case SADB_X_AUTHTYPE_PASSPHRASE:
574 (*ipr)->ref_type = IPSP_AUTH_PASSPHRASE;
575 break;
576 case SADB_X_AUTHTYPE_RSA:
577 (*ipr)->ref_type = IPSP_AUTH_RSA;
578 break;
579 default:
580 FREE(*ipr, M_CREDENTIALS);
581 *ipr = NULL;
582 return;
583 }
584 (*ipr)->ref_count = 1;
585 (*ipr)->ref_malloctype = M_CREDENTIALS;
586 bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred),
587 (*ipr) + 1, (*ipr)->ref_len);
588 }
589
590 /*
591 * Import a set of credentials into the TDB.
592 */
593 void
import_credentials(struct tdb * tdb,struct sadb_x_cred * sadb_cred,int dstcred)594 import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred)
595 {
596 struct ipsec_ref **ipr;
597
598 if (!sadb_cred)
599 return;
600
601 if (dstcred == PFKEYV2_CRED_REMOTE)
602 ipr = &tdb->tdb_remote_cred;
603 else
604 ipr = &tdb->tdb_local_cred;
605
606 MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) -
607 sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
608 M_CREDENTIALS, M_WAITOK);
609 (*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred);
610
611 switch (sadb_cred->sadb_x_cred_type) {
612 case SADB_X_CREDTYPE_X509:
613 (*ipr)->ref_type = IPSP_CRED_X509;
614 break;
615 case SADB_X_CREDTYPE_KEYNOTE:
616 (*ipr)->ref_type = IPSP_CRED_KEYNOTE;
617 break;
618 default:
619 FREE(*ipr, M_CREDENTIALS);
620 *ipr = NULL;
621 return;
622 }
623 (*ipr)->ref_count = 1;
624 (*ipr)->ref_malloctype = M_CREDENTIALS;
625 bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred),
626 (*ipr) + 1, (*ipr)->ref_len);
627 }
628
629 /*
630 * Import an identity payload into the TDB.
631 */
632 void
import_identity(struct tdb * tdb,struct sadb_ident * sadb_ident,int type)633 import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type)
634 {
635 struct ipsec_ref **ipr;
636
637 if (!sadb_ident)
638 return;
639
640 if (type == PFKEYV2_IDENTITY_SRC)
641 ipr = &tdb->tdb_srcid;
642 else
643 ipr = &tdb->tdb_dstid;
644
645 MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) -
646 sizeof(struct sadb_ident) + sizeof(struct ipsec_ref),
647 M_CREDENTIALS, M_WAITOK);
648 (*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
649
650 switch (sadb_ident->sadb_ident_type) {
651 case SADB_IDENTTYPE_PREFIX:
652 (*ipr)->ref_type = IPSP_IDENTITY_PREFIX;
653 break;
654 case SADB_IDENTTYPE_FQDN:
655 (*ipr)->ref_type = IPSP_IDENTITY_FQDN;
656 break;
657 case SADB_IDENTTYPE_USERFQDN:
658 (*ipr)->ref_type = IPSP_IDENTITY_USERFQDN;
659 break;
660 case SADB_X_IDENTTYPE_CONNECTION:
661 (*ipr)->ref_type = IPSP_IDENTITY_CONNECTION;
662 break;
663 default:
664 FREE(*ipr, M_CREDENTIALS);
665 *ipr = NULL;
666 return;
667 }
668 (*ipr)->ref_count = 1;
669 (*ipr)->ref_malloctype = M_CREDENTIALS;
670 bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1,
671 (*ipr)->ref_len);
672 }
673
674 void
export_credentials(void ** p,struct tdb * tdb,int dstcred)675 export_credentials(void **p, struct tdb *tdb, int dstcred)
676 {
677 struct ipsec_ref **ipr;
678 struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p;
679
680 if (dstcred == PFKEYV2_CRED_REMOTE)
681 ipr = &tdb->tdb_remote_cred;
682 else
683 ipr = &tdb->tdb_local_cred;
684
685 sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
686 PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
687
688 switch ((*ipr)->ref_type) {
689 case IPSP_CRED_KEYNOTE:
690 sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
691 break;
692 case IPSP_CRED_X509:
693 sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
694 break;
695 }
696 *p += sizeof(struct sadb_x_cred);
697 bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
698 *p += PADUP((*ipr)->ref_len);
699 }
700
701 void
export_auth(void ** p,struct tdb * tdb,int dstauth)702 export_auth(void **p, struct tdb *tdb, int dstauth)
703 {
704 struct ipsec_ref **ipr;
705 struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p;
706
707 if (dstauth == PFKEYV2_AUTH_REMOTE)
708 ipr = &tdb->tdb_remote_auth;
709 else
710 ipr = &tdb->tdb_local_auth;
711
712 sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
713 PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
714
715 switch ((*ipr)->ref_type) {
716 case IPSP_AUTH_PASSPHRASE:
717 sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
718 break;
719 case IPSP_AUTH_RSA:
720 sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
721 break;
722 }
723 *p += sizeof(struct sadb_x_cred);
724 bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
725 *p += PADUP((*ipr)->ref_len);
726 }
727
728 void
export_identity(void ** p,struct tdb * tdb,int type)729 export_identity(void **p, struct tdb *tdb, int type)
730 {
731 struct ipsec_ref **ipr;
732 struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
733
734 if (type == PFKEYV2_IDENTITY_SRC)
735 ipr = &tdb->tdb_srcid;
736 else
737 ipr = &tdb->tdb_dstid;
738
739 sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
740 PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
741
742 switch ((*ipr)->ref_type) {
743 case IPSP_IDENTITY_PREFIX:
744 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
745 break;
746 case IPSP_IDENTITY_FQDN:
747 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
748 break;
749 case IPSP_IDENTITY_USERFQDN:
750 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
751 break;
752 case IPSP_IDENTITY_CONNECTION:
753 sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION;
754 break;
755 }
756 *p += sizeof(struct sadb_ident);
757 bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
758 *p += PADUP((*ipr)->ref_len);
759 }
760
761 /* ... */
762 void
import_key(struct ipsecinit * ii,struct sadb_key * sadb_key,int type)763 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
764 {
765 if (!sadb_key)
766 return;
767
768 if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
769 ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
770 ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
771 } else {
772 ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
773 ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
774 }
775 }
776
777 void
export_key(void ** p,struct tdb * tdb,int type)778 export_key(void **p, struct tdb *tdb, int type)
779 {
780 struct sadb_key *sadb_key = (struct sadb_key *) *p;
781
782 if (type == PFKEYV2_ENCRYPTION_KEY) {
783 sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
784 PADUP(tdb->tdb_emxkeylen)) /
785 sizeof(uint64_t);
786 sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
787 *p += sizeof(struct sadb_key);
788 bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
789 *p += PADUP(tdb->tdb_emxkeylen);
790 } else {
791 sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
792 PADUP(tdb->tdb_amxkeylen)) /
793 sizeof(uint64_t);
794 sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
795 *p += sizeof(struct sadb_key);
796 bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
797 *p += PADUP(tdb->tdb_amxkeylen);
798 }
799 }
800
801 /* Import/Export remote port for UDP Encapsulation */
802 void
import_udpencap(struct tdb * tdb,struct sadb_x_udpencap * sadb_udpencap)803 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
804 {
805 if (sadb_udpencap)
806 tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
807 }
808
809 void
export_udpencap(void ** p,struct tdb * tdb)810 export_udpencap(void **p, struct tdb *tdb)
811 {
812 struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
813
814 sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
815 sadb_udpencap->sadb_x_udpencap_reserved = 0;
816 sadb_udpencap->sadb_x_udpencap_len =
817 sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
818 *p += sizeof(struct sadb_x_udpencap);
819 }
820