1 /* $OpenBSD: pfkeyv2_convert.c,v 1.77 2021/12/11 16:33:46 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 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 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 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 if (timeout_add_sec(&tdb->tdb_timer_tmo, 306 tdb->tdb_exp_timeout)) 307 tdb_ref(tdb); 308 } else 309 tdb->tdb_flags &= ~TDBF_TIMER; 310 311 if ((tdb->tdb_exp_first_use = 312 sadb_lifetime->sadb_lifetime_usetime) != 0) 313 tdb->tdb_flags |= TDBF_FIRSTUSE; 314 else 315 tdb->tdb_flags &= ~TDBF_FIRSTUSE; 316 break; 317 318 case PFKEYV2_LIFETIME_SOFT: 319 if ((tdb->tdb_soft_allocations = 320 sadb_lifetime->sadb_lifetime_allocations) != 0) 321 tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS; 322 else 323 tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS; 324 325 if ((tdb->tdb_soft_bytes = 326 sadb_lifetime->sadb_lifetime_bytes) != 0) 327 tdb->tdb_flags |= TDBF_SOFT_BYTES; 328 else 329 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; 330 331 if ((tdb->tdb_soft_timeout = 332 sadb_lifetime->sadb_lifetime_addtime) != 0) { 333 tdb->tdb_flags |= TDBF_SOFT_TIMER; 334 if (timeout_add_sec(&tdb->tdb_stimer_tmo, 335 tdb->tdb_soft_timeout)) 336 tdb_ref(tdb); 337 } else 338 tdb->tdb_flags &= ~TDBF_SOFT_TIMER; 339 340 if ((tdb->tdb_soft_first_use = 341 sadb_lifetime->sadb_lifetime_usetime) != 0) 342 tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE; 343 else 344 tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; 345 break; 346 347 case PFKEYV2_LIFETIME_CURRENT: /* Nothing fancy here. */ 348 tdb->tdb_cur_allocations = 349 sadb_lifetime->sadb_lifetime_allocations; 350 tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes; 351 tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; 352 tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; 353 } 354 mtx_leave(&tdb->tdb_mtx); 355 } 356 357 /* 358 * Export TDB expiration information. 359 */ 360 void 361 export_lifetime(void **p, struct tdb *tdb, int type) 362 { 363 struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p; 364 365 sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / 366 sizeof(uint64_t); 367 368 switch (type) { 369 case PFKEYV2_LIFETIME_HARD: 370 if (tdb->tdb_flags & TDBF_ALLOCATIONS) 371 sadb_lifetime->sadb_lifetime_allocations = 372 tdb->tdb_exp_allocations; 373 374 if (tdb->tdb_flags & TDBF_BYTES) 375 sadb_lifetime->sadb_lifetime_bytes = 376 tdb->tdb_exp_bytes; 377 378 if (tdb->tdb_flags & TDBF_TIMER) 379 sadb_lifetime->sadb_lifetime_addtime = 380 tdb->tdb_exp_timeout; 381 382 if (tdb->tdb_flags & TDBF_FIRSTUSE) 383 sadb_lifetime->sadb_lifetime_usetime = 384 tdb->tdb_exp_first_use; 385 break; 386 387 case PFKEYV2_LIFETIME_SOFT: 388 if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS) 389 sadb_lifetime->sadb_lifetime_allocations = 390 tdb->tdb_soft_allocations; 391 392 if (tdb->tdb_flags & TDBF_SOFT_BYTES) 393 sadb_lifetime->sadb_lifetime_bytes = 394 tdb->tdb_soft_bytes; 395 396 if (tdb->tdb_flags & TDBF_SOFT_TIMER) 397 sadb_lifetime->sadb_lifetime_addtime = 398 tdb->tdb_soft_timeout; 399 400 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) 401 sadb_lifetime->sadb_lifetime_usetime = 402 tdb->tdb_soft_first_use; 403 break; 404 405 case PFKEYV2_LIFETIME_CURRENT: 406 sadb_lifetime->sadb_lifetime_allocations = 407 tdb->tdb_cur_allocations; 408 sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes; 409 sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established; 410 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use; 411 break; 412 413 case PFKEYV2_LIFETIME_LASTUSE: 414 sadb_lifetime->sadb_lifetime_allocations = 0; 415 sadb_lifetime->sadb_lifetime_bytes = 0; 416 sadb_lifetime->sadb_lifetime_addtime = 0; 417 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used; 418 break; 419 } 420 421 *p += sizeof(struct sadb_lifetime); 422 } 423 424 /* 425 * Import flow information to two struct sockaddr_encap's. Either 426 * all or none of the address arguments are NULL. 427 */ 428 int 429 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask, 430 struct sadb_address *ssrc, struct sadb_address *ssrcmask, 431 struct sadb_address *ddst, struct sadb_address *ddstmask, 432 struct sadb_protocol *sab, struct sadb_protocol *ftype) 433 { 434 u_int8_t transproto = 0; 435 union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1); 436 union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1); 437 union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1); 438 union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1); 439 440 if (ssrc == NULL) 441 return 0; /* There wasn't any information to begin with. */ 442 443 bzero(flow, sizeof(*flow)); 444 bzero(flowmask, sizeof(*flowmask)); 445 446 if (sab != NULL) 447 transproto = sab->sadb_protocol_proto; 448 449 /* 450 * Check that all the address families match. We know they are 451 * valid and supported because pfkeyv2_parsemessage() checked that. 452 */ 453 if ((src->sa.sa_family != dst->sa.sa_family) || 454 (src->sa.sa_family != srcmask->sa.sa_family) || 455 (src->sa.sa_family != dstmask->sa.sa_family)) 456 return EINVAL; 457 458 /* 459 * We set these as an indication that tdb_filter/tdb_filtermask are 460 * in fact initialized. 461 */ 462 flow->sen_family = flowmask->sen_family = PF_KEY; 463 flow->sen_len = flowmask->sen_len = SENT_LEN; 464 465 switch (src->sa.sa_family) { 466 case AF_INET: 467 /* netmask handling */ 468 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); 469 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); 470 471 flow->sen_type = SENT_IP4; 472 flow->sen_direction = ftype->sadb_protocol_direction; 473 flow->sen_ip_src = src->sin.sin_addr; 474 flow->sen_ip_dst = dst->sin.sin_addr; 475 flow->sen_proto = transproto; 476 flow->sen_sport = src->sin.sin_port; 477 flow->sen_dport = dst->sin.sin_port; 478 479 flowmask->sen_type = SENT_IP4; 480 flowmask->sen_direction = 0xff; 481 flowmask->sen_ip_src = srcmask->sin.sin_addr; 482 flowmask->sen_ip_dst = dstmask->sin.sin_addr; 483 flowmask->sen_sport = srcmask->sin.sin_port; 484 flowmask->sen_dport = dstmask->sin.sin_port; 485 if (transproto) 486 flowmask->sen_proto = 0xff; 487 break; 488 489 #ifdef INET6 490 case AF_INET6: 491 in6_embedscope(&src->sin6.sin6_addr, &src->sin6, 492 NULL); 493 in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6, 494 NULL); 495 496 /* netmask handling */ 497 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); 498 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); 499 500 flow->sen_type = SENT_IP6; 501 flow->sen_ip6_direction = ftype->sadb_protocol_direction; 502 flow->sen_ip6_src = src->sin6.sin6_addr; 503 flow->sen_ip6_dst = dst->sin6.sin6_addr; 504 flow->sen_ip6_proto = transproto; 505 flow->sen_ip6_sport = src->sin6.sin6_port; 506 flow->sen_ip6_dport = dst->sin6.sin6_port; 507 508 flowmask->sen_type = SENT_IP6; 509 flowmask->sen_ip6_direction = 0xff; 510 flowmask->sen_ip6_src = srcmask->sin6.sin6_addr; 511 flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr; 512 flowmask->sen_ip6_sport = srcmask->sin6.sin6_port; 513 flowmask->sen_ip6_dport = dstmask->sin6.sin6_port; 514 if (transproto) 515 flowmask->sen_ip6_proto = 0xff; 516 break; 517 #endif /* INET6 */ 518 } 519 520 return 0; 521 } 522 523 /* 524 * Helper to export addresses from an struct sockaddr_encap. 525 */ 526 static void 527 export_encap(void **p, struct sockaddr_encap *encap, int type) 528 { 529 struct sadb_address *saddr = (struct sadb_address *)*p; 530 union sockaddr_union *sunion; 531 532 *p += sizeof(struct sadb_address); 533 sunion = (union sockaddr_union *)*p; 534 535 switch (encap->sen_type) { 536 case SENT_IP4: 537 saddr->sadb_address_len = (sizeof(struct sadb_address) + 538 PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t); 539 sunion->sa.sa_len = sizeof(struct sockaddr_in); 540 sunion->sa.sa_family = AF_INET; 541 if (type == SADB_X_EXT_SRC_FLOW || 542 type == SADB_X_EXT_SRC_MASK) { 543 sunion->sin.sin_addr = encap->sen_ip_src; 544 sunion->sin.sin_port = encap->sen_sport; 545 } else { 546 sunion->sin.sin_addr = encap->sen_ip_dst; 547 sunion->sin.sin_port = encap->sen_dport; 548 } 549 *p += PADUP(sizeof(struct sockaddr_in)); 550 break; 551 case SENT_IP6: 552 saddr->sadb_address_len = (sizeof(struct sadb_address) 553 + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t); 554 sunion->sa.sa_len = sizeof(struct sockaddr_in6); 555 sunion->sa.sa_family = AF_INET6; 556 if (type == SADB_X_EXT_SRC_FLOW || 557 type == SADB_X_EXT_SRC_MASK) { 558 sunion->sin6.sin6_addr = encap->sen_ip6_src; 559 sunion->sin6.sin6_port = encap->sen_ip6_sport; 560 } else { 561 sunion->sin6.sin6_addr = encap->sen_ip6_dst; 562 sunion->sin6.sin6_port = encap->sen_ip6_dport; 563 } 564 *p += PADUP(sizeof(struct sockaddr_in6)); 565 break; 566 } 567 } 568 569 /* 570 * Export flow information from two struct sockaddr_encap's. 571 */ 572 void 573 export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow, 574 struct sockaddr_encap *flowmask, void **headers) 575 { 576 struct sadb_protocol *sab; 577 578 headers[SADB_X_EXT_FLOW_TYPE] = *p; 579 sab = (struct sadb_protocol *)*p; 580 sab->sadb_protocol_len = sizeof(struct sadb_protocol) / 581 sizeof(uint64_t); 582 583 switch (ftype) { 584 case IPSP_IPSEC_USE: 585 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE; 586 break; 587 case IPSP_IPSEC_ACQUIRE: 588 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE; 589 break; 590 case IPSP_IPSEC_REQUIRE: 591 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE; 592 break; 593 case IPSP_DENY: 594 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY; 595 break; 596 case IPSP_PERMIT: 597 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS; 598 break; 599 case IPSP_IPSEC_DONTACQ: 600 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ; 601 break; 602 default: 603 sab->sadb_protocol_proto = 0; 604 break; 605 } 606 607 switch (flow->sen_type) { 608 case SENT_IP4: 609 sab->sadb_protocol_direction = flow->sen_direction; 610 break; 611 #ifdef INET6 612 case SENT_IP6: 613 sab->sadb_protocol_direction = flow->sen_ip6_direction; 614 break; 615 #endif /* INET6 */ 616 } 617 *p += sizeof(struct sadb_protocol); 618 619 headers[SADB_X_EXT_PROTOCOL] = *p; 620 sab = (struct sadb_protocol *)*p; 621 sab->sadb_protocol_len = sizeof(struct sadb_protocol) / 622 sizeof(uint64_t); 623 switch (flow->sen_type) { 624 case SENT_IP4: 625 sab->sadb_protocol_proto = flow->sen_proto; 626 break; 627 #ifdef INET6 628 case SENT_IP6: 629 sab->sadb_protocol_proto = flow->sen_ip6_proto; 630 break; 631 #endif /* INET6 */ 632 } 633 *p += sizeof(struct sadb_protocol); 634 635 headers[SADB_X_EXT_SRC_FLOW] = *p; 636 export_encap(p, flow, SADB_X_EXT_SRC_FLOW); 637 638 headers[SADB_X_EXT_SRC_MASK] = *p; 639 export_encap(p, flowmask, SADB_X_EXT_SRC_MASK); 640 641 headers[SADB_X_EXT_DST_FLOW] = *p; 642 export_encap(p, flow, SADB_X_EXT_DST_FLOW); 643 644 headers[SADB_X_EXT_DST_MASK] = *p; 645 export_encap(p, flowmask, SADB_X_EXT_DST_MASK); 646 } 647 648 /* 649 * Copy an SADB_ADDRESS payload to a struct sockaddr. 650 */ 651 void 652 import_address(struct sockaddr *sa, struct sadb_address *sadb_address) 653 { 654 int salen; 655 struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address + 656 sizeof(struct sadb_address)); 657 658 if (!sadb_address) 659 return; 660 661 if (ssa->sa_len) 662 salen = ssa->sa_len; 663 else 664 switch (ssa->sa_family) { 665 case AF_INET: 666 salen = sizeof(struct sockaddr_in); 667 break; 668 669 #ifdef INET6 670 case AF_INET6: 671 salen = sizeof(struct sockaddr_in6); 672 break; 673 #endif /* INET6 */ 674 675 default: 676 return; 677 } 678 679 bcopy(ssa, sa, salen); 680 sa->sa_len = salen; 681 } 682 683 /* 684 * Export a struct sockaddr as an SADB_ADDRESS payload. 685 */ 686 void 687 export_address(void **p, struct sockaddr *sa) 688 { 689 struct sadb_address *sadb_address = (struct sadb_address *) *p; 690 691 sadb_address->sadb_address_len = (sizeof(struct sadb_address) + 692 PADUP(sa->sa_len)) / sizeof(uint64_t); 693 694 *p += sizeof(struct sadb_address); 695 bcopy(sa, *p, sa->sa_len); 696 ((struct sockaddr *) *p)->sa_family = sa->sa_family; 697 *p += PADUP(sa->sa_len); 698 } 699 700 /* 701 * Import an identity payload into the TDB. 702 */ 703 static void 704 import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident, 705 size_t *id_sz) 706 { 707 size_t id_len; 708 709 if (!sadb_ident) { 710 *id = NULL; 711 return; 712 } 713 714 id_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident); 715 *id_sz = sizeof(struct ipsec_id) + id_len; 716 *id = malloc(*id_sz, M_CREDENTIALS, M_WAITOK); 717 (*id)->len = id_len; 718 719 switch (sadb_ident->sadb_ident_type) { 720 case SADB_IDENTTYPE_PREFIX: 721 (*id)->type = IPSP_IDENTITY_PREFIX; 722 break; 723 case SADB_IDENTTYPE_FQDN: 724 (*id)->type = IPSP_IDENTITY_FQDN; 725 break; 726 case SADB_IDENTTYPE_USERFQDN: 727 (*id)->type = IPSP_IDENTITY_USERFQDN; 728 break; 729 case SADB_IDENTTYPE_ASN1_DN: 730 (*id)->type = IPSP_IDENTITY_ASN1_DN; 731 break; 732 default: 733 free(*id, M_CREDENTIALS, *id_sz); 734 *id = NULL; 735 return; 736 } 737 bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1, 738 (*id)->len); 739 } 740 741 void 742 import_identities(struct ipsec_ids **ids, int swapped, 743 struct sadb_ident *srcid, struct sadb_ident *dstid) 744 { 745 struct ipsec_ids *tmp; 746 size_t id_local_sz, id_remote_sz; 747 748 *ids = NULL; 749 tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS, M_WAITOK); 750 import_identity(&tmp->id_local, swapped ? dstid: srcid, &id_local_sz); 751 import_identity(&tmp->id_remote, swapped ? srcid: dstid, &id_remote_sz); 752 if (tmp->id_local != NULL && tmp->id_remote != NULL) { 753 *ids = ipsp_ids_insert(tmp); 754 if (*ids == tmp) 755 return; 756 } 757 free(tmp->id_local, M_CREDENTIALS, id_local_sz); 758 free(tmp->id_remote, M_CREDENTIALS, id_remote_sz); 759 free(tmp, M_CREDENTIALS, sizeof(*tmp)); 760 } 761 762 static void 763 export_identity(void **p, struct ipsec_id *id) 764 { 765 struct sadb_ident *sadb_ident = (struct sadb_ident *) *p; 766 767 sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) + 768 PADUP(id->len)) / sizeof(uint64_t); 769 770 switch (id->type) { 771 case IPSP_IDENTITY_PREFIX: 772 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX; 773 break; 774 case IPSP_IDENTITY_FQDN: 775 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN; 776 break; 777 case IPSP_IDENTITY_USERFQDN: 778 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN; 779 break; 780 case IPSP_IDENTITY_ASN1_DN: 781 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_ASN1_DN; 782 break; 783 } 784 *p += sizeof(struct sadb_ident); 785 bcopy(id + 1, *p, id->len); 786 *p += PADUP(id->len); 787 } 788 789 void 790 export_identities(void **p, struct ipsec_ids *ids, int swapped, 791 void **headers) 792 { 793 headers[SADB_EXT_IDENTITY_SRC] = *p; 794 export_identity(p, swapped ? ids->id_remote : ids->id_local); 795 headers[SADB_EXT_IDENTITY_DST] = *p; 796 export_identity(p, swapped ? ids->id_local : ids->id_remote); 797 } 798 799 /* ... */ 800 void 801 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type) 802 { 803 if (!sadb_key) 804 return; 805 806 if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */ 807 ii->ii_enckeylen = sadb_key->sadb_key_bits / 8; 808 ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key); 809 } else { 810 ii->ii_authkeylen = sadb_key->sadb_key_bits / 8; 811 ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key); 812 } 813 } 814 815 void 816 export_key(void **p, struct tdb *tdb, int type) 817 { 818 struct sadb_key *sadb_key = (struct sadb_key *) *p; 819 820 if (type == PFKEYV2_ENCRYPTION_KEY) { 821 sadb_key->sadb_key_len = (sizeof(struct sadb_key) + 822 PADUP(tdb->tdb_emxkeylen)) / 823 sizeof(uint64_t); 824 sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8; 825 *p += sizeof(struct sadb_key); 826 bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen); 827 *p += PADUP(tdb->tdb_emxkeylen); 828 } else { 829 sadb_key->sadb_key_len = (sizeof(struct sadb_key) + 830 PADUP(tdb->tdb_amxkeylen)) / 831 sizeof(uint64_t); 832 sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8; 833 *p += sizeof(struct sadb_key); 834 bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen); 835 *p += PADUP(tdb->tdb_amxkeylen); 836 } 837 } 838 839 /* Import/Export remote port for UDP Encapsulation */ 840 void 841 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap) 842 { 843 if (sadb_udpencap) 844 tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port; 845 } 846 847 void 848 export_udpencap(void **p, struct tdb *tdb) 849 { 850 struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p; 851 852 sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port; 853 sadb_udpencap->sadb_x_udpencap_reserved = 0; 854 sadb_udpencap->sadb_x_udpencap_len = 855 sizeof(struct sadb_x_udpencap) / sizeof(uint64_t); 856 *p += sizeof(struct sadb_x_udpencap); 857 } 858 859 /* Export PF replay for SA */ 860 void 861 export_replay(void **p, struct tdb *tdb) 862 { 863 struct sadb_x_replay *sreplay = (struct sadb_x_replay *)*p; 864 865 sreplay->sadb_x_replay_count = tdb->tdb_rpl; 866 sreplay->sadb_x_replay_len = 867 sizeof(struct sadb_x_replay) / sizeof(uint64_t); 868 *p += sizeof(struct sadb_x_replay); 869 } 870 871 /* Export mtu for SA */ 872 void 873 export_mtu(void **p, struct tdb *tdb) 874 { 875 struct sadb_x_mtu *smtu = (struct sadb_x_mtu *)*p; 876 877 smtu->sadb_x_mtu_mtu = tdb->tdb_mtu; 878 smtu->sadb_x_mtu_len = 879 sizeof(struct sadb_x_mtu) / sizeof(uint64_t); 880 *p += sizeof(struct sadb_x_mtu); 881 } 882 883 /* Import rdomain switch for SA */ 884 void 885 import_rdomain(struct tdb *tdb, struct sadb_x_rdomain *srdomain) 886 { 887 if (srdomain) 888 tdb->tdb_rdomain_post = srdomain->sadb_x_rdomain_dom2; 889 } 890 891 /* Export rdomain switch for SA */ 892 void 893 export_rdomain(void **p, struct tdb *tdb) 894 { 895 struct sadb_x_rdomain *srdomain = (struct sadb_x_rdomain *)*p; 896 897 srdomain->sadb_x_rdomain_dom1 = tdb->tdb_rdomain; 898 srdomain->sadb_x_rdomain_dom2 = tdb->tdb_rdomain_post; 899 srdomain->sadb_x_rdomain_len = 900 sizeof(struct sadb_x_rdomain) / sizeof(uint64_t); 901 *p += sizeof(struct sadb_x_rdomain); 902 } 903 904 #if NPF > 0 905 /* Import PF tag information for SA */ 906 void 907 import_tag(struct tdb *tdb, struct sadb_x_tag *stag) 908 { 909 char *s; 910 911 if (stag) { 912 s = (char *)(stag + 1); 913 tdb->tdb_tag = pf_tagname2tag(s, 1); 914 } 915 } 916 917 /* Export PF tag information for SA */ 918 void 919 export_tag(void **p, struct tdb *tdb) 920 { 921 struct sadb_x_tag *stag = (struct sadb_x_tag *)*p; 922 char *s = (char *)(stag + 1); 923 924 pf_tag2tagname(tdb->tdb_tag, s); 925 926 stag->sadb_x_tag_taglen = strlen(s) + 1; 927 stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) + 928 PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t); 929 *p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen); 930 } 931 932 /* Import enc(4) tap device information for SA */ 933 void 934 import_tap(struct tdb *tdb, struct sadb_x_tap *stap) 935 { 936 if (stap) 937 tdb->tdb_tap = stap->sadb_x_tap_unit; 938 } 939 940 /* Export enc(4) tap device information for SA */ 941 void 942 export_tap(void **p, struct tdb *tdb) 943 { 944 struct sadb_x_tap *stag = (struct sadb_x_tap *)*p; 945 946 stag->sadb_x_tap_unit = tdb->tdb_tap; 947 stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t); 948 *p += sizeof(struct sadb_x_tap); 949 } 950 #endif 951 952 void 953 export_satype(void **p, struct tdb *tdb) 954 { 955 struct sadb_protocol *sab = *p; 956 957 sab->sadb_protocol_len = sizeof(struct sadb_protocol) / 958 sizeof(uint64_t); 959 sab->sadb_protocol_proto = tdb->tdb_satype; 960 *p += sizeof(struct sadb_protocol); 961 } 962 963 void 964 export_counter(void **p, struct tdb *tdb) 965 { 966 struct sadb_x_counter *scnt = (struct sadb_x_counter *)*p; 967 968 scnt->sadb_x_counter_len = sizeof(struct sadb_x_counter) / 969 sizeof(uint64_t); 970 scnt->sadb_x_counter_pad = 0; 971 scnt->sadb_x_counter_ipackets = tdb->tdb_ipackets; 972 scnt->sadb_x_counter_opackets = tdb->tdb_opackets; 973 scnt->sadb_x_counter_ibytes = tdb->tdb_ibytes; 974 scnt->sadb_x_counter_obytes = tdb->tdb_obytes; 975 scnt->sadb_x_counter_idrops = tdb->tdb_idrops; 976 scnt->sadb_x_counter_odrops = tdb->tdb_odrops; 977 scnt->sadb_x_counter_idecompbytes = tdb->tdb_idecompbytes; 978 scnt->sadb_x_counter_ouncompbytes = tdb->tdb_ouncompbytes; 979 *p += sizeof(struct sadb_x_counter); 980 } 981