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