1 /* $OpenBSD: ip_ah.c,v 1.146 2021/02/25 02:48:21 dlg Exp $ */ 2 /* 3 * The authors of this code are John Ioannidis (ji@tla.org), 4 * Angelos D. Keromytis (kermit@csd.uch.gr) and 5 * Niels Provos (provos@physnet.uni-hamburg.de). 6 * 7 * The original version of this code was written by John Ioannidis 8 * for BSD/OS in Athens, Greece, in November 1995. 9 * 10 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 11 * by Angelos D. Keromytis. 12 * 13 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 14 * and Niels Provos. 15 * 16 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. 17 * 18 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 19 * Angelos D. Keromytis and Niels Provos. 20 * Copyright (c) 1999 Niklas Hallqvist. 21 * Copyright (c) 2001 Angelos D. Keromytis. 22 * 23 * Permission to use, copy, and modify this software with or without fee 24 * is hereby granted, provided that this entire notice is included in 25 * all copies of any software which is or includes a copy or 26 * modification of this software. 27 * You may use this code under the GNU public license if you so wish. Please 28 * contribute changes back to the authors under this freer than GPL license 29 * so that we may further the use of strong encryption without limitations to 30 * all. 31 * 32 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 33 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 34 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 35 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 36 * PURPOSE. 37 */ 38 39 #include "pfsync.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/mbuf.h> 44 #include <sys/socket.h> 45 46 #include <net/if.h> 47 #include <net/if_var.h> 48 #include <net/bpf.h> 49 50 #include <netinet/in.h> 51 #include <netinet/ip.h> 52 #include <netinet/ip_var.h> 53 54 #ifdef INET6 55 #include <netinet/ip6.h> 56 #endif /* INET6 */ 57 58 #include <netinet/ip_ipsp.h> 59 #include <netinet/ip_ah.h> 60 #include <net/pfkeyv2.h> 61 #include <net/if_enc.h> 62 63 #if NPFSYNC > 0 64 #include <net/pfvar.h> 65 #include <net/if_pfsync.h> 66 #endif /* NPFSYNC > 0 */ 67 68 #include <crypto/cryptodev.h> 69 #include <crypto/xform.h> 70 71 #include "bpfilter.h" 72 73 #ifdef ENCDEBUG 74 #define DPRINTF(x) if (encdebug) printf x 75 #else 76 #define DPRINTF(x) 77 #endif 78 79 int ah_massage_headers(struct mbuf **, int, int, int, int); 80 81 const unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */ 82 83 84 /* 85 * ah_attach() is called from the transformation initialization code. 86 */ 87 int 88 ah_attach(void) 89 { 90 return 0; 91 } 92 93 /* 94 * ah_init() is called when an SPI is being set up. 95 */ 96 int 97 ah_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) 98 { 99 struct auth_hash *thash = NULL; 100 struct cryptoini cria, crin; 101 102 /* Authentication operation. */ 103 switch (ii->ii_authalg) { 104 case SADB_AALG_MD5HMAC: 105 thash = &auth_hash_hmac_md5_96; 106 break; 107 108 case SADB_AALG_SHA1HMAC: 109 thash = &auth_hash_hmac_sha1_96; 110 break; 111 112 case SADB_X_AALG_RIPEMD160HMAC: 113 thash = &auth_hash_hmac_ripemd_160_96; 114 break; 115 116 case SADB_X_AALG_SHA2_256: 117 thash = &auth_hash_hmac_sha2_256_128; 118 break; 119 120 case SADB_X_AALG_SHA2_384: 121 thash = &auth_hash_hmac_sha2_384_192; 122 break; 123 124 case SADB_X_AALG_SHA2_512: 125 thash = &auth_hash_hmac_sha2_512_256; 126 break; 127 128 default: 129 DPRINTF(("%s: unsupported authentication algorithm %d" 130 " specified\n", __func__, ii->ii_authalg)); 131 return EINVAL; 132 } 133 134 if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) { 135 DPRINTF(("ah_init(): keylength %d doesn't match algorithm " 136 "%s keysize (%d)\n", ii->ii_authkeylen, thash->name, 137 thash->keysize)); 138 return EINVAL; 139 } 140 141 tdbp->tdb_xform = xsp; 142 tdbp->tdb_authalgxform = thash; 143 tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL; 144 145 DPRINTF(("%s: initialized TDB with hash algorithm %s\n", __func__, 146 thash->name)); 147 148 tdbp->tdb_amxkeylen = ii->ii_authkeylen; 149 tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA, M_WAITOK); 150 151 memcpy(tdbp->tdb_amxkey, ii->ii_authkey, tdbp->tdb_amxkeylen); 152 153 /* Initialize crypto session. */ 154 memset(&cria, 0, sizeof(cria)); 155 cria.cri_alg = tdbp->tdb_authalgxform->type; 156 cria.cri_klen = ii->ii_authkeylen * 8; 157 cria.cri_key = ii->ii_authkey; 158 159 if ((tdbp->tdb_wnd > 0) && (tdbp->tdb_flags & TDBF_ESN)) { 160 memset(&crin, 0, sizeof(crin)); 161 crin.cri_alg = CRYPTO_ESN; 162 cria.cri_next = &crin; 163 } 164 165 return crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0); 166 } 167 168 /* 169 * Paranoia. 170 */ 171 int 172 ah_zeroize(struct tdb *tdbp) 173 { 174 int err; 175 176 if (tdbp->tdb_amxkey) { 177 explicit_bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen); 178 free(tdbp->tdb_amxkey, M_XDATA, tdbp->tdb_amxkeylen); 179 tdbp->tdb_amxkey = NULL; 180 } 181 182 err = crypto_freesession(tdbp->tdb_cryptoid); 183 tdbp->tdb_cryptoid = 0; 184 return err; 185 } 186 187 /* 188 * Massage IPv4/IPv6 headers for AH processing. 189 */ 190 int 191 ah_massage_headers(struct mbuf **m0, int af, int skip, int alg, int out) 192 { 193 struct mbuf *m = *m0; 194 unsigned char *ptr; 195 int off, count; 196 struct ip *ip; 197 #ifdef INET6 198 struct ip6_ext *ip6e; 199 struct ip6_hdr ip6; 200 int ad, alloc, nxt, noff, error; 201 #endif /* INET6 */ 202 203 switch (af) { 204 case AF_INET: 205 /* 206 * This is the least painful way of dealing with IPv4 header 207 * and option processing -- just make sure they're in 208 * contiguous memory. 209 */ 210 *m0 = m = m_pullup(m, skip); 211 if (m == NULL) { 212 DPRINTF(("%s: m_pullup() failed\n", __func__)); 213 ahstat_inc(ahs_hdrops); 214 return ENOBUFS; 215 } 216 217 /* Fix the IP header */ 218 ip = mtod(m, struct ip *); 219 ip->ip_tos = 0; 220 ip->ip_ttl = 0; 221 ip->ip_sum = 0; 222 ip->ip_off = 0; 223 224 ptr = mtod(m, unsigned char *); 225 226 /* IPv4 option processing */ 227 for (off = sizeof(struct ip); off < skip;) { 228 if (ptr[off] != IPOPT_EOL && ptr[off] != IPOPT_NOP && 229 off + 1 >= skip) { 230 DPRINTF(("%s: illegal IPv4 option length for" 231 " option %d\n", __func__, ptr[off])); 232 233 ahstat_inc(ahs_hdrops); 234 m_freem(m); 235 return EINVAL; 236 } 237 238 switch (ptr[off]) { 239 case IPOPT_EOL: 240 off = skip; /* End the loop. */ 241 break; 242 243 case IPOPT_NOP: 244 off++; 245 break; 246 247 case IPOPT_SECURITY: /* 0x82 */ 248 case 0x85: /* Extended security. */ 249 case 0x86: /* Commercial security. */ 250 case 0x94: /* Router alert */ 251 case 0x95: /* RFC1770 */ 252 /* Sanity check for option length. */ 253 if (ptr[off + 1] < 2) { 254 DPRINTF(("%s: illegal IPv4 option" 255 " length for option %d\n", __func__, 256 ptr[off])); 257 258 ahstat_inc(ahs_hdrops); 259 m_freem(m); 260 return EINVAL; 261 } 262 263 off += ptr[off + 1]; 264 break; 265 266 case IPOPT_LSRR: 267 case IPOPT_SSRR: 268 /* Sanity check for option length. */ 269 if (ptr[off + 1] < 2) { 270 DPRINTF(("%s: illegal IPv4 option" 271 " length for option %d\n", __func__, 272 ptr[off])); 273 274 ahstat_inc(ahs_hdrops); 275 m_freem(m); 276 return EINVAL; 277 } 278 279 /* 280 * On output, if we have either of the 281 * source routing options, we should 282 * swap the destination address of the 283 * IP header with the last address 284 * specified in the option, as that is 285 * what the destination's IP header 286 * will look like. 287 */ 288 if (out && 289 ptr[off + 1] >= 2 + sizeof(struct in_addr)) 290 memcpy(&ip->ip_dst, 291 ptr + off + ptr[off + 1] - 292 sizeof(struct in_addr), 293 sizeof(struct in_addr)); 294 295 /* FALLTHROUGH */ 296 default: 297 /* Sanity check for option length. */ 298 if (ptr[off + 1] < 2) { 299 DPRINTF(("%s: illegal IPv4 option" 300 " length for option %d\n", __func__, 301 ptr[off])); 302 ahstat_inc(ahs_hdrops); 303 m_freem(m); 304 return EINVAL; 305 } 306 307 /* Zeroize all other options. */ 308 count = ptr[off + 1]; 309 memset(ptr + off, 0, count); 310 off += count; 311 break; 312 } 313 314 /* Sanity check. */ 315 if (off > skip) { 316 DPRINTF(("%s: malformed IPv4 options header\n", 317 __func__)); 318 319 ahstat_inc(ahs_hdrops); 320 m_freem(m); 321 return EINVAL; 322 } 323 } 324 325 break; 326 327 #ifdef INET6 328 case AF_INET6: /* Ugly... */ 329 /* Copy and "cook" the IPv6 header. */ 330 m_copydata(m, 0, sizeof(ip6), &ip6); 331 332 /* We don't do IPv6 Jumbograms. */ 333 if (ip6.ip6_plen == 0) { 334 DPRINTF(("%s: unsupported IPv6 jumbogram", __func__)); 335 ahstat_inc(ahs_hdrops); 336 m_freem(m); 337 return EMSGSIZE; 338 } 339 340 ip6.ip6_flow = 0; 341 ip6.ip6_hlim = 0; 342 ip6.ip6_vfc &= ~IPV6_VERSION_MASK; 343 ip6.ip6_vfc |= IPV6_VERSION; 344 345 /* Scoped address handling. */ 346 if (IN6_IS_SCOPE_EMBED(&ip6.ip6_src)) 347 ip6.ip6_src.s6_addr16[1] = 0; 348 if (IN6_IS_SCOPE_EMBED(&ip6.ip6_dst)) 349 ip6.ip6_dst.s6_addr16[1] = 0; 350 351 /* Done with IPv6 header. */ 352 error = m_copyback(m, 0, sizeof(struct ip6_hdr), &ip6, 353 M_NOWAIT); 354 if (error) { 355 DPRINTF(("%s: m_copyback no memory", __func__)); 356 ahstat_inc(ahs_hdrops); 357 m_freem(m); 358 return error; 359 } 360 361 /* Let's deal with the remaining headers (if any). */ 362 if (skip - sizeof(struct ip6_hdr) > 0) { 363 if (m->m_len <= skip) { 364 ptr = malloc(skip - sizeof(struct ip6_hdr), 365 M_XDATA, M_NOWAIT); 366 if (ptr == NULL) { 367 DPRINTF(("%s: failed to allocate memory" 368 " for IPv6 headers\n", __func__)); 369 ahstat_inc(ahs_hdrops); 370 m_freem(m); 371 return ENOBUFS; 372 } 373 374 /* 375 * Copy all the protocol headers after 376 * the IPv6 header. 377 */ 378 m_copydata(m, sizeof(struct ip6_hdr), 379 skip - sizeof(struct ip6_hdr), ptr); 380 alloc = 1; 381 } else { 382 /* No need to allocate memory. */ 383 ptr = mtod(m, unsigned char *) + 384 sizeof(struct ip6_hdr); 385 alloc = 0; 386 } 387 } else 388 break; 389 390 nxt = ip6.ip6_nxt; /* Next header type. */ 391 392 for (off = 0; off < skip - sizeof(struct ip6_hdr);) { 393 if (off + sizeof(struct ip6_ext) > 394 skip - sizeof(struct ip6_hdr)) 395 goto error6; 396 ip6e = (struct ip6_ext *)(ptr + off); 397 398 switch (nxt) { 399 case IPPROTO_HOPOPTS: 400 case IPPROTO_DSTOPTS: 401 noff = off + ((ip6e->ip6e_len + 1) << 3); 402 403 /* Sanity check. */ 404 if (noff > skip - sizeof(struct ip6_hdr)) 405 goto error6; 406 407 /* 408 * Zero out mutable options. 409 */ 410 for (count = off + sizeof(struct ip6_ext); 411 count < noff;) { 412 if (ptr[count] == IP6OPT_PAD1) { 413 count++; 414 continue; /* Skip padding. */ 415 } 416 417 if (count + 2 > noff) 418 goto error6; 419 ad = ptr[count + 1] + 2; 420 if (count + ad > noff) 421 goto error6; 422 423 /* If mutable option, zeroize. */ 424 if (ptr[count] & IP6OPT_MUTABLE) 425 memset(ptr + count, 0, ad); 426 427 count += ad; 428 } 429 430 if (count != noff) 431 goto error6; 432 break; 433 434 case IPPROTO_ROUTING: 435 /* 436 * Always include routing headers in 437 * computation. 438 */ 439 { 440 struct ip6_rthdr *rh; 441 442 rh = (struct ip6_rthdr *)(ptr + off); 443 /* 444 * must adjust content to make it look like 445 * its final form (as seen at the final 446 * destination). 447 * we only know how to massage type 0 routing 448 * header. 449 */ 450 if (out && rh->ip6r_type == IPV6_RTHDR_TYPE_0) { 451 struct ip6_rthdr0 *rh0; 452 struct in6_addr *addr, finaldst; 453 int i; 454 455 rh0 = (struct ip6_rthdr0 *)rh; 456 addr = (struct in6_addr *)(rh0 + 1); 457 458 for (i = 0; i < rh0->ip6r0_segleft; i++) 459 if (IN6_IS_SCOPE_EMBED(&addr[i])) 460 addr[i].s6_addr16[1] = 0; 461 462 finaldst = addr[rh0->ip6r0_segleft - 1]; 463 memmove(&addr[1], &addr[0], 464 sizeof(struct in6_addr) * 465 (rh0->ip6r0_segleft - 1)); 466 467 m_copydata(m, 0, sizeof(ip6), &ip6); 468 addr[0] = ip6.ip6_dst; 469 ip6.ip6_dst = finaldst; 470 error = m_copyback(m, 0, sizeof(ip6), 471 &ip6, M_NOWAIT); 472 if (error) { 473 if (alloc) 474 free(ptr, M_XDATA, 0); 475 ahstat_inc(ahs_hdrops); 476 m_freem(m); 477 return error; 478 } 479 rh0->ip6r0_segleft = 0; 480 } 481 break; 482 } 483 484 default: 485 DPRINTF(("%s: unexpected IPv6 header type %d\n", 486 __func__, off)); 487 error6: 488 if (alloc) 489 free(ptr, M_XDATA, 0); 490 ahstat_inc(ahs_hdrops); 491 m_freem(m); 492 return EINVAL; 493 } 494 495 /* Advance. */ 496 off += ((ip6e->ip6e_len + 1) << 3); 497 nxt = ip6e->ip6e_nxt; 498 } 499 500 /* Copyback and free, if we allocated. */ 501 if (alloc) { 502 error = m_copyback(m, sizeof(struct ip6_hdr), 503 skip - sizeof(struct ip6_hdr), ptr, M_NOWAIT); 504 free(ptr, M_XDATA, 0); 505 if (error) { 506 ahstat_inc(ahs_hdrops); 507 m_freem(m); 508 return error; 509 } 510 } 511 512 break; 513 #endif /* INET6 */ 514 } 515 516 return 0; 517 } 518 519 /* 520 * ah_input() gets called to verify that an input packet 521 * passes authentication. 522 */ 523 int 524 ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) 525 { 526 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 527 struct tdb_crypto *tc = NULL; 528 u_int32_t btsx, esn; 529 u_int8_t hl; 530 int error, rplen; 531 u_int64_t ibytes; 532 #ifdef ENCDEBUG 533 char buf[INET6_ADDRSTRLEN]; 534 #endif 535 struct cryptodesc *crda = NULL; 536 struct cryptop *crp = NULL; 537 538 rplen = AH_FLENGTH + sizeof(u_int32_t); 539 540 /* Save the AH header, we use it throughout. */ 541 m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t), &hl); 542 543 /* Replay window checking, if applicable. */ 544 if (tdb->tdb_wnd > 0) { 545 m_copydata(m, skip + offsetof(struct ah, ah_rpl), 546 sizeof(u_int32_t), &btsx); 547 btsx = ntohl(btsx); 548 549 switch (checkreplaywindow(tdb, btsx, &esn, 0)) { 550 case 0: /* All's well. */ 551 break; 552 case 1: 553 DPRINTF(("%s: replay counter wrapped for SA %s/%08x\n", 554 __func__, ipsp_address(&tdb->tdb_dst, buf, 555 sizeof(buf)), ntohl(tdb->tdb_spi))); 556 ahstat_inc(ahs_wrap); 557 error = ENOBUFS; 558 goto drop; 559 case 2: 560 DPRINTF(("%s: old packet received in SA %s/%08x\n", 561 __func__, ipsp_address(&tdb->tdb_dst, buf, 562 sizeof(buf)), ntohl(tdb->tdb_spi))); 563 ahstat_inc(ahs_replay); 564 error = ENOBUFS; 565 goto drop; 566 case 3: 567 DPRINTF(("%s: duplicate packet received in SA " 568 "%s/%08x\n", __func__, 569 ipsp_address(&tdb->tdb_dst, buf, 570 sizeof(buf)), ntohl(tdb->tdb_spi))); 571 ahstat_inc(ahs_replay); 572 error = ENOBUFS; 573 goto drop; 574 default: 575 DPRINTF(("%s: bogus value from " 576 "checkreplaywindow() in SA %s/%08x\n", __func__, 577 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 578 ntohl(tdb->tdb_spi))); 579 ahstat_inc(ahs_replay); 580 error = ENOBUFS; 581 goto drop; 582 } 583 } 584 585 /* Verify AH header length. */ 586 if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH) { 587 DPRINTF(("%s: bad authenticator length %ld for packet " 588 "in SA %s/%08x\n", __func__, hl * sizeof(u_int32_t), 589 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 590 ntohl(tdb->tdb_spi))); 591 ahstat_inc(ahs_badauthl); 592 error = EACCES; 593 goto drop; 594 } 595 if (skip + ahx->authsize + rplen > m->m_pkthdr.len) { 596 DPRINTF(("%s: bad mbuf length %d (expecting %d) " 597 "for packet in SA %s/%08x\n", __func__, 598 m->m_pkthdr.len, skip + ahx->authsize + rplen, 599 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 600 ntohl(tdb->tdb_spi))); 601 ahstat_inc(ahs_badauthl); 602 error = EACCES; 603 goto drop; 604 } 605 606 /* Update the counters. */ 607 ibytes = (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t)); 608 tdb->tdb_cur_bytes += ibytes; 609 tdb->tdb_ibytes += ibytes; 610 ahstat_add(ahs_ibytes, ibytes); 611 612 /* Hard expiration. */ 613 if (tdb->tdb_flags & TDBF_BYTES && 614 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { 615 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 616 tdb_delete(tdb); 617 error = ENXIO; 618 goto drop; 619 } 620 621 /* Notify on expiration. */ 622 if (tdb->tdb_flags & TDBF_SOFT_BYTES && 623 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { 624 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 625 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking. */ 626 } 627 628 /* Get crypto descriptors. */ 629 crp = crypto_getreq(1); 630 if (crp == NULL) { 631 DPRINTF(("%s: failed to acquire crypto descriptors\n", 632 __func__)); 633 ahstat_inc(ahs_crypto); 634 error = ENOBUFS; 635 goto drop; 636 } 637 638 crda = &crp->crp_desc[0]; 639 640 crda->crd_skip = 0; 641 crda->crd_len = m->m_pkthdr.len; 642 crda->crd_inject = skip + rplen; 643 644 /* Authentication operation. */ 645 crda->crd_alg = ahx->type; 646 crda->crd_key = tdb->tdb_amxkey; 647 crda->crd_klen = tdb->tdb_amxkeylen * 8; 648 649 if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN)) { 650 esn = htonl(esn); 651 memcpy(crda->crd_esn, &esn, 4); 652 crda->crd_flags |= CRD_F_ESN; 653 } 654 655 /* Allocate IPsec-specific opaque crypto info. */ 656 tc = malloc(sizeof(*tc) + skip + rplen + ahx->authsize, M_XDATA, 657 M_NOWAIT | M_ZERO); 658 if (tc == NULL) { 659 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); 660 ahstat_inc(ahs_crypto); 661 error = ENOBUFS; 662 goto drop; 663 } 664 665 /* 666 * Save the authenticator, the skipped portion of the packet, 667 * and the AH header. 668 */ 669 m_copydata(m, 0, skip + rplen + ahx->authsize, tc + 1); 670 671 /* Zeroize the authenticator on the packet. */ 672 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT); 673 674 /* "Massage" the packet headers for crypto processing. */ 675 error = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, skip, 676 ahx->type, 0); 677 if (error) { 678 /* mbuf was freed by callee. */ 679 m = NULL; 680 goto drop; 681 } 682 683 /* Crypto operation descriptor. */ 684 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 685 crp->crp_flags = CRYPTO_F_IMBUF; 686 crp->crp_buf = (caddr_t)m; 687 crp->crp_callback = ipsec_input_cb; 688 crp->crp_sid = tdb->tdb_cryptoid; 689 crp->crp_opaque = (caddr_t)tc; 690 691 /* These are passed as-is to the callback. */ 692 tc->tc_skip = skip; 693 tc->tc_protoff = protoff; 694 tc->tc_spi = tdb->tdb_spi; 695 tc->tc_proto = tdb->tdb_sproto; 696 tc->tc_rdomain = tdb->tdb_rdomain; 697 memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union)); 698 699 return crypto_dispatch(crp); 700 701 drop: 702 m_freem(m); 703 crypto_freereq(crp); 704 free(tc, M_XDATA, 0); 705 return error; 706 } 707 708 int 709 ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) 710 { 711 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 712 int roff, rplen, skip, protoff; 713 u_int32_t btsx, esn; 714 caddr_t ptr; 715 unsigned char calc[AH_ALEN_MAX]; 716 struct mbuf *m1, *m0; 717 #ifdef ENCDEBUG 718 char buf[INET6_ADDRSTRLEN]; 719 #endif 720 721 NET_ASSERT_LOCKED(); 722 723 skip = tc->tc_skip; 724 protoff = tc->tc_protoff; 725 726 rplen = AH_FLENGTH + sizeof(u_int32_t); 727 728 /* Copy authenticator off the packet. */ 729 m_copydata(m, skip + rplen, ahx->authsize, calc); 730 731 ptr = (caddr_t) (tc + 1); 732 733 /* Verify authenticator. */ 734 if (timingsafe_bcmp(ptr + skip + rplen, calc, ahx->authsize)) { 735 DPRINTF(("%s: authentication failed for packet in SA %s/%08x\n", 736 __func__, ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 737 ntohl(tdb->tdb_spi))); 738 739 ahstat_inc(ahs_badauth); 740 goto baddone; 741 } 742 743 /* Fix the Next Protocol field. */ 744 ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip]; 745 746 /* Copyback the saved (uncooked) network headers. */ 747 m_copyback(m, 0, skip, ptr, M_NOWAIT); 748 749 /* Replay window checking, if applicable. */ 750 if (tdb->tdb_wnd > 0) { 751 m_copydata(m, skip + offsetof(struct ah, ah_rpl), 752 sizeof(u_int32_t), &btsx); 753 btsx = ntohl(btsx); 754 755 switch (checkreplaywindow(tdb, btsx, &esn, 1)) { 756 case 0: /* All's well. */ 757 #if NPFSYNC > 0 758 pfsync_update_tdb(tdb,0); 759 #endif 760 break; 761 case 1: 762 DPRINTF(("%s: replay counter wrapped for SA %s/%08x\n", 763 __func__, ipsp_address(&tdb->tdb_dst, buf, 764 sizeof(buf)), ntohl(tdb->tdb_spi))); 765 ahstat_inc(ahs_wrap); 766 goto baddone; 767 case 2: 768 DPRINTF(("%s: old packet received in SA %s/%08x\n", 769 __func__, ipsp_address(&tdb->tdb_dst, buf, 770 sizeof(buf)), ntohl(tdb->tdb_spi))); 771 ahstat_inc(ahs_replay); 772 goto baddone; 773 case 3: 774 DPRINTF(("%s): duplicate packet received in " 775 "SA %s/%08x\n", __func__, 776 ipsp_address(&tdb->tdb_dst, buf, 777 sizeof(buf)), ntohl(tdb->tdb_spi))); 778 ahstat_inc(ahs_replay); 779 goto baddone; 780 default: 781 DPRINTF(("%s: bogus value from " 782 "checkreplaywindow() in SA %s/%08x\n", __func__, 783 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 784 ntohl(tdb->tdb_spi))); 785 ahstat_inc(ahs_replay); 786 goto baddone; 787 } 788 } 789 790 /* Record the beginning of the AH header. */ 791 m1 = m_getptr(m, skip, &roff); 792 if (m1 == NULL) { 793 DPRINTF(("%s: bad mbuf chain for packet in SA %s/%08x\n", 794 __func__, ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 795 ntohl(tdb->tdb_spi))); 796 ahstat_inc(ahs_hdrops); 797 goto baddone; 798 } 799 800 /* Remove the AH header from the mbuf. */ 801 if (roff == 0) { 802 /* 803 * The AH header was conveniently at the beginning of 804 * the mbuf. 805 */ 806 m_adj(m1, rplen + ahx->authsize); 807 /* 808 * If m1 is the first mbuf, it has set M_PKTHDR and m_adj() 809 * has already adjusted the packet header length for us. 810 */ 811 if (m1 != m) 812 m->m_pkthdr.len -= rplen + ahx->authsize; 813 } else 814 if (roff + rplen + ahx->authsize >= m1->m_len) { 815 int adjlen; 816 817 /* 818 * Part or all of the AH header is at the end 819 * of this mbuf, so first let's remove the 820 * remainder of the AH header from the 821 * beginning of the remainder of the mbuf 822 * chain, if any. 823 */ 824 if (roff + rplen + ahx->authsize > m1->m_len) { 825 adjlen = roff + rplen + ahx->authsize - 826 m1->m_len; 827 /* Adjust the next mbuf by the remainder. */ 828 m_adj(m1->m_next, adjlen); 829 830 /* 831 * The second mbuf is guaranteed not 832 * to have a pkthdr... 833 */ 834 m->m_pkthdr.len -= adjlen; 835 } 836 837 /* Now, let's unlink the mbuf chain for a second... */ 838 m0 = m1->m_next; 839 m1->m_next = NULL; 840 841 /* 842 * ...and trim the end of the first part of 843 * the chain...sick 844 */ 845 adjlen = m1->m_len - roff; 846 m_adj(m1, -adjlen); 847 /* 848 * If m1 is the first mbuf, it has set M_PKTHDR and 849 * m_adj() has already adjusted the packet header len. 850 */ 851 if (m1 != m) 852 m->m_pkthdr.len -= adjlen; 853 854 /* Finally, let's relink. */ 855 m1->m_next = m0; 856 } else { 857 /* 858 * The AH header lies in the "middle" of the 859 * mbuf...do an overlapping copy of the 860 * remainder of the mbuf over the ESP header. 861 */ 862 bcopy(mtod(m1, u_char *) + roff + rplen + 863 ahx->authsize, mtod(m1, u_char *) + roff, 864 m1->m_len - (roff + rplen + ahx->authsize)); 865 m1->m_len -= rplen + ahx->authsize; 866 m->m_pkthdr.len -= rplen + ahx->authsize; 867 } 868 869 free(tc, M_XDATA, 0); 870 871 return ipsec_common_input_cb(m, tdb, skip, protoff); 872 873 baddone: 874 m_freem(m); 875 free(tc, M_XDATA, 0); 876 return -1; 877 } 878 879 /* 880 * AH output routine, called by ipsp_process_packet(). 881 */ 882 int 883 ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, 884 int protoff) 885 { 886 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 887 struct cryptodesc *crda; 888 struct tdb_crypto *tc = NULL; 889 struct mbuf *mi; 890 struct cryptop *crp = NULL; 891 u_int64_t replay64; 892 u_int16_t iplen; 893 int error, rplen, roff; 894 u_int8_t prot; 895 struct ah *ah; 896 #if NBPFILTER > 0 897 struct ifnet *encif; 898 #ifdef ENCDEBUG 899 char buf[INET6_ADDRSTRLEN]; 900 #endif 901 902 if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) { 903 encif->if_opackets++; 904 encif->if_obytes += m->m_pkthdr.len; 905 906 if (encif->if_bpf) { 907 struct enchdr hdr; 908 909 memset(&hdr, 0, sizeof(hdr)); 910 911 hdr.af = tdb->tdb_dst.sa.sa_family; 912 hdr.spi = tdb->tdb_spi; 913 hdr.flags |= M_AUTH; 914 915 bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, 916 ENC_HDRLEN, m, BPF_DIRECTION_OUT); 917 } 918 } 919 #endif 920 921 ahstat_inc(ahs_output); 922 923 /* 924 * Check for replay counter wrap-around in automatic (not 925 * manual) keying. 926 */ 927 if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0)) { 928 DPRINTF(("%s: SA %s/%08x should have expired\n", __func__, 929 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 930 ntohl(tdb->tdb_spi))); 931 ahstat_inc(ahs_wrap); 932 error = EINVAL; 933 goto drop; 934 } 935 936 rplen = AH_FLENGTH + sizeof(u_int32_t); 937 938 switch (tdb->tdb_dst.sa.sa_family) { 939 case AF_INET: 940 /* Check for IP maximum packet size violations. */ 941 if (rplen + ahx->authsize + m->m_pkthdr.len > IP_MAXPACKET) { 942 DPRINTF(("%s: packet in SA %s/%08x got too big\n", 943 __func__, 944 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 945 ntohl(tdb->tdb_spi))); 946 ahstat_inc(ahs_toobig); 947 error = EMSGSIZE; 948 goto drop; 949 } 950 break; 951 952 #ifdef INET6 953 case AF_INET6: 954 /* Check for IPv6 maximum packet size violations. */ 955 if (rplen + ahx->authsize + m->m_pkthdr.len > IPV6_MAXPACKET) { 956 DPRINTF(("%s: packet in SA %s/%08x got too big\n", 957 __func__, ipsp_address(&tdb->tdb_dst, buf, 958 sizeof(buf)), ntohl(tdb->tdb_spi))); 959 ahstat_inc(ahs_toobig); 960 error = EMSGSIZE; 961 goto drop; 962 } 963 break; 964 #endif /* INET6 */ 965 966 default: 967 DPRINTF(("%s: unknown/unsupported protocol family %d, " 968 "SA %s/%08x\n", __func__, tdb->tdb_dst.sa.sa_family, 969 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 970 ntohl(tdb->tdb_spi))); 971 ahstat_inc(ahs_nopf); 972 error = EPFNOSUPPORT; 973 goto drop; 974 } 975 976 /* Update the counters. */ 977 tdb->tdb_cur_bytes += m->m_pkthdr.len - skip; 978 ahstat_add(ahs_obytes, m->m_pkthdr.len - skip); 979 980 /* Hard expiration. */ 981 if (tdb->tdb_flags & TDBF_BYTES && 982 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { 983 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 984 tdb_delete(tdb); 985 error = EINVAL; 986 goto drop; 987 } 988 989 /* Notify on expiration. */ 990 if (tdb->tdb_flags & TDBF_SOFT_BYTES && 991 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { 992 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 993 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ 994 } 995 996 /* 997 * Loop through mbuf chain; if we find a readonly mbuf, 998 * copy the packet. 999 */ 1000 mi = m; 1001 while (mi != NULL && !M_READONLY(mi)) 1002 mi = mi->m_next; 1003 1004 if (mi != NULL) { 1005 struct mbuf *n = m_dup_pkt(m, 0, M_DONTWAIT); 1006 1007 if (n == NULL) { 1008 ahstat_inc(ahs_hdrops); 1009 error = ENOBUFS; 1010 goto drop; 1011 } 1012 1013 m_freem(m); 1014 m = n; 1015 } 1016 1017 /* Inject AH header. */ 1018 mi = m_makespace(m, skip, rplen + ahx->authsize, &roff); 1019 if (mi == NULL) { 1020 DPRINTF(("%s: failed to inject AH header for SA %s/%08x\n", 1021 __func__, ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 1022 ntohl(tdb->tdb_spi))); 1023 ahstat_inc(ahs_hdrops); 1024 error = ENOBUFS; 1025 goto drop; 1026 } 1027 1028 /* 1029 * The AH header is guaranteed by m_makespace() to be in 1030 * contiguous memory, at 'roff' of the returned mbuf. 1031 */ 1032 ah = (struct ah *)(mtod(mi, caddr_t) + roff); 1033 1034 /* Initialize the AH header. */ 1035 m_copydata(m, protoff, sizeof(u_int8_t), &ah->ah_nh); 1036 ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t); 1037 ah->ah_rv = 0; 1038 ah->ah_spi = tdb->tdb_spi; 1039 1040 /* Zeroize authenticator. */ 1041 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT); 1042 1043 replay64 = tdb->tdb_rpl++; 1044 ah->ah_rpl = htonl((u_int32_t)replay64); 1045 #if NPFSYNC > 0 1046 pfsync_update_tdb(tdb,1); 1047 #endif 1048 1049 /* Get crypto descriptors. */ 1050 crp = crypto_getreq(1); 1051 if (crp == NULL) { 1052 DPRINTF(("%s: failed to acquire crypto descriptors\n", 1053 __func__)); 1054 ahstat_inc(ahs_crypto); 1055 error = ENOBUFS; 1056 goto drop; 1057 } 1058 1059 crda = &crp->crp_desc[0]; 1060 1061 crda->crd_skip = 0; 1062 crda->crd_inject = skip + rplen; 1063 crda->crd_len = m->m_pkthdr.len; 1064 1065 /* Authentication operation. */ 1066 crda->crd_alg = ahx->type; 1067 crda->crd_key = tdb->tdb_amxkey; 1068 crda->crd_klen = tdb->tdb_amxkeylen * 8; 1069 1070 if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN)) { 1071 u_int32_t esn; 1072 1073 esn = htonl((u_int32_t)(replay64 >> 32)); 1074 memcpy(crda->crd_esn, &esn, 4); 1075 crda->crd_flags |= CRD_F_ESN; 1076 } 1077 1078 /* Allocate IPsec-specific opaque crypto info. */ 1079 tc = malloc(sizeof(*tc) + skip, M_XDATA, M_NOWAIT | M_ZERO); 1080 if (tc == NULL) { 1081 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); 1082 ahstat_inc(ahs_crypto); 1083 error = ENOBUFS; 1084 goto drop; 1085 } 1086 1087 /* Save the skipped portion of the packet. */ 1088 m_copydata(m, 0, skip, tc + 1); 1089 1090 /* 1091 * Fix IP header length on the header used for 1092 * authentication. We don't need to fix the original 1093 * header length as it will be fixed by our caller. 1094 */ 1095 switch (tdb->tdb_dst.sa.sa_family) { 1096 case AF_INET: 1097 memcpy((caddr_t) &iplen, ((caddr_t)(tc + 1)) + 1098 offsetof(struct ip, ip_len), sizeof(u_int16_t)); 1099 iplen = htons(ntohs(iplen) + rplen + ahx->authsize); 1100 m_copyback(m, offsetof(struct ip, ip_len), 1101 sizeof(u_int16_t), &iplen, M_NOWAIT); 1102 break; 1103 1104 #ifdef INET6 1105 case AF_INET6: 1106 memcpy((caddr_t) &iplen, ((caddr_t)(tc + 1)) + 1107 offsetof(struct ip6_hdr, ip6_plen), sizeof(u_int16_t)); 1108 iplen = htons(ntohs(iplen) + rplen + ahx->authsize); 1109 m_copyback(m, offsetof(struct ip6_hdr, ip6_plen), 1110 sizeof(u_int16_t), &iplen, M_NOWAIT); 1111 break; 1112 #endif /* INET6 */ 1113 } 1114 1115 /* Fix the Next Header field in saved header. */ 1116 ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH; 1117 1118 /* Update the Next Protocol field in the IP header. */ 1119 prot = IPPROTO_AH; 1120 m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT); 1121 1122 /* "Massage" the packet headers for crypto processing. */ 1123 error = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, skip, 1124 ahx->type, 1); 1125 if (error) { 1126 /* mbuf was freed by callee. */ 1127 m = NULL; 1128 goto drop; 1129 } 1130 1131 /* Crypto operation descriptor. */ 1132 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 1133 crp->crp_flags = CRYPTO_F_IMBUF; 1134 crp->crp_buf = (caddr_t)m; 1135 crp->crp_callback = ipsec_output_cb; 1136 crp->crp_sid = tdb->tdb_cryptoid; 1137 crp->crp_opaque = (caddr_t)tc; 1138 1139 /* These are passed as-is to the callback. */ 1140 tc->tc_skip = skip; 1141 tc->tc_protoff = protoff; 1142 tc->tc_spi = tdb->tdb_spi; 1143 tc->tc_proto = tdb->tdb_sproto; 1144 tc->tc_rdomain = tdb->tdb_rdomain; 1145 memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union)); 1146 1147 return crypto_dispatch(crp); 1148 1149 drop: 1150 m_freem(m); 1151 crypto_freereq(crp); 1152 free(tc, M_XDATA, 0); 1153 return error; 1154 } 1155 1156 /* 1157 * AH output callback. 1158 */ 1159 int 1160 ah_output_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int ilen, 1161 int olen) 1162 { 1163 int skip = tc->tc_skip; 1164 caddr_t ptr = (caddr_t) (tc + 1); 1165 1166 /* 1167 * Copy original headers (with the new protocol number) back 1168 * in place. 1169 */ 1170 m_copyback(m, 0, skip, ptr, M_NOWAIT); 1171 1172 /* No longer needed. */ 1173 free(tc, M_XDATA, 0); 1174 1175 /* Call the IPsec input callback. */ 1176 if (ipsp_process_done(m, tdb)) { 1177 ahstat_inc(ahs_outfail); 1178 return -1; 1179 } 1180 1181 return 0; 1182 } 1183