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