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