xref: /openbsd-src/sys/net/pfkeyv2_convert.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: pfkeyv2_convert.c,v 1.5 2001/07/05 16:48:04 jjbg 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 <netinet/ip_ipsp.h>
101 #include <net/pfkeyv2.h>
102 #include <crypto/cryptodev.h>
103 #include <crypto/xform.h>
104 
105 /*
106  * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
107  * of the TDB will be initialized by other import routines, and tdb_init().
108  */
109 void
110 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
111 {
112 	if (!sadb_sa)
113 		return;
114 
115 	if (ii) {
116 		ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
117 		ii->ii_authalg = sadb_sa->sadb_sa_auth;
118 		ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
119 
120 		tdb->tdb_spi = sadb_sa->sadb_sa_spi;
121 		tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
122 
123 		if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
124 			tdb->tdb_flags |= TDBF_PFS;
125 
126 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV)
127 			tdb->tdb_flags |= TDBF_HALFIV;
128 
129 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
130 			tdb->tdb_flags |= TDBF_TUNNELING;
131 
132 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING)
133 			tdb->tdb_flags |= TDBF_RANDOMPADDING;
134 
135 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY)
136 			tdb->tdb_flags |= TDBF_NOREPLAY;
137 	}
138 
139 	if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
140 		tdb->tdb_flags |= TDBF_INVALID;
141 }
142 
143 /*
144  * Export some of the information on a TDB.
145  */
146 void
147 export_sa(void **p, struct tdb *tdb)
148 {
149 	struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
150 
151 	sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
152 
153 	sadb_sa->sadb_sa_spi = tdb->tdb_spi;
154 	sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
155 
156 	if (tdb->tdb_flags & TDBF_INVALID)
157 		sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
158 
159 	if (tdb->tdb_sproto == IPPROTO_IPCOMP) {
160 		switch (tdb->tdb_compalgxform->type)
161 		{
162 		case CRYPTO_DEFLATE_COMP:
163 			sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
164 			break;
165 		}
166 	}
167 
168 	if (tdb->tdb_authalgxform) {
169 		switch (tdb->tdb_authalgxform->type) {
170 		case CRYPTO_MD5_HMAC:
171 			sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
172 			break;
173 
174 		case CRYPTO_SHA1_HMAC:
175 			sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
176 			break;
177 
178 		case CRYPTO_RIPEMD160_HMAC:
179 			sadb_sa->sadb_sa_auth = SADB_AALG_RIPEMD160HMAC;
180 			break;
181 
182 		case CRYPTO_MD5_KPDK:
183 			sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5;
184 			break;
185 
186 		case CRYPTO_SHA1_KPDK:
187 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1;
188 			break;
189 		}
190 	}
191 
192 	if (tdb->tdb_encalgxform) {
193 		switch (tdb->tdb_encalgxform->type) {
194 		case CRYPTO_DES_CBC:
195 			sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC;
196 			break;
197 
198 		case CRYPTO_3DES_CBC:
199 			sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
200 			break;
201 
202 		case CRYPTO_AES_CBC:
203 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
204 			break;
205 
206 		case CRYPTO_CAST_CBC:
207 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
208 			break;
209 
210 		case CRYPTO_BLF_CBC:
211 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
212 			break;
213 
214 		case CRYPTO_SKIPJACK_CBC:
215 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK;
216 			break;
217 		}
218 	}
219 
220 	if (tdb->tdb_flags & TDBF_PFS)
221 		sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
222 
223 	/* Only relevant for the "old" IPsec transforms. */
224 	if (tdb->tdb_flags & TDBF_HALFIV)
225 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
226 
227 	if (tdb->tdb_flags & TDBF_TUNNELING)
228 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
229 
230 	if (tdb->tdb_flags & TDBF_RANDOMPADDING)
231 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING;
232 
233 	if (tdb->tdb_flags & TDBF_NOREPLAY)
234 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
235 
236 	*p += sizeof(struct sadb_sa);
237 }
238 
239 /*
240  * Initialize expirations and counters based on lifetime payload.
241  */
242 void
243 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
244 {
245 	if (!sadb_lifetime)
246 		return;
247 
248 	switch (type) {
249 	case PFKEYV2_LIFETIME_HARD:
250 		if ((tdb->tdb_exp_allocations =
251 		    sadb_lifetime->sadb_lifetime_allocations) != 0)
252 			tdb->tdb_flags |= TDBF_ALLOCATIONS;
253 		else
254 			tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
255 
256 		if ((tdb->tdb_exp_bytes =
257 		    sadb_lifetime->sadb_lifetime_bytes) != 0)
258 			tdb->tdb_flags |= TDBF_BYTES;
259 		else
260 			tdb->tdb_flags &= ~TDBF_BYTES;
261 
262 		if ((tdb->tdb_exp_timeout =
263 		    sadb_lifetime->sadb_lifetime_addtime) != 0) {
264 			tdb->tdb_flags |= TDBF_TIMER;
265 			timeout_add(&tdb->tdb_timer_tmo,
266 			    hz * tdb->tdb_exp_timeout);
267 		} else
268 			tdb->tdb_flags &= ~TDBF_TIMER;
269 
270 		if ((tdb->tdb_exp_first_use =
271 		    sadb_lifetime->sadb_lifetime_usetime) != 0)	{
272 			tdb->tdb_flags |= TDBF_FIRSTUSE;
273 			timeout_add(&tdb->tdb_first_tmo,
274 			    hz * tdb->tdb_exp_first_use);
275 		} else
276 			tdb->tdb_flags &= ~TDBF_FIRSTUSE;
277 		break;
278 
279 	case PFKEYV2_LIFETIME_SOFT:
280 		if ((tdb->tdb_soft_allocations =
281 		    sadb_lifetime->sadb_lifetime_allocations) != 0)
282 			tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
283 		else
284 			tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
285 
286 		if ((tdb->tdb_soft_bytes =
287 		    sadb_lifetime->sadb_lifetime_bytes) != 0)
288 			tdb->tdb_flags |= TDBF_SOFT_BYTES;
289 		else
290 			tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
291 
292 		if ((tdb->tdb_soft_timeout =
293 		    sadb_lifetime->sadb_lifetime_addtime) != 0) {
294 			tdb->tdb_flags |= TDBF_SOFT_TIMER;
295 			timeout_add(&tdb->tdb_stimer_tmo,
296 			    hz * tdb->tdb_soft_timeout);
297 		} else
298 			tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
299 
300 		if ((tdb->tdb_soft_first_use =
301 		    sadb_lifetime->sadb_lifetime_usetime) != 0)	{
302 			tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
303 			timeout_add(&tdb->tdb_sfirst_tmo, hz *
304 			    tdb->tdb_soft_first_use);
305 		}
306 		else
307 			tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
308 		break;
309 
310 	case PFKEYV2_LIFETIME_CURRENT:  /* Nothing fancy here. */
311 		tdb->tdb_cur_allocations =
312 		    sadb_lifetime->sadb_lifetime_allocations;
313 		tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
314 		tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
315 		tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
316 	}
317 }
318 
319 /*
320  * Export TDB expiration information.
321  */
322 void
323 export_lifetime(void **p, struct tdb *tdb, int type)
324 {
325 	struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
326 
327 	sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
328 	    sizeof(uint64_t);
329 
330 	switch (type) {
331 	case PFKEYV2_LIFETIME_HARD:
332 		if (tdb->tdb_flags & TDBF_ALLOCATIONS)
333 			sadb_lifetime->sadb_lifetime_allocations =
334 			    tdb->tdb_exp_allocations;
335 
336 		if (tdb->tdb_flags & TDBF_BYTES)
337 			sadb_lifetime->sadb_lifetime_bytes =
338 			    tdb->tdb_exp_bytes;
339 
340 		if (tdb->tdb_flags & TDBF_TIMER)
341 			sadb_lifetime->sadb_lifetime_addtime =
342 			    tdb->tdb_exp_timeout;
343 
344 		if (tdb->tdb_flags & TDBF_FIRSTUSE)
345 			sadb_lifetime->sadb_lifetime_usetime =
346 			    tdb->tdb_exp_first_use;
347 		break;
348 
349 	case PFKEYV2_LIFETIME_SOFT:
350 		if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
351 			sadb_lifetime->sadb_lifetime_allocations =
352 			    tdb->tdb_soft_allocations;
353 
354 		if (tdb->tdb_flags & TDBF_SOFT_BYTES)
355 			sadb_lifetime->sadb_lifetime_bytes =
356 			    tdb->tdb_soft_bytes;
357 
358 		if (tdb->tdb_flags & TDBF_SOFT_TIMER)
359 			sadb_lifetime->sadb_lifetime_addtime =
360 			    tdb->tdb_soft_timeout;
361 
362 		if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
363 			sadb_lifetime->sadb_lifetime_usetime =
364 			    tdb->tdb_soft_first_use;
365 		break;
366 
367 	case PFKEYV2_LIFETIME_CURRENT:
368 		sadb_lifetime->sadb_lifetime_allocations =
369 		    tdb->tdb_cur_allocations;
370 		sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
371 		sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
372 		sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
373 		break;
374 	}
375 
376 	*p += sizeof(struct sadb_lifetime);
377 }
378 
379 /*
380  * Copy an SADB_ADDRESS payload to a struct sockaddr.
381  */
382 void
383 import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
384 {
385 	int salen;
386 	struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
387 	    sizeof(struct sadb_address));
388 
389 	if (!sadb_address)
390 		return;
391 
392 	if (ssa->sa_len)
393 		salen = ssa->sa_len;
394 	else
395 		switch(ssa->sa_family) {
396 #ifdef INET
397 		case AF_INET:
398 			salen = sizeof(struct sockaddr_in);
399 			break;
400 #endif /* INET */
401 
402 #if INET6
403 		case AF_INET6:
404 			salen = sizeof(struct sockaddr_in6);
405 			break;
406 #endif /* INET6 */
407 
408 		default:
409 			return;
410 		}
411 
412 	bcopy(ssa, sa, salen);
413 	sa->sa_len = salen;
414 }
415 
416 /*
417  * Export a struct sockaddr as an SADB_ADDRESS payload.
418  */
419 void
420 export_address(void **p, struct sockaddr *sa)
421 {
422 	struct sadb_address *sadb_address = (struct sadb_address *) *p;
423 
424 	sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
425 	    PADUP(SA_LEN(sa))) / sizeof(uint64_t);
426 
427 	*p += sizeof(struct sadb_address);
428 	bcopy(sa, *p, SA_LEN(sa));
429 	((struct sockaddr *) *p)->sa_family = sa->sa_family;
430 	*p += PADUP(SA_LEN(sa));
431 }
432 
433 /*
434  * Import authentication information into the TDB.
435  */
436 void
437 import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth)
438 {
439 	struct ipsec_ref **ipr;
440 
441 	if (!sadb_auth)
442 		return;
443 
444 	if (dstauth == PFKEYV2_AUTH_REMOTE)
445 		ipr = &tdb->tdb_remote_auth;
446 	else
447 		ipr = &tdb->tdb_local_auth;
448 
449 	MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) -
450 	    sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
451 	    M_CREDENTIALS, M_WAITOK);
452 	(*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred);
453 
454 	switch (sadb_auth->sadb_x_cred_type) {
455 	case SADB_X_AUTHTYPE_PASSPHRASE:
456 		(*ipr)->ref_type = IPSP_AUTH_PASSPHRASE;
457 		break;
458 	case SADB_X_AUTHTYPE_RSA:
459 		(*ipr)->ref_type = IPSP_AUTH_RSA;
460 		break;
461 	default:
462 		FREE(*ipr, M_CREDENTIALS);
463 		*ipr = NULL;
464 		return;
465 	}
466 	(*ipr)->ref_count = 1;
467 	(*ipr)->ref_malloctype = M_CREDENTIALS;
468 	bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred),
469 	    (*ipr) + 1, (*ipr)->ref_len);
470 }
471 
472 /*
473  * Import a set of credentials into the TDB.
474  */
475 void
476 import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred)
477 {
478 	struct ipsec_ref **ipr;
479 
480 	if (!sadb_cred)
481 		return;
482 
483 	if (dstcred == PFKEYV2_CRED_REMOTE)
484 		ipr = &tdb->tdb_remote_cred;
485 	else
486 		ipr = &tdb->tdb_local_cred;
487 
488 	MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) -
489 	    sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
490 	    M_CREDENTIALS, M_WAITOK);
491 	(*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred);
492 
493 	switch (sadb_cred->sadb_x_cred_type) {
494 	case SADB_X_CREDTYPE_X509:
495 		(*ipr)->ref_type = IPSP_CRED_X509;
496 		break;
497 	case SADB_X_CREDTYPE_KEYNOTE:
498 		(*ipr)->ref_type = IPSP_CRED_KEYNOTE;
499 		break;
500 	default:
501 		FREE(*ipr, M_CREDENTIALS);
502 		*ipr = NULL;
503 		return;
504 	}
505 	(*ipr)->ref_count = 1;
506 	(*ipr)->ref_malloctype = M_CREDENTIALS;
507 	bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred),
508 	    (*ipr) + 1, (*ipr)->ref_len);
509 }
510 
511 /*
512  * Import an identity payload into the TDB.
513  */
514 void
515 import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type)
516 {
517 	struct ipsec_ref **ipr;
518 
519 	if (!sadb_ident)
520 		return;
521 
522 	if (type == PFKEYV2_IDENTITY_SRC)
523 		ipr = &tdb->tdb_srcid;
524 	else
525 		ipr = &tdb->tdb_dstid;
526 
527 	MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) -
528 	    sizeof(struct sadb_ident) + sizeof(struct ipsec_ref),
529 	    M_CREDENTIALS, M_WAITOK);
530 	(*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
531 
532 	switch (sadb_ident->sadb_ident_type) {
533 	case SADB_IDENTTYPE_PREFIX:
534 		(*ipr)->ref_type = IPSP_IDENTITY_PREFIX;
535 		break;
536 	case SADB_IDENTTYPE_FQDN:
537 		(*ipr)->ref_type = IPSP_IDENTITY_FQDN;
538 		break;
539 	case SADB_IDENTTYPE_USERFQDN:
540 		(*ipr)->ref_type = IPSP_IDENTITY_USERFQDN;
541 		break;
542 	case SADB_X_IDENTTYPE_CONNECTION:
543 		(*ipr)->ref_type = IPSP_IDENTITY_CONNECTION;
544 		break;
545 	default:
546 		FREE(*ipr, M_CREDENTIALS);
547 		*ipr = NULL;
548 		return;
549 	}
550 	(*ipr)->ref_count = 1;
551 	(*ipr)->ref_malloctype = M_CREDENTIALS;
552 	bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1,
553 	    (*ipr)->ref_len);
554 }
555 
556 void
557 export_credentials(void **p, struct tdb *tdb, int dstcred)
558 {
559 	struct ipsec_ref **ipr;
560 	struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p;
561 
562 	if (dstcred == PFKEYV2_CRED_REMOTE)
563 		ipr = &tdb->tdb_remote_cred;
564 	else
565 		ipr = &tdb->tdb_local_cred;
566 
567 	sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
568 	    PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
569 
570 	switch ((*ipr)->ref_type) {
571 	case IPSP_CRED_KEYNOTE:
572 		sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
573 		break;
574 	case IPSP_CRED_X509:
575 		sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
576 		break;
577 	}
578 	*p += sizeof(struct sadb_x_cred);
579 	bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
580 	*p += PADUP((*ipr)->ref_len);
581 }
582 
583 void
584 export_auth(void **p, struct tdb *tdb, int dstauth)
585 {
586 	struct ipsec_ref **ipr;
587 	struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p;
588 
589 	if (dstauth == PFKEYV2_AUTH_REMOTE)
590 		ipr = &tdb->tdb_remote_auth;
591 	else
592 		ipr = &tdb->tdb_local_auth;
593 
594 	sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
595 	    PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
596 
597 	switch ((*ipr)->ref_type) {
598 	case IPSP_CRED_KEYNOTE:
599 		sadb_auth->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
600 		break;
601 	case IPSP_CRED_X509:
602 		sadb_auth->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
603 		break;
604 	}
605 	*p += sizeof(struct sadb_x_cred);
606 	bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
607 	*p += PADUP((*ipr)->ref_len);
608 }
609 
610 void
611 export_identity(void **p, struct tdb *tdb, int type)
612 {
613 	struct ipsec_ref **ipr;
614 	struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
615 
616 	if (type == PFKEYV2_IDENTITY_SRC)
617 		ipr = &tdb->tdb_srcid;
618 	else
619 		ipr = &tdb->tdb_dstid;
620 
621 	sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
622 	    PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
623 
624 	switch ((*ipr)->ref_type) {
625 	case IPSP_IDENTITY_PREFIX:
626 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
627 		break;
628 	case IPSP_IDENTITY_FQDN:
629 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
630 		break;
631 	case IPSP_IDENTITY_USERFQDN:
632 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
633 		break;
634 	case IPSP_IDENTITY_CONNECTION:
635 		sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION;
636 		break;
637 	}
638 	*p += sizeof(struct sadb_ident);
639 	bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
640 	*p += PADUP((*ipr)->ref_len);
641 }
642 
643 /* ... */
644 void
645 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
646 {
647 	if (!sadb_key)
648 		return;
649 
650 	if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
651 		ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
652 		ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
653 	} else {
654 		ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
655 		ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
656 	}
657 }
658 
659 void
660 export_key(void **p, struct tdb *tdb, int type)
661 {
662 	struct sadb_key *sadb_key = (struct sadb_key *) *p;
663 
664 	if (type == PFKEYV2_ENCRYPTION_KEY) {
665 		sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
666 		    PADUP(tdb->tdb_emxkeylen)) /
667 		    sizeof(uint64_t);
668 		sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
669 		*p += sizeof(struct sadb_key);
670 		bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
671 		*p += PADUP(tdb->tdb_emxkeylen);
672 	} else {
673 		sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
674 		    PADUP(tdb->tdb_amxkeylen)) /
675 		    sizeof(uint64_t);
676 		sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
677 		*p += sizeof(struct sadb_key);
678 		bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
679 		*p += PADUP(tdb->tdb_amxkeylen);
680 	}
681 }
682