xref: /openbsd/sys/net/pfkeyv2_convert.c (revision 952c6363)
1 /*	$OpenBSD: pfkeyv2_convert.c,v 1.83 2023/11/28 13:23:20 bluhm 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 "pf.h"
95 
96 #include <sys/param.h>
97 #include <sys/systm.h>
98 #include <sys/mbuf.h>
99 #include <sys/kernel.h>
100 #include <sys/socket.h>
101 #include <sys/timeout.h>
102 #include <net/route.h>
103 #include <net/if.h>
104 
105 #include <netinet/in.h>
106 #include <netinet/ip_ipsp.h>
107 #include <net/pfkeyv2.h>
108 #include <crypto/cryptodev.h>
109 #include <crypto/xform.h>
110 
111 #if NPF > 0
112 #include <net/pfvar.h>
113 #endif
114 
115 /*
116  * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
117  * of the TDB will be initialized by other import routines, and tdb_init().
118  */
119 void
import_sa(struct tdb * tdb,struct sadb_sa * sadb_sa,struct ipsecinit * ii)120 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
121 {
122 	if (!sadb_sa)
123 		return;
124 
125 	mtx_enter(&tdb->tdb_mtx);
126 	if (ii) {
127 		ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
128 		ii->ii_authalg = sadb_sa->sadb_sa_auth;
129 		ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
130 
131 		tdb->tdb_spi = sadb_sa->sadb_sa_spi;
132 		tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
133 
134 		if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
135 			tdb->tdb_flags |= TDBF_PFS;
136 
137 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
138 			tdb->tdb_flags |= TDBF_TUNNELING;
139 
140 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
141 			tdb->tdb_flags |= TDBF_UDPENCAP;
142 
143 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_ESN)
144 			tdb->tdb_flags |= TDBF_ESN;
145 	}
146 
147 	if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
148 		tdb->tdb_flags |= TDBF_INVALID;
149 	mtx_leave(&tdb->tdb_mtx);
150 }
151 
152 /*
153  * Export some of the information on a TDB.
154  */
155 void
export_sa(void ** p,struct tdb * tdb)156 export_sa(void **p, struct tdb *tdb)
157 {
158 	struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
159 
160 	sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
161 
162 	sadb_sa->sadb_sa_spi = tdb->tdb_spi;
163 	sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
164 
165 	if (tdb->tdb_flags & TDBF_INVALID)
166 		sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
167 	else
168 		sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE;
169 
170 	if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
171 	    tdb->tdb_compalgxform != NULL) {
172 		switch (tdb->tdb_compalgxform->type) {
173 		case CRYPTO_DEFLATE_COMP:
174 			sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
175 			break;
176 		}
177 	}
178 
179 	if (tdb->tdb_authalgxform) {
180 		switch (tdb->tdb_authalgxform->type) {
181 		case CRYPTO_MD5_HMAC:
182 			sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
183 			break;
184 
185 		case CRYPTO_SHA1_HMAC:
186 			sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
187 			break;
188 
189 		case CRYPTO_RIPEMD160_HMAC:
190 			sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
191 			break;
192 
193 		case CRYPTO_SHA2_256_HMAC:
194 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
195 			break;
196 
197 		case CRYPTO_SHA2_384_HMAC:
198 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
199 			break;
200 
201 		case CRYPTO_SHA2_512_HMAC:
202 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
203 			break;
204 
205 		case CRYPTO_AES_128_GMAC:
206 			sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC;
207 			break;
208 
209 		case CRYPTO_AES_192_GMAC:
210 			sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC;
211 			break;
212 
213 		case CRYPTO_AES_256_GMAC:
214 			sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC;
215 			break;
216 
217 		case CRYPTO_CHACHA20_POLY1305_MAC:
218 			sadb_sa->sadb_sa_auth = SADB_X_AALG_CHACHA20POLY1305;
219 			break;
220 		}
221 	}
222 
223 	if (tdb->tdb_encalgxform) {
224 		switch (tdb->tdb_encalgxform->type) {
225 		case CRYPTO_NULL:
226 			sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL;
227 			break;
228 
229 		case CRYPTO_3DES_CBC:
230 			sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
231 			break;
232 
233 		case CRYPTO_AES_CBC:
234 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
235 			break;
236 
237 		case CRYPTO_AES_CTR:
238 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
239 			break;
240 
241 		case CRYPTO_AES_GCM_16:
242 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
243 			break;
244 
245 		case CRYPTO_AES_GMAC:
246 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC;
247 			break;
248 
249 		case CRYPTO_CAST_CBC:
250 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
251 			break;
252 
253 		case CRYPTO_BLF_CBC:
254 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
255 			break;
256 
257 		case CRYPTO_CHACHA20_POLY1305:
258 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CHACHA20POLY1305;
259 			break;
260 		}
261 	}
262 
263 	if (tdb->tdb_flags & TDBF_PFS)
264 		sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
265 
266 	if (tdb->tdb_flags & TDBF_TUNNELING)
267 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
268 
269 	if (tdb->tdb_flags & TDBF_UDPENCAP)
270 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP;
271 
272 	if (tdb->tdb_flags & TDBF_ESN)
273 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_ESN;
274 
275 	*p += sizeof(struct sadb_sa);
276 }
277 
278 /*
279  * Initialize expirations and counters based on lifetime payload.
280  */
281 void
import_lifetime(struct tdb * tdb,struct sadb_lifetime * sadb_lifetime,int type)282 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
283 {
284 	if (!sadb_lifetime)
285 		return;
286 
287 	mtx_enter(&tdb->tdb_mtx);
288 	switch (type) {
289 	case PFKEYV2_LIFETIME_HARD:
290 		if ((tdb->tdb_exp_allocations =
291 		    sadb_lifetime->sadb_lifetime_allocations) != 0)
292 			tdb->tdb_flags |= TDBF_ALLOCATIONS;
293 		else
294 			tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
295 
296 		if ((tdb->tdb_exp_bytes =
297 		    sadb_lifetime->sadb_lifetime_bytes) != 0)
298 			tdb->tdb_flags |= TDBF_BYTES;
299 		else
300 			tdb->tdb_flags &= ~TDBF_BYTES;
301 
302 		if ((tdb->tdb_exp_timeout =
303 		    sadb_lifetime->sadb_lifetime_addtime) != 0) {
304 			tdb->tdb_flags |= TDBF_TIMER;
305 		} else
306 			tdb->tdb_flags &= ~TDBF_TIMER;
307 
308 		if ((tdb->tdb_exp_first_use =
309 		    sadb_lifetime->sadb_lifetime_usetime) != 0)
310 			tdb->tdb_flags |= TDBF_FIRSTUSE;
311 		else
312 			tdb->tdb_flags &= ~TDBF_FIRSTUSE;
313 		break;
314 
315 	case PFKEYV2_LIFETIME_SOFT:
316 		if ((tdb->tdb_soft_allocations =
317 		    sadb_lifetime->sadb_lifetime_allocations) != 0)
318 			tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
319 		else
320 			tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
321 
322 		if ((tdb->tdb_soft_bytes =
323 		    sadb_lifetime->sadb_lifetime_bytes) != 0)
324 			tdb->tdb_flags |= TDBF_SOFT_BYTES;
325 		else
326 			tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
327 
328 		if ((tdb->tdb_soft_timeout =
329 		    sadb_lifetime->sadb_lifetime_addtime) != 0) {
330 			tdb->tdb_flags |= TDBF_SOFT_TIMER;
331 		} else
332 			tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
333 
334 		if ((tdb->tdb_soft_first_use =
335 		    sadb_lifetime->sadb_lifetime_usetime) != 0)
336 			tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
337 		else
338 			tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
339 		break;
340 
341 	case PFKEYV2_LIFETIME_CURRENT:  /* Nothing fancy here. */
342 		tdb->tdb_cur_allocations =
343 		    sadb_lifetime->sadb_lifetime_allocations;
344 		tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
345 		tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
346 		tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
347 	}
348 	mtx_leave(&tdb->tdb_mtx);
349 }
350 
351 /*
352  * Export TDB expiration information.
353  */
354 void
export_lifetime(void ** p,struct tdb * tdb,int type)355 export_lifetime(void **p, struct tdb *tdb, int type)
356 {
357 	struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
358 
359 	sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
360 	    sizeof(uint64_t);
361 
362 	switch (type) {
363 	case PFKEYV2_LIFETIME_HARD:
364 		if (tdb->tdb_flags & TDBF_ALLOCATIONS)
365 			sadb_lifetime->sadb_lifetime_allocations =
366 			    tdb->tdb_exp_allocations;
367 
368 		if (tdb->tdb_flags & TDBF_BYTES)
369 			sadb_lifetime->sadb_lifetime_bytes =
370 			    tdb->tdb_exp_bytes;
371 
372 		if (tdb->tdb_flags & TDBF_TIMER)
373 			sadb_lifetime->sadb_lifetime_addtime =
374 			    tdb->tdb_exp_timeout;
375 
376 		if (tdb->tdb_flags & TDBF_FIRSTUSE)
377 			sadb_lifetime->sadb_lifetime_usetime =
378 			    tdb->tdb_exp_first_use;
379 		break;
380 
381 	case PFKEYV2_LIFETIME_SOFT:
382 		if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
383 			sadb_lifetime->sadb_lifetime_allocations =
384 			    tdb->tdb_soft_allocations;
385 
386 		if (tdb->tdb_flags & TDBF_SOFT_BYTES)
387 			sadb_lifetime->sadb_lifetime_bytes =
388 			    tdb->tdb_soft_bytes;
389 
390 		if (tdb->tdb_flags & TDBF_SOFT_TIMER)
391 			sadb_lifetime->sadb_lifetime_addtime =
392 			    tdb->tdb_soft_timeout;
393 
394 		if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
395 			sadb_lifetime->sadb_lifetime_usetime =
396 			    tdb->tdb_soft_first_use;
397 		break;
398 
399 	case PFKEYV2_LIFETIME_CURRENT:
400 		sadb_lifetime->sadb_lifetime_allocations =
401 		    tdb->tdb_cur_allocations;
402 		sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
403 		sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
404 		sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
405 		break;
406 
407 	case PFKEYV2_LIFETIME_LASTUSE:
408 		sadb_lifetime->sadb_lifetime_allocations = 0;
409 		sadb_lifetime->sadb_lifetime_bytes = 0;
410 		sadb_lifetime->sadb_lifetime_addtime = 0;
411 		sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used;
412 		break;
413 	}
414 
415 	*p += sizeof(struct sadb_lifetime);
416 }
417 
418 /*
419  * Import flow information to two struct sockaddr_encap's. Either
420  * all or none of the address arguments are NULL.
421  */
422 int
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)423 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
424     struct sadb_address *ssrc, struct sadb_address *ssrcmask,
425     struct sadb_address *ddst, struct sadb_address *ddstmask,
426     struct sadb_protocol *sab, struct sadb_protocol *ftype)
427 {
428 	u_int8_t transproto = 0;
429 	union sockaddr_union *src, *dst, *srcmask, *dstmask;
430 
431 	if (ssrc == NULL)
432 		return 0; /* There wasn't any information to begin with. */
433 
434 	src = (union sockaddr_union *)(ssrc + 1);
435 	dst = (union sockaddr_union *)(ddst + 1);
436 	srcmask = (union sockaddr_union *)(ssrcmask + 1);
437 	dstmask = (union sockaddr_union *)(ddstmask + 1);
438 
439 	bzero(flow, sizeof(*flow));
440 	bzero(flowmask, sizeof(*flowmask));
441 
442 	if (sab != NULL)
443 		transproto = sab->sadb_protocol_proto;
444 
445 	/*
446 	 * Check that all the address families match. We know they are
447 	 * valid and supported because pfkeyv2_parsemessage() checked that.
448 	 */
449 	if ((src->sa.sa_family != dst->sa.sa_family) ||
450 	    (src->sa.sa_family != srcmask->sa.sa_family) ||
451 	    (src->sa.sa_family != dstmask->sa.sa_family))
452 		return EINVAL;
453 
454 	/*
455 	 * We set these as an indication that tdb_filter/tdb_filtermask are
456 	 * in fact initialized.
457 	 */
458 	flow->sen_family = flowmask->sen_family = PF_KEY;
459 	flow->sen_len = flowmask->sen_len = SENT_LEN;
460 
461 	switch (src->sa.sa_family) {
462 	case AF_INET:
463 		/* netmask handling */
464 		rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
465 		rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
466 
467 		flow->sen_type = SENT_IP4;
468 		flow->sen_direction = ftype->sadb_protocol_direction;
469 		flow->sen_ip_src = src->sin.sin_addr;
470 		flow->sen_ip_dst = dst->sin.sin_addr;
471 		flow->sen_proto = transproto;
472 		flow->sen_sport = src->sin.sin_port;
473 		flow->sen_dport = dst->sin.sin_port;
474 
475 		flowmask->sen_type = SENT_IP4;
476 		flowmask->sen_direction = 0xff;
477 		flowmask->sen_ip_src = srcmask->sin.sin_addr;
478 		flowmask->sen_ip_dst = dstmask->sin.sin_addr;
479 		flowmask->sen_sport = srcmask->sin.sin_port;
480 		flowmask->sen_dport = dstmask->sin.sin_port;
481 		if (transproto)
482 			flowmask->sen_proto = 0xff;
483 		break;
484 
485 #ifdef INET6
486 	case AF_INET6:
487 		in6_embedscope(&src->sin6.sin6_addr, &src->sin6, NULL, NULL);
488 		in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6, NULL, NULL);
489 
490 		/* netmask handling */
491 		rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
492 		rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
493 
494 		flow->sen_type = SENT_IP6;
495 		flow->sen_ip6_direction = ftype->sadb_protocol_direction;
496 		flow->sen_ip6_src = src->sin6.sin6_addr;
497 		flow->sen_ip6_dst = dst->sin6.sin6_addr;
498 		flow->sen_ip6_proto = transproto;
499 		flow->sen_ip6_sport = src->sin6.sin6_port;
500 		flow->sen_ip6_dport = dst->sin6.sin6_port;
501 
502 		flowmask->sen_type = SENT_IP6;
503 		flowmask->sen_ip6_direction = 0xff;
504 		flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
505 		flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
506 		flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
507 		flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
508 		if (transproto)
509 			flowmask->sen_ip6_proto = 0xff;
510 		break;
511 #endif /* INET6 */
512 	}
513 
514 	return 0;
515 }
516 
517 /*
518  * Helper to export addresses from an struct sockaddr_encap.
519  */
520 static void
export_encap(void ** p,struct sockaddr_encap * encap,int type)521 export_encap(void **p, struct sockaddr_encap *encap, int type)
522 {
523 	struct sadb_address *saddr = (struct sadb_address *)*p;
524 	union sockaddr_union *sunion;
525 
526 	*p += sizeof(struct sadb_address);
527 	sunion = (union sockaddr_union *)*p;
528 
529 	switch (encap->sen_type) {
530 	case SENT_IP4:
531 		saddr->sadb_address_len = (sizeof(struct sadb_address) +
532 		    PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
533 		sunion->sa.sa_len = sizeof(struct sockaddr_in);
534 		sunion->sa.sa_family = AF_INET;
535 		if (type == SADB_X_EXT_SRC_FLOW ||
536 		    type == SADB_X_EXT_SRC_MASK) {
537 			sunion->sin.sin_addr = encap->sen_ip_src;
538 			sunion->sin.sin_port = encap->sen_sport;
539 		} else {
540 			sunion->sin.sin_addr = encap->sen_ip_dst;
541 			sunion->sin.sin_port = encap->sen_dport;
542 		}
543 		*p += PADUP(sizeof(struct sockaddr_in));
544 		break;
545 	case SENT_IP6:
546 		saddr->sadb_address_len = (sizeof(struct sadb_address)
547 		    + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
548 		sunion->sa.sa_len = sizeof(struct sockaddr_in6);
549 		sunion->sa.sa_family = AF_INET6;
550 		if (type == SADB_X_EXT_SRC_FLOW ||
551 		    type == SADB_X_EXT_SRC_MASK) {
552 			sunion->sin6.sin6_addr = encap->sen_ip6_src;
553 			sunion->sin6.sin6_port = encap->sen_ip6_sport;
554 		} else {
555 			sunion->sin6.sin6_addr = encap->sen_ip6_dst;
556 			sunion->sin6.sin6_port = encap->sen_ip6_dport;
557 		}
558 		*p += PADUP(sizeof(struct sockaddr_in6));
559 		break;
560 	}
561 }
562 
563 /*
564  * Export flow information from two struct sockaddr_encap's.
565  */
566 void
export_flow(void ** p,u_int8_t ftype,struct sockaddr_encap * flow,struct sockaddr_encap * flowmask,void ** headers)567 export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
568     struct sockaddr_encap *flowmask, void **headers)
569 {
570 	struct sadb_protocol *sab;
571 
572 	headers[SADB_X_EXT_FLOW_TYPE] = *p;
573 	sab = (struct sadb_protocol *)*p;
574 	sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
575 	    sizeof(uint64_t);
576 
577 	switch (ftype) {
578 	case IPSP_IPSEC_USE:
579 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
580 		break;
581 	case IPSP_IPSEC_ACQUIRE:
582 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
583 		break;
584 	case IPSP_IPSEC_REQUIRE:
585 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
586 		break;
587 	case IPSP_DENY:
588 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
589 		break;
590 	case IPSP_PERMIT:
591 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
592 		break;
593 	case IPSP_IPSEC_DONTACQ:
594 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
595 		break;
596 	default:
597 		sab->sadb_protocol_proto = 0;
598 		break;
599 	}
600 
601 	switch (flow->sen_type) {
602 	case SENT_IP4:
603 		sab->sadb_protocol_direction = flow->sen_direction;
604 		break;
605 #ifdef INET6
606 	case SENT_IP6:
607 		sab->sadb_protocol_direction = flow->sen_ip6_direction;
608 		break;
609 #endif /* INET6 */
610 	}
611 	*p += sizeof(struct sadb_protocol);
612 
613 	headers[SADB_X_EXT_PROTOCOL] = *p;
614 	sab = (struct sadb_protocol *)*p;
615 	sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
616 	    sizeof(uint64_t);
617 	switch (flow->sen_type) {
618 	case SENT_IP4:
619 		sab->sadb_protocol_proto = flow->sen_proto;
620 		break;
621 #ifdef INET6
622 	case SENT_IP6:
623 		sab->sadb_protocol_proto = flow->sen_ip6_proto;
624 		break;
625 #endif /* INET6 */
626 	}
627 	*p += sizeof(struct sadb_protocol);
628 
629 	headers[SADB_X_EXT_SRC_FLOW] = *p;
630 	export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
631 
632 	headers[SADB_X_EXT_SRC_MASK] = *p;
633 	export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
634 
635 	headers[SADB_X_EXT_DST_FLOW] = *p;
636 	export_encap(p, flow, SADB_X_EXT_DST_FLOW);
637 
638 	headers[SADB_X_EXT_DST_MASK] = *p;
639 	export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
640 }
641 
642 /*
643  * Copy an SADB_ADDRESS payload to a struct sockaddr.
644  */
645 void
import_address(struct sockaddr * sa,struct sadb_address * sadb_address)646 import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
647 {
648 	int salen;
649 	struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
650 	    sizeof(struct sadb_address));
651 
652 	if (!sadb_address)
653 		return;
654 
655 	if (ssa->sa_len)
656 		salen = ssa->sa_len;
657 	else
658 		switch (ssa->sa_family) {
659 		case AF_INET:
660 			salen = sizeof(struct sockaddr_in);
661 			break;
662 
663 #ifdef INET6
664 		case AF_INET6:
665 			salen = sizeof(struct sockaddr_in6);
666 			break;
667 #endif /* INET6 */
668 
669 		default:
670 			return;
671 		}
672 
673 	bcopy(ssa, sa, salen);
674 	sa->sa_len = salen;
675 }
676 
677 /*
678  * Export a struct sockaddr as an SADB_ADDRESS payload.
679  */
680 void
export_address(void ** p,struct sockaddr * sa)681 export_address(void **p, struct sockaddr *sa)
682 {
683 	struct sadb_address *sadb_address = (struct sadb_address *) *p;
684 
685 	sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
686 	    PADUP(sa->sa_len)) / sizeof(uint64_t);
687 
688 	*p += sizeof(struct sadb_address);
689 	bcopy(sa, *p, sa->sa_len);
690 	((struct sockaddr *) *p)->sa_family = sa->sa_family;
691 	*p += PADUP(sa->sa_len);
692 }
693 
694 /*
695  * Import an identity payload into the TDB.
696  */
697 static void
import_identity(struct ipsec_id ** id,struct sadb_ident * sadb_ident,size_t * id_sz)698 import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident,
699     size_t *id_sz)
700 {
701 	size_t id_len;
702 
703 	if (!sadb_ident) {
704 		*id = NULL;
705 		return;
706 	}
707 
708 	id_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
709 	*id_sz = sizeof(struct ipsec_id) + id_len;
710 	*id = malloc(*id_sz, M_CREDENTIALS, M_WAITOK);
711 	(*id)->len = id_len;
712 
713 	switch (sadb_ident->sadb_ident_type) {
714 	case SADB_IDENTTYPE_PREFIX:
715 		(*id)->type = IPSP_IDENTITY_PREFIX;
716 		break;
717 	case SADB_IDENTTYPE_FQDN:
718 		(*id)->type = IPSP_IDENTITY_FQDN;
719 		break;
720 	case SADB_IDENTTYPE_USERFQDN:
721 		(*id)->type = IPSP_IDENTITY_USERFQDN;
722 		break;
723 	case SADB_IDENTTYPE_ASN1_DN:
724 		(*id)->type = IPSP_IDENTITY_ASN1_DN;
725 		break;
726 	default:
727 		free(*id, M_CREDENTIALS, *id_sz);
728 		*id = NULL;
729 		return;
730 	}
731 	bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1,
732 	    (*id)->len);
733 }
734 
735 void
import_identities(struct ipsec_ids ** ids,int swapped,struct sadb_ident * srcid,struct sadb_ident * dstid)736 import_identities(struct ipsec_ids **ids, int swapped,
737     struct sadb_ident *srcid, struct sadb_ident *dstid)
738 {
739 	struct ipsec_ids *tmp;
740 	size_t id_local_sz, id_remote_sz;
741 
742 	*ids = NULL;
743 	tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS, M_WAITOK);
744 	import_identity(&tmp->id_local, swapped ? dstid: srcid, &id_local_sz);
745 	import_identity(&tmp->id_remote, swapped ? srcid: dstid, &id_remote_sz);
746 	if (tmp->id_local != NULL && tmp->id_remote != NULL) {
747 		*ids = ipsp_ids_insert(tmp);
748 		if (*ids == tmp)
749 			return;
750 	}
751 	free(tmp->id_local, M_CREDENTIALS, id_local_sz);
752 	free(tmp->id_remote, M_CREDENTIALS, id_remote_sz);
753 	free(tmp, M_CREDENTIALS, sizeof(*tmp));
754 }
755 
756 static void
export_identity(void ** p,struct ipsec_id * id)757 export_identity(void **p, struct ipsec_id *id)
758 {
759 	struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
760 
761 	sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
762 	    PADUP(id->len)) / sizeof(uint64_t);
763 
764 	switch (id->type) {
765 	case IPSP_IDENTITY_PREFIX:
766 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
767 		break;
768 	case IPSP_IDENTITY_FQDN:
769 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
770 		break;
771 	case IPSP_IDENTITY_USERFQDN:
772 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
773 		break;
774 	case IPSP_IDENTITY_ASN1_DN:
775 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_ASN1_DN;
776 		break;
777 	}
778 	*p += sizeof(struct sadb_ident);
779 	bcopy(id + 1, *p, id->len);
780 	*p += PADUP(id->len);
781 }
782 
783 void
export_identities(void ** p,struct ipsec_ids * ids,int swapped,void ** headers)784 export_identities(void **p, struct ipsec_ids *ids, int swapped,
785     void **headers)
786 {
787 	headers[SADB_EXT_IDENTITY_SRC] = *p;
788 	export_identity(p, swapped ? ids->id_remote : ids->id_local);
789 	headers[SADB_EXT_IDENTITY_DST] = *p;
790 	export_identity(p, swapped ? ids->id_local : ids->id_remote);
791 }
792 
793 /* ... */
794 void
import_key(struct ipsecinit * ii,struct sadb_key * sadb_key,int type)795 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
796 {
797 	if (!sadb_key)
798 		return;
799 
800 	if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
801 		ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
802 		ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
803 	} else {
804 		ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
805 		ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
806 	}
807 }
808 
809 void
export_key(void ** p,struct tdb * tdb,int type)810 export_key(void **p, struct tdb *tdb, int type)
811 {
812 	struct sadb_key *sadb_key = (struct sadb_key *) *p;
813 
814 	if (type == PFKEYV2_ENCRYPTION_KEY) {
815 		sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
816 		    PADUP(tdb->tdb_emxkeylen)) /
817 		    sizeof(uint64_t);
818 		sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
819 		*p += sizeof(struct sadb_key);
820 		bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
821 		*p += PADUP(tdb->tdb_emxkeylen);
822 	} else {
823 		sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
824 		    PADUP(tdb->tdb_amxkeylen)) /
825 		    sizeof(uint64_t);
826 		sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
827 		*p += sizeof(struct sadb_key);
828 		bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
829 		*p += PADUP(tdb->tdb_amxkeylen);
830 	}
831 }
832 
833 /* Import/Export remote port for UDP Encapsulation */
834 void
import_udpencap(struct tdb * tdb,struct sadb_x_udpencap * sadb_udpencap)835 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
836 {
837 	if (sadb_udpencap)
838 		tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
839 }
840 
841 void
export_udpencap(void ** p,struct tdb * tdb)842 export_udpencap(void **p, struct tdb *tdb)
843 {
844 	struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
845 
846 	sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
847 	sadb_udpencap->sadb_x_udpencap_reserved = 0;
848 	sadb_udpencap->sadb_x_udpencap_len =
849 	    sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
850 	*p += sizeof(struct sadb_x_udpencap);
851 }
852 
853 /* Export PF replay for SA */
854 void
export_replay(void ** p,struct tdb * tdb)855 export_replay(void **p, struct tdb *tdb)
856 {
857 	struct sadb_x_replay *sreplay = (struct sadb_x_replay *)*p;
858 
859 	sreplay->sadb_x_replay_count = tdb->tdb_rpl;
860 	sreplay->sadb_x_replay_len =
861 	    sizeof(struct sadb_x_replay) / sizeof(uint64_t);
862 	*p += sizeof(struct sadb_x_replay);
863 }
864 
865 /* Export mtu for SA */
866 void
export_mtu(void ** p,struct tdb * tdb)867 export_mtu(void **p, struct tdb *tdb)
868 {
869 	struct sadb_x_mtu *smtu = (struct sadb_x_mtu *)*p;
870 
871 	smtu->sadb_x_mtu_mtu = tdb->tdb_mtu;
872 	smtu->sadb_x_mtu_len =
873 	    sizeof(struct sadb_x_mtu) / sizeof(uint64_t);
874 	*p += sizeof(struct sadb_x_mtu);
875 }
876 
877 /* Import rdomain switch for SA */
878 void
import_rdomain(struct tdb * tdb,struct sadb_x_rdomain * srdomain)879 import_rdomain(struct tdb *tdb, struct sadb_x_rdomain *srdomain)
880 {
881 	if (srdomain)
882 		tdb->tdb_rdomain_post = srdomain->sadb_x_rdomain_dom2;
883 }
884 
885 /* Export rdomain switch for SA */
886 void
export_rdomain(void ** p,struct tdb * tdb)887 export_rdomain(void **p, struct tdb *tdb)
888 {
889 	struct sadb_x_rdomain *srdomain = (struct sadb_x_rdomain *)*p;
890 
891 	srdomain->sadb_x_rdomain_dom1 = tdb->tdb_rdomain;
892 	srdomain->sadb_x_rdomain_dom2 = tdb->tdb_rdomain_post;
893 	srdomain->sadb_x_rdomain_len =
894 	    sizeof(struct sadb_x_rdomain) / sizeof(uint64_t);
895 	*p += sizeof(struct sadb_x_rdomain);
896 }
897 
898 #if NPF > 0
899 /* Import PF tag information for SA */
900 void
import_tag(struct tdb * tdb,struct sadb_x_tag * stag)901 import_tag(struct tdb *tdb, struct sadb_x_tag *stag)
902 {
903 	char *s;
904 
905 	if (stag) {
906 		s = (char *)(stag + 1);
907 		tdb->tdb_tag = pf_tagname2tag(s, 1);
908 	}
909 }
910 
911 /* Export PF tag information for SA */
912 void
export_tag(void ** p,struct tdb * tdb)913 export_tag(void **p, struct tdb *tdb)
914 {
915 	struct sadb_x_tag *stag = (struct sadb_x_tag *)*p;
916 	char *s = (char *)(stag + 1);
917 
918 	pf_tag2tagname(tdb->tdb_tag, s);
919 
920 	stag->sadb_x_tag_taglen = strlen(s) + 1;
921 	stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) +
922 	    PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
923 	*p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen);
924 }
925 
926 /* Import enc(4) tap device information for SA */
927 void
import_tap(struct tdb * tdb,struct sadb_x_tap * stap)928 import_tap(struct tdb *tdb, struct sadb_x_tap *stap)
929 {
930 	if (stap)
931 		tdb->tdb_tap = stap->sadb_x_tap_unit;
932 }
933 
934 /* Export enc(4) tap device information for SA */
935 void
export_tap(void ** p,struct tdb * tdb)936 export_tap(void **p, struct tdb *tdb)
937 {
938 	struct sadb_x_tap *stag = (struct sadb_x_tap *)*p;
939 
940 	stag->sadb_x_tap_unit = tdb->tdb_tap;
941 	stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t);
942 	*p += sizeof(struct sadb_x_tap);
943 }
944 #endif
945 
946 /* Import interface information for SA */
947 void
import_iface(struct tdb * tdb,struct sadb_x_iface * siface)948 import_iface(struct tdb *tdb, struct sadb_x_iface *siface)
949 {
950 	if (siface != NULL) {
951 		SET(tdb->tdb_flags, TDBF_IFACE);
952 		tdb->tdb_iface = siface->sadb_x_iface_unit;
953 		tdb->tdb_iface_dir = siface->sadb_x_iface_direction;
954 	}
955 }
956 
957 /* Export interface information for SA */
958 void
export_iface(void ** p,struct tdb * tdb)959 export_iface(void **p, struct tdb *tdb)
960 {
961 	struct sadb_x_iface *siface = (struct sadb_x_iface *)*p;
962 
963 	siface->sadb_x_iface_len = sizeof(*siface) / sizeof(uint64_t);
964 	siface->sadb_x_iface_unit = tdb->tdb_iface;
965 	siface->sadb_x_iface_direction = tdb->tdb_iface_dir;
966 
967 	*p += sizeof(*siface);
968 }
969 
970 void
export_satype(void ** p,struct tdb * tdb)971 export_satype(void **p, struct tdb *tdb)
972 {
973 	struct sadb_protocol *sab = *p;
974 
975 	sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
976 	    sizeof(uint64_t);
977 	sab->sadb_protocol_proto = tdb->tdb_satype;
978 	*p += sizeof(struct sadb_protocol);
979 }
980 
981 void
export_counter(void ** p,struct tdb * tdb)982 export_counter(void **p, struct tdb *tdb)
983 {
984 	uint64_t counters[tdb_ncounters];
985 	struct sadb_x_counter *scnt = (struct sadb_x_counter *)*p;
986 
987 	counters_read(tdb->tdb_counters, counters, tdb_ncounters, NULL);
988 
989 	scnt->sadb_x_counter_len = sizeof(struct sadb_x_counter) /
990 	    sizeof(uint64_t);
991 	scnt->sadb_x_counter_pad = 0;
992 	scnt->sadb_x_counter_ipackets = counters[tdb_ipackets];
993 	scnt->sadb_x_counter_opackets = counters[tdb_opackets];
994 	scnt->sadb_x_counter_ibytes = counters[tdb_ibytes];
995 	scnt->sadb_x_counter_obytes = counters[tdb_obytes];
996 	scnt->sadb_x_counter_idrops = counters[tdb_idrops];
997 	scnt->sadb_x_counter_odrops = counters[tdb_odrops];
998 	scnt->sadb_x_counter_idecompbytes = counters[tdb_idecompbytes];
999 	scnt->sadb_x_counter_ouncompbytes = counters[tdb_ouncompbytes];
1000 	*p += sizeof(struct sadb_x_counter);
1001 }
1002