summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_ah.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_ah.c')
-rw-r--r--sys/netinet/ip_ah.c68
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: