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