* ah_input() gets called to verify that an input packet * passes authentication. */
| 529 | * passes authentication. |
| 530 | */ |
| 531 | static int |
| 532 | ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) |
| 533 | { |
| 534 | IPSEC_DEBUG_DECLARE(char buf[128]); |
| 535 | const struct auth_hash *ahx; |
| 536 | struct cryptop *crp; |
| 537 | struct xform_data *xd; |
| 538 | struct newah *ah; |
| 539 | crypto_session_t cryptoid; |
| 540 | int hl, rplen, authsize, ahsize, error; |
| 541 | uint32_t seqh; |
| 542 | |
| 543 | IPSEC_ASSERT(sav != NULL, ("null SA")); |
| 544 | IPSEC_ASSERT(sav->key_auth != NULL, ("null authentication key")); |
| 545 | IPSEC_ASSERT(sav->tdb_authalgxform != NULL, |
| 546 | ("null authentication xform")); |
| 547 | |
| 548 | /* Figure out header size. */ |
| 549 | rplen = HDRSIZE(sav); |
| 550 | |
| 551 | if (m->m_len < skip + rplen) { |
| 552 | m = m_pullup(m, skip + rplen); |
| 553 | if (m == NULL) { |
| 554 | DPRINTF(("ah_input: cannot pullup header\n")); |
| 555 | AHSTAT_INC(ahs_hdrops); /*XXX*/ |
| 556 | error = ENOBUFS; |
| 557 | goto bad; |
| 558 | } |
| 559 | } |
| 560 | ah = (struct newah *)(mtod(m, caddr_t) + skip); |
| 561 | |
| 562 | /* Check replay window, if applicable. */ |
| 563 | SECASVAR_LOCK(sav); |
| 564 | if (sav->replay != NULL && sav->replay->wsize != 0 && |
| 565 | ipsec_chkreplay(ntohl(ah->ah_seq), &seqh, sav) == 0) { |
| 566 | SECASVAR_UNLOCK(sav); |
| 567 | AHSTAT_INC(ahs_replay); |
| 568 | DPRINTF(("%s: packet replay failure: %s\n", __func__, |
| 569 | ipsec_sa2str(sav, buf, sizeof(buf)))); |
| 570 | error = EACCES; |
| 571 | goto bad; |
| 572 | } |
| 573 | cryptoid = sav->tdb_cryptoid; |
| 574 | SECASVAR_UNLOCK(sav); |
| 575 | |
| 576 | /* Verify AH header length. */ |
| 577 | hl = sizeof(struct ah) + (ah->ah_len * sizeof (u_int32_t)); |
| 578 | ahx = sav->tdb_authalgxform; |
| 579 | authsize = AUTHSIZE(sav); |
| 580 | ahsize = ah_hdrsiz(sav); |
| 581 | if (hl != ahsize) { |
| 582 | DPRINTF(("%s: bad authenticator length %u (expecting %lu)" |
| 583 | " for packet in SA %s/%08lx\n", __func__, hl, |
| 584 | (u_long)ahsize, |
| 585 | ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), |
| 586 | (u_long) ntohl(sav->spi))); |
| 587 | AHSTAT_INC(ahs_badauthl); |
| 588 | error = EACCES; |
nothing calls this directly
no test coverage detected