diff options
Diffstat (limited to 'sys/netinet/ip_ah.c')
-rw-r--r-- | sys/netinet/ip_ah.c | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index a10c2a7b7ba..e64026d6392 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.158 2021/10/22 15:44:20 bluhm Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.159 2021/10/23 15:42:35 tobhe Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -531,7 +531,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) struct tdb_crypto *tc = NULL; u_int32_t btsx, esn; u_int8_t hl; - int error, rplen; + int error, rplen, clen; u_int64_t ibytes; #ifdef ENCDEBUG char buf[INET6_ADDRSTRLEN]; @@ -686,9 +686,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; crp->crp_buf = (caddr_t)m; - crp->crp_callback = ipsec_input_cb; crp->crp_sid = tdb->tdb_cryptoid; - crp->crp_opaque = (caddr_t)tc; /* These are passed as-is to the callback. */ tc->tc_skip = skip; @@ -699,7 +697,34 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union)); tc->tc_rpl = tdb->tdb_rpl; - crypto_dispatch(crp); + KERNEL_LOCK(); + crypto_invoke(crp); + while (crp->crp_etype == EAGAIN) { + /* Reset the session ID */ + if (tdb->tdb_cryptoid != 0) + tdb->tdb_cryptoid = crp->crp_sid; + crypto_invoke(crp); + } + KERNEL_UNLOCK(); + if (crp->crp_etype) { + DPRINTF("crypto error %d", crp->crp_etype); + ipsecstat_inc(ipsec_noxform); + error = crp->crp_etype; + goto drop; + } + + /* Length of data after processing */ + clen = crp->crp_olen; + + /* Release the crypto descriptors */ + crypto_freereq(crp); + + error = ah_input_cb(tdb, tc, m, clen); + if (error) { + ipsecstat_inc(ipsec_idrops); + tdb->tdb_idrops++; + } + return 0; drop: @@ -893,7 +918,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff) struct cryptop *crp = NULL; u_int64_t replay64; u_int16_t iplen; - int error, rplen, roff; + int error, rplen, roff, ilen, olen; u_int8_t prot; struct ah *ah; #if NBPFILTER > 0 @@ -1133,9 +1158,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff) crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; crp->crp_buf = (caddr_t)m; - crp->crp_callback = ipsec_output_cb; crp->crp_sid = tdb->tdb_cryptoid; - crp->crp_opaque = (caddr_t)tc; /* These are passed as-is to the callback. */ tc->tc_skip = skip; @@ -1145,7 +1168,34 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff) tc->tc_rdomain = tdb->tdb_rdomain; memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union)); - crypto_dispatch(crp); + KERNEL_LOCK(); + crypto_invoke(crp); + while (crp->crp_etype == EAGAIN) { + /* Reset the session ID */ + if (tdb->tdb_cryptoid != 0) + tdb->tdb_cryptoid = crp->crp_sid; + crypto_invoke(crp); + } + KERNEL_UNLOCK(); + if (crp->crp_etype) { + DPRINTF("crypto error %d", crp->crp_etype); + ipsecstat_inc(ipsec_noxform); + error = crp->crp_etype; + goto drop; + } + + ilen = crp->crp_ilen; + olen = crp->crp_olen; + + /* Release the crypto descriptors */ + crypto_freereq(crp); + + error = ah_output_cb(tdb, tc, m, ilen, olen); + if (error) { + ipsecstat_inc(ipsec_odrops); + tdb->tdb_odrops++; + } + return 0; drop: |