summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorTobias Heider <tobhe@cvs.openbsd.org>2021-10-24 22:34:20 +0000
committerTobias Heider <tobhe@cvs.openbsd.org>2021-10-24 22:34:20 +0000
commitb5dac976511df97d1d274a214e5964751069ee6a (patch)
tree1728288fcf4e998e08252ad273b57b725d0b5584 /sys/netinet
parent1a238521f5b20b36491cb2c35e3e12fd9a1d7712 (diff)
Refactor ah_input() and ah_output() for new crypto API.
ok bluhm@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_ah.c167
-rw-r--r--sys/netinet/ip_ipsp.h5
2 files changed, 57 insertions, 115 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 40347ee61b9..0a9a4fbbc04 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.163 2021/10/24 17:08:27 bluhm Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.164 2021/10/24 22:34:19 tobhe Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -530,17 +530,20 @@ int
ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
{
const struct auth_hash *ahx = tdb->tdb_authalgxform;
- struct mbuf *m = *mp;
- struct tdb_crypto *tc = NULL;
- u_int32_t btsx, esn;
- u_int8_t hl;
+ struct mbuf *m = *mp, *m1, *m0;
+ struct cryptodesc *crda = NULL;
+ struct cryptop *crp = NULL;
+ int roff;
+ uint32_t btsx, esn;
+ uint8_t *ptr = NULL;
+ uint8_t hl;
int error, rplen, clen;
- u_int64_t ibytes;
+ uint64_t ibytes;
+ uint64_t rpl;
#ifdef ENCDEBUG
char buf[INET6_ADDRSTRLEN];
#endif
- struct cryptodesc *crda = NULL;
- struct cryptop *crp = NULL;
+ uint8_t calc[AH_ALEN_MAX];
rplen = AH_FLENGTH + sizeof(u_int32_t);
@@ -658,10 +661,9 @@ ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
}
/* Allocate IPsec-specific opaque crypto info. */
- tc = malloc(sizeof(*tc) + skip + rplen + ahx->authsize, M_XDATA,
- M_NOWAIT | M_ZERO);
- if (tc == NULL) {
- DPRINTF("failed to allocate tdb_crypto");
+ ptr = malloc(skip + rplen + ahx->authsize, M_XDATA, M_NOWAIT | M_ZERO);
+ if (ptr == NULL) {
+ DPRINTF("failed to allocate buffer");
ahstat_inc(ahs_crypto);
error = ENOBUFS;
goto drop;
@@ -671,7 +673,7 @@ ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
* Save the authenticator, the skipped portion of the packet,
* and the AH header.
*/
- m_copydata(m, 0, skip + rplen + ahx->authsize, tc + 1);
+ m_copydata(m, 0, skip + rplen + ahx->authsize, ptr);
/* Zeroize the authenticator on the packet. */
m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT);
@@ -690,15 +692,6 @@ ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
crp->crp_buf = (caddr_t)m;
crp->crp_sid = tdb->tdb_cryptoid;
- /* These are passed as-is to the callback. */
- tc->tc_skip = skip;
- tc->tc_protoff = protoff;
- tc->tc_spi = tdb->tdb_spi;
- tc->tc_proto = tdb->tdb_sproto;
- tc->tc_rdomain = tdb->tdb_rdomain;
- memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union));
- tc->tc_rpl = tdb->tdb_rpl;
-
KERNEL_LOCK();
while ((error = crypto_invoke(crp)) == EAGAIN) {
/* Reset the session ID */
@@ -717,59 +710,30 @@ ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
/* Release the crypto descriptors */
crypto_freereq(crp);
-
- return ah_input_cb(tdb, tc, mp, clen);
-
- drop:
- m_freemp(mp);
- crypto_freereq(crp);
- free(tc, M_XDATA, 0);
- return error;
-}
-
-int
-ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int clen)
-{
- const struct auth_hash *ahx = tdb->tdb_authalgxform;
- struct mbuf *m = *mp;
- int roff, rplen, skip, protoff;
- u_int64_t rpl;
- u_int32_t btsx, esn;
- caddr_t ptr;
- unsigned char calc[AH_ALEN_MAX];
- struct mbuf *m1, *m0;
-#ifdef ENCDEBUG
- char buf[INET6_ADDRSTRLEN];
-#endif
-
- NET_ASSERT_LOCKED();
-
- skip = tc->tc_skip;
- protoff = tc->tc_protoff;
- rpl = tc->tc_rpl;
-
- rplen = AH_FLENGTH + sizeof(u_int32_t);
+ crp = NULL;
/* Copy authenticator off the packet. */
m_copydata(m, skip + rplen, ahx->authsize, calc);
- ptr = (caddr_t) (tc + 1);
-
/* Verify authenticator. */
if (timingsafe_bcmp(ptr + skip + rplen, calc, ahx->authsize)) {
DPRINTF("authentication failed for packet in SA %s/%08x",
ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
ntohl(tdb->tdb_spi));
ahstat_inc(ahs_badauth);
- goto baddone;
+ error = -1;
+ goto drop;
}
/* Fix the Next Protocol field. */
- ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip];
+ ptr[protoff] = ptr[skip];
/* Copyback the saved (uncooked) network headers. */
m_copyback(m, 0, skip, ptr, M_NOWAIT);
+ free(ptr, M_XDATA, 0);
+ ptr = NULL;
+
/* Replay window checking, if applicable. */
if (tdb->tdb_wnd > 0) {
m_copydata(m, skip + offsetof(struct ah, ah_rpl),
@@ -787,26 +751,30 @@ ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int clen)
ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
ntohl(tdb->tdb_spi));
ahstat_inc(ahs_wrap);
- goto baddone;
+ error = -1;
+ goto drop;
case 2:
DPRINTF("old packet received in SA %s/%08x",
ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
ntohl(tdb->tdb_spi));
ahstat_inc(ahs_replay);
- goto baddone;
+ error = -1;
+ goto drop;
case 3:
DPRINTF("duplicate packet received in SA %s/%08x",
ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
ntohl(tdb->tdb_spi));
ahstat_inc(ahs_replay);
- goto baddone;
+ error = -1;
+ goto drop;
default:
DPRINTF("bogus value from checkreplaywindow() "
"in SA %s/%08x",
ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
ntohl(tdb->tdb_spi));
ahstat_inc(ahs_replay);
- goto baddone;
+ error = -1;
+ goto drop;
}
}
@@ -817,7 +785,8 @@ ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int clen)
ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
ntohl(tdb->tdb_spi));
ahstat_inc(ahs_hdrops);
- goto baddone;
+ error = -1;
+ goto drop;
}
/* Remove the AH header from the mbuf. */
@@ -889,14 +858,13 @@ ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int clen)
m->m_pkthdr.len -= rplen + ahx->authsize;
}
- free(tc, M_XDATA, 0);
-
return ipsec_common_input_cb(mp, tdb, skip, protoff);
- baddone:
+ drop:
+ free(ptr, M_XDATA, 0);
m_freemp(mp);
- free(tc, M_XDATA, 0);
- return -1;
+ crypto_freereq(crp);
+ return error;
}
/*
@@ -907,13 +875,13 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
{
const struct auth_hash *ahx = tdb->tdb_authalgxform;
struct cryptodesc *crda;
- struct tdb_crypto *tc = NULL;
struct mbuf *mi;
struct cryptop *crp = NULL;
- u_int64_t replay64;
- u_int16_t iplen;
+ uint64_t replay64;
+ uint16_t iplen;
int error, rplen, roff, ilen, olen;
- u_int8_t prot;
+ uint8_t *ptr = NULL;
+ uint8_t prot;
struct ah *ah;
#if NBPFILTER > 0
struct ifnet *encif;
@@ -1095,17 +1063,16 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
crda->crd_flags |= CRD_F_ESN;
}
- /* Allocate IPsec-specific opaque crypto info. */
- tc = malloc(sizeof(*tc) + skip, M_XDATA, M_NOWAIT | M_ZERO);
- if (tc == NULL) {
- DPRINTF("failed to allocate tdb_crypto");
+ ptr = malloc(skip, M_XDATA, M_NOWAIT | M_ZERO);
+ if (ptr == NULL) {
+ DPRINTF("failed to allocate buffer");
ahstat_inc(ahs_crypto);
error = ENOBUFS;
goto drop;
}
/* Save the skipped portion of the packet. */
- m_copydata(m, 0, skip, tc + 1);
+ m_copydata(m, 0, skip, ptr);
/*
* Fix IP header length on the header used for
@@ -1114,7 +1081,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
*/
switch (tdb->tdb_dst.sa.sa_family) {
case AF_INET:
- memcpy((caddr_t) &iplen, ((caddr_t)(tc + 1)) +
+ memcpy((caddr_t) &iplen, ((caddr_t)ptr) +
offsetof(struct ip, ip_len), sizeof(u_int16_t));
iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
m_copyback(m, offsetof(struct ip, ip_len),
@@ -1123,7 +1090,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
#ifdef INET6
case AF_INET6:
- memcpy((caddr_t) &iplen, ((caddr_t)(tc + 1)) +
+ memcpy((caddr_t) &iplen, ((caddr_t)ptr) +
offsetof(struct ip6_hdr, ip6_plen), sizeof(u_int16_t));
iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
@@ -1133,7 +1100,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
}
/* Fix the Next Header field in saved header. */
- ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH;
+ ptr[protoff] = IPPROTO_AH;
/* Update the Next Protocol field in the IP header. */
prot = IPPROTO_AH;
@@ -1154,14 +1121,6 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
crp->crp_buf = (caddr_t)m;
crp->crp_sid = tdb->tdb_cryptoid;
- /* These are passed as-is to the callback. */
- tc->tc_skip = skip;
- tc->tc_protoff = protoff;
- tc->tc_spi = tdb->tdb_spi;
- tc->tc_proto = tdb->tdb_sproto;
- tc->tc_rdomain = tdb->tdb_rdomain;
- memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union));
-
KERNEL_LOCK();
while ((error = crypto_invoke(crp)) == EAGAIN) {
/* Reset the session ID */
@@ -1180,39 +1139,25 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
/* Release the crypto descriptors */
crypto_freereq(crp);
-
- return ah_output_cb(tdb, tc, m, ilen, olen);
-
- drop:
- m_freem(m);
- crypto_freereq(crp);
- free(tc, M_XDATA, 0);
- return error;
-}
-
-/*
- * AH output callback.
- */
-int
-ah_output_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int ilen,
- int olen)
-{
- int skip = tc->tc_skip;
- caddr_t ptr = (caddr_t) (tc + 1);
- int error;
+ crp = NULL;
/*
* Copy original headers (with the new protocol number) back
* in place.
*/
m_copyback(m, 0, skip, ptr, M_NOWAIT);
-
- /* No longer needed. */
- free(tc, M_XDATA, 0);
+ free(ptr, M_XDATA, 0);
+ ptr = NULL;
/* Call the IPsec input callback. */
error = ipsp_process_done(m, tdb);
if (error)
ahstat_inc(ahs_outfail);
return error;
+
+ drop:
+ free(ptr, M_XDATA, 0);
+ m_freem(m);
+ crypto_freereq(crp);
+ return error;
}
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index f79d393197b..768ee8519a8 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.215 2021/10/24 18:15:58 tobhe Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.216 2021/10/24 22:34:19 tobhe Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -571,10 +571,7 @@ int ah_attach(void);
int ah_init(struct tdb *, const struct xformsw *, struct ipsecinit *);
int ah_zeroize(struct tdb *);
int ah_input(struct mbuf **, struct tdb *, int, int);
-int ah_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf **, int);
int ah_output(struct mbuf *, struct tdb *, int, int);
-int ah_output_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int,
- int);
int ah_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int ah4_input(struct mbuf **, int *, int, int);