summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-05-30 12:14:00 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-05-30 12:14:00 +0000
commit5a8d3a660ffa2f702399c0a3b2ad186708166d5e (patch)
tree847ffa0643e5addb49602cfc614957caabe545a9
parentbcb2f5d31ec7ac7867241d34de691663bf8266b2 (diff)
Handle TDBF_SKIPCRYPTO on output, and PACKET_TAG_IPSEC_IN_CRYPTO_DONE
on input.
-rw-r--r--sys/netinet/ip_ah.c285
-rw-r--r--sys/netinet/ip_esp.c110
2 files changed, 235 insertions, 160 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 03d0d9d1224..fc8cc4a92a8 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.55 2001/05/27 03:51:31 angelos Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.56 2001/05/30 12:13:59 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -501,7 +501,9 @@ int
ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
{
struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
+ struct tdb_ident *tdbi;
struct tdb_crypto *tc;
+ struct m_tag *mtag;
u_int32_t btsx;
u_int8_t hl;
int rplen;
@@ -604,50 +606,74 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
crda->crd_key = tdb->tdb_amxkey;
crda->crd_klen = tdb->tdb_amxkeylen * 8;
- /* Allocate IPsec-specific opaque crypto info */
- MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
- M_XDATA, M_NOWAIT);
- if (tc == NULL)
+ /* Find out if we've already done crypto */
+ for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
+ mtag != NULL;
+ mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag))
{
- m_freem(m);
- crypto_freereq(crp);
- DPRINTF(("ah_input(): failed to allocate tdb_crypto\n"));
- ahstat.ahs_crypto++;
- return ENOBUFS;
+ tdbi = (struct tdb_ident *) (mtag + 1);
+ if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi &&
+ !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union)))
+ break;
}
- bzero(tc, sizeof(struct tdb_crypto));
- /*
- * Save the authenticator, the skipped portion of the packet, and the
- * AH header.
- */
- MALLOC(tc->tc_ptr, caddr_t, skip + rplen + ahx->authsize,
- M_XDATA, M_NOWAIT);
- if (tc->tc_ptr == 0)
+ /* Allocate IPsec-specific opaque crypto info */
+ if (mtag == NULL)
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto) + skip +
+ rplen + ahx->authsize, M_XDATA, M_NOWAIT);
+ else
+ {
+#ifdef DEBUG
+ /*
+ * Check that it has the proper length -- i.e., contains the
+ * authenticator.
+ */
+ if (mtag->m_tag_len != sizeof(struct tdb_ident) + ahx->authsize)
+ {
+ m_freem(m);
+ crypto_freereq(crp);
+ DPRINTF(("ah_input(): tag had wrong length (%d, should be %d)\n",
+ mtag->m_tag_len,
+ sizeof(struct tdb_ident) + ahx->authsize));
+ ahstat.ahs_crypto++;
+ return EINVAL;
+ }
+#endif
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA,
+ M_NOWAIT);
+ }
+ if (tc == NULL)
{
m_freem(m);
- FREE(tc, M_XDATA);
crypto_freereq(crp);
- DPRINTF(("ah_input(): failed to allocate auth array\n"));
+ DPRINTF(("ah_input(): failed to allocate tdb_crypto\n"));
ahstat.ahs_crypto++;
return ENOBUFS;
}
- /* Save data */
- m_copydata(m, 0, skip + rplen + ahx->authsize, tc->tc_ptr);
-
- /* Zeroize the authenticator on the packet */
- m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
+ bzero(tc, sizeof(struct tdb_crypto));
- /* "Massage" the packet headers for crypto processing */
- if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
- skip, ahx->type, 0)) != 0)
+ /* Only save information if crypto processing is needed */
+ if (mtag == NULL)
{
- /* mbuf will be free'd by callee */
- FREE(tc->tc_ptr, M_XDATA);
- FREE(tc, M_XDATA);
- crypto_freereq(crp);
- return btsx;
+ /*
+ * Save the authenticator, the skipped portion of the packet,
+ * and the AH header.
+ */
+ m_copydata(m, 0, skip + rplen + ahx->authsize, (caddr_t) (tc + 1));
+
+ /* Zeroize the authenticator on the packet */
+ m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
+
+ /* "Massage" the packet headers for crypto processing */
+ if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
+ skip, ahx->type, 0)) != 0)
+ {
+ /* mbuf will be free'd by callee */
+ FREE(tc, M_XDATA);
+ crypto_freereq(crp);
+ return btsx;
+ }
}
/* Crypto operation descriptor */
@@ -663,9 +689,13 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
tc->tc_protoff = protoff;
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
+ tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified */
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
- return crypto_dispatch(crp);
+ if (mtag == NULL)
+ return crypto_dispatch(crp);
+ else
+ return ah_input_cb(crp);
}
/*
@@ -680,9 +710,11 @@ ah_input_cb(void *op)
struct cryptodesc *crd;
struct auth_hash *ahx;
struct tdb_crypto *tc;
+ caddr_t ptr, authptr;
struct cryptop *crp;
+ struct m_tag *mtag;
struct tdb *tdb;
- caddr_t ptr = 0;
+ u_int8_t prot;
int s, err;
crp = (struct cryptop *) op;
@@ -691,7 +723,7 @@ ah_input_cb(void *op)
tc = (struct tdb_crypto *) crp->crp_opaque;
skip = tc->tc_skip;
protoff = tc->tc_protoff;
- ptr = tc->tc_ptr;
+ mtag = (struct m_tag *) tc->tc_ptr;
m = (struct mbuf *) crp->crp_buf;
s = spltdb();
@@ -724,9 +756,14 @@ ah_input_cb(void *op)
error = crp->crp_etype;
goto baddone;
}
+ else
+ {
+ crypto_freereq(crp); /* No longer needed */
+ crp = NULL;
+ }
/* Shouldn't happen... */
- if (!m)
+ if (m == NULL)
{
ahstat.ahs_crypto++;
DPRINTF(("ah_input_cb(): bogus returned buffer from crypto\n"));
@@ -739,11 +776,36 @@ ah_input_cb(void *op)
else
rplen = AH_FLENGTH;
- /* Copy computed authenticator */
+ /* Copy authenticator off the packet. */
m_copydata(m, skip + rplen, ahx->authsize, calc);
+ /*
+ * If we have an mtag, it means we can get the authenticator off
+ * of it, as opposed to right after the tdb_crypto.
+ */
+ if (mtag == NULL)
+ {
+ ptr = (caddr_t) (tc + 1);
+ authptr = ptr + skip + rplen;
+
+ /* Fix the Next Protocol field */
+ ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip];
+
+ /* Copyback the saved (uncooked) network headers */
+ m_copyback(m, 0, skip, ptr);
+ }
+ else
+ {
+ authptr = (caddr_t) (mtag + 1);
+ authptr += sizeof(struct tdb_crypto);
+
+ /* Fix the Next Protocol field */
+ m_copydata(m, skip, sizeof(u_int8_t), &prot);
+ m_copyback(m, protoff, sizeof(u_int8_t), &prot);
+ }
+
/* Verify authenticator */
- if (bcmp(ptr + skip + rplen, calc, ahx->authsize))
+ if (bcmp(authptr, calc, ahx->authsize))
{
DPRINTF(("ah_input(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
ahstat.ahs_badauth++;
@@ -751,17 +813,6 @@ ah_input_cb(void *op)
goto baddone;
}
- /* Fix the Next Protocol field */
- ((u_int8_t *) ptr)[protoff] =
- ((u_int8_t *) ptr)[skip];
-
- /* Copyback the saved (uncooked) network headers */
- m_copyback(m, 0, skip, ptr);
-
- /* No longer needed */
- FREE(ptr, M_XDATA);
- crypto_freereq(crp);
-
/* Record the beginning of the AH header */
m1 = m_getptr(m, skip, &roff);
if (m1 == NULL)
@@ -825,21 +876,18 @@ ah_input_cb(void *op)
m->m_pkthdr.len -= rplen + ahx->authsize;
}
- err = ipsec_common_input_cb(m, tdb, skip, protoff, NULL);
+ err = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
splx(s);
return err;
baddone:
splx(s);
- if (m)
+ if (m != NULL)
m_freem(m);
- /* We have to free this manually */
- if (ptr)
- FREE(ptr, M_XDATA);
-
- crypto_freereq(crp);
+ if (crp != NULL)
+ crypto_freereq(crp);
return error;
}
@@ -857,8 +905,8 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
struct mbuf *mo, *mi;
struct cryptop *crp;
u_int16_t iplen;
- u_int8_t prot;
int len, rplen;
+ u_int8_t prot;
struct ah *ah;
#if NBPFILTER > 0
@@ -1044,8 +1092,12 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
crda->crd_klen = tdb->tdb_amxkeylen * 8;
/* Allocate IPsec-specific opaque crypto info */
- MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA,
- M_NOWAIT);
+ if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto) + skip,
+ M_XDATA, M_NOWAIT);
+ else
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA,
+ M_NOWAIT);
if (tc == NULL)
{
m_freem(m);
@@ -1054,64 +1106,64 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
ahstat.ahs_crypto++;
return ENOBUFS;
}
+
bzero(tc, sizeof(struct tdb_crypto));
/* Save the skipped portion of the packet */
- MALLOC(tc->tc_ptr, caddr_t, skip, M_XDATA, M_NOWAIT);
- if (tc->tc_ptr == 0)
- {
- FREE(tc, M_XDATA);
- m_freem(m);
- crypto_freereq(crp);
- DPRINTF(("ah_output(): failed to allocate auth array\n"));
- ahstat.ahs_crypto++;
- return ENOBUFS;
- }
- else
- m_copydata(m, 0, skip, tc->tc_ptr);
-
- /*
- * Fix IP header length on the header used for authentication. We don't
- * need to fix the original header length as it will be fixed by our
- * caller.
- */
- switch (tdb->tdb_dst.sa.sa_family)
+ if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
{
+ m_copydata(m, 0, skip, (caddr_t) (tc + 1));
+
+ /*
+ * Fix IP header length on the header used for authentication. We don't
+ * need to fix the original header length as it will be fixed by our
+ * caller.
+ */
+ switch (tdb->tdb_dst.sa.sa_family)
+ {
#ifdef INET
- case AF_INET:
- bcopy(tc->tc_ptr + offsetof(struct ip, ip_len),
- (caddr_t) &iplen, sizeof(u_int16_t));
- iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
- m_copyback(m, offsetof(struct ip, ip_len), sizeof(u_int16_t),
- (caddr_t) &iplen);
- break;
+ case AF_INET:
+ bcopy(((caddr_t)(tc + 1)) + offsetof(struct ip, ip_len),
+ (caddr_t) &iplen, sizeof(u_int16_t));
+ iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
+ m_copyback(m, offsetof(struct ip, ip_len), sizeof(u_int16_t),
+ (caddr_t) &iplen);
+ break;
#endif /* INET */
#ifdef INET6
- case AF_INET6:
- bcopy(tc->tc_ptr + offsetof(struct ip6_hdr, ip6_plen),
- (caddr_t) &iplen, sizeof(u_int16_t));
- iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
- m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
- sizeof(u_int16_t), (caddr_t) &iplen);
- break;
+ case AF_INET6:
+ bcopy(((caddr_t)(tc + 1)) + offsetof(struct ip6_hdr, ip6_plen),
+ (caddr_t) &iplen, sizeof(u_int16_t));
+ iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
+ m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
+ sizeof(u_int16_t), (caddr_t) &iplen);
+ break;
#endif /* INET6 */
- }
+ }
+
+ /* Fix the Next Header field in saved header. */
+ ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH;
- /* Update the Next Protocol field in the IP header and the saved data */
- prot = IPPROTO_AH;
- m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot);
- ((u_int8_t *) tc->tc_ptr)[protoff] = IPPROTO_AH;
+ /* Update the Next Protocol field in the IP header. */
+ prot = IPPROTO_AH;
+ m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot);
- /* "Massage" the packet headers for crypto processing */
- if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
- skip, ahx->type, 1)) != 0)
+ /* "Massage" the packet headers for crypto processing */
+ if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
+ skip, ahx->type, 1)) != 0)
+ {
+ /* mbuf will be free'd by callee */
+ FREE(tc, M_XDATA);
+ crypto_freereq(crp);
+ return len;
+ }
+ }
+ else
{
- /* mbuf will be free'd by callee */
- FREE(tc->tc_ptr, M_XDATA);
- FREE(tc, M_XDATA);
- crypto_freereq(crp);
- return len;
+ /* Update the Next Protocol field in the IP header. */
+ prot = IPPROTO_AH;
+ m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot);
}
/* Crypto operation descriptor */
@@ -1136,7 +1188,10 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
bcopy(&tdb2->tdb_dst, &tc->tc_dst2, sizeof(union sockaddr_union));
}
- return crypto_dispatch(crp);
+ if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
+ return crypto_dispatch(crp);
+ else
+ return ah_output_cb(crp);
}
/*
@@ -1149,15 +1204,15 @@ ah_output_cb(void *op)
int skip, protoff, error;
struct tdb_crypto *tc;
struct cryptop *crp;
- caddr_t ptr = 0;
struct mbuf *m;
+ caddr_t ptr;
int err, s;
crp = (struct cryptop *) op;
tc = (struct tdb_crypto *) crp->crp_opaque;
skip = tc->tc_skip;
protoff = tc->tc_protoff;
- ptr = tc->tc_ptr;
+ ptr = (caddr_t) (tc + 1);
m = (struct mbuf *) crp->crp_buf;
s = spltdb();
@@ -1193,7 +1248,7 @@ ah_output_cb(void *op)
}
/* Shouldn't happen... */
- if (!m)
+ if (m == NULL)
{
ahstat.ahs_crypto++;
DPRINTF(("ah_output_cb(): bogus returned buffer from crypto\n"));
@@ -1202,10 +1257,10 @@ ah_output_cb(void *op)
}
/* Copy original headers (with the new protocol number) back in place */
- m_copyback(m, 0, skip, ptr);
+ if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
+ m_copyback(m, 0, skip, ptr);
/* No longer needed */
- FREE(ptr, M_XDATA);
crypto_freereq(crp);
err = ipsp_process_done(m, tdb, tdb2);
@@ -1215,13 +1270,9 @@ ah_output_cb(void *op)
baddone:
splx(s);
- if (m)
+ if (m != NULL)
m_freem(m);
- /* We have to free this manually */
- if (ptr)
- FREE(ptr, M_XDATA);
-
crypto_freereq(crp);
return error;
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index 3577e6babad..7d9248cf33b 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.60 2001/05/27 03:48:34 angelos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.61 2001/05/30 12:13:58 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -278,8 +278,10 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
{
struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
+ struct tdb_ident *tdbi;
struct tdb_crypto *tc;
int plen, alen, hlen;
+ struct m_tag *mtag;
u_int32_t btsx;
struct cryptodesc *crde = NULL, *crda = NULL;
@@ -368,6 +370,31 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
}
+ /* Find out if we've already done crypto */
+ for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
+ mtag != NULL;
+ mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag))
+ {
+ tdbi = (struct tdb_ident *) (mtag + 1);
+ if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi &&
+ !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union)))
+ break;
+ }
+#ifdef DEBUG
+ /*
+ * Check the the length of the tag is correct, i.e., it contains the
+ * authenticator.
+ */
+ if (mtag != NULL && mtag->m_tag_len != sizeof(struct tdb_ident) + alen)
+ {
+ m_freem(m);
+ DPRINTF(("esp_input(): bad tag length %d (should be %d)\n",
+ mtag->m_tag_len, sizeof(struct tdb_ident) + alen));
+ espstat.esps_crypto++;
+ return EINVAL;
+ }
+#endif
+
/* Get crypto descriptors */
crp = crypto_getreq(esph && espx ? 2 : 1);
if (crp == NULL)
@@ -379,8 +406,12 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
}
/* Get IPsec-specific opaque pointer */
- MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
- M_XDATA, M_NOWAIT);
+ if (esph == NULL || mtag != NULL)
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
+ M_XDATA, M_NOWAIT);
+ else
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto) + alen,
+ M_XDATA, M_NOWAIT);
if (tc == NULL)
{
m_freem(m);
@@ -389,7 +420,9 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
espstat.esps_crypto++;
return ENOBUFS;
}
+
bzero(tc, sizeof(struct tdb_crypto));
+ tc->tc_ptr = (caddr_t) mtag;
if (esph)
{
@@ -405,25 +438,12 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
crda->crd_key = tdb->tdb_amxkey;
crda->crd_klen = tdb->tdb_amxkeylen * 8;
- /* Keep a copy of the authenticator */
- MALLOC(tc->tc_ptr, caddr_t, alen, M_XDATA, M_NOWAIT);
- if (tc->tc_ptr == 0)
- {
- FREE(tc, M_XDATA);
- m_freem(m);
- crypto_freereq(crp);
- DPRINTF(("esp_input(): failed to allocate auth array\n"));
- espstat.esps_crypto++;
- return ENOBUFS;
- }
-
/* Copy the authenticator */
- m_copydata(m, m->m_pkthdr.len - alen, alen, tc->tc_ptr);
+ if (mtag == NULL)
+ m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) (tc + 1));
}
else
- {
- crde = crp->crp_desc;
- }
+ crde = crp->crp_desc;
/* Crypto operation descriptor */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
@@ -465,7 +485,10 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
/* XXX Rounds ? */
}
- return crypto_dispatch(crp);
+ if (mtag == NULL)
+ return crypto_dispatch(crp);
+ else
+ return esp_input_cb(crp);
}
/*
@@ -482,9 +505,10 @@ esp_input_cb(void *op)
struct enc_xform *espx;
struct tdb_crypto *tc;
struct cryptop *crp;
+ struct m_tag *mtag;
struct tdb *tdb;
- caddr_t ptr = 0;
int s, err = 0;
+ caddr_t ptr;
crp = (struct cryptop *) op;
crd = crp->crp_desc;
@@ -492,7 +516,7 @@ esp_input_cb(void *op)
tc = (struct tdb_crypto *) crp->crp_opaque;
skip = tc->tc_skip;
protoff = tc->tc_protoff;
- ptr = tc->tc_ptr;
+ mtag = (struct m_tag *) tc->tc_ptr;
m = (struct mbuf *) crp->crp_buf;
s = spltdb();
@@ -529,7 +553,7 @@ esp_input_cb(void *op)
}
/* Shouldn't happen... */
- if (!m)
+ if (m == NULL)
{
espstat.esps_crypto++;
DPRINTF(("esp_input_cb(): bogus returned buffer from crypto\n"));
@@ -543,6 +567,14 @@ esp_input_cb(void *op)
/* Copy the authenticator from the packet */
m_copydata(m, m->m_pkthdr.len - esph->authsize, esph->authsize, aalg);
+ if (mtag != NULL)
+ {
+ ptr = (caddr_t) (mtag + 1);
+ ptr += sizeof(struct tdb_ident);
+ }
+ else
+ ptr = (caddr_t) (tc + 1);
+
/* Verify authenticator */
if (bcmp(ptr, aalg, esph->authsize))
{
@@ -554,9 +586,6 @@ esp_input_cb(void *op)
/* Remove trailing authenticator */
m_adj(m, -(esph->authsize));
-
- /* We have to manually free this */
- FREE(ptr, M_XDATA);
}
/* Release the crypto descriptors */
@@ -663,7 +692,7 @@ esp_input_cb(void *op)
m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2);
/* Back to generic IPsec input processing */
- err = ipsec_common_input_cb(m, tdb, skip, protoff, NULL);
+ err = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
splx(s);
return err;
@@ -673,10 +702,6 @@ esp_input_cb(void *op)
if (m)
m_freem(m);
- /* We have to manually free this */
- if (ptr)
- FREE(ptr, M_XDATA);
-
crypto_freereq(crp);
return error;
@@ -883,14 +908,10 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
/* Self-describing padding ? */
if (!(tdb->tdb_flags & TDBF_RANDOMPADDING))
- {
- for (ilen = 0; ilen < padding - 2; ilen++)
- pad[ilen] = ilen + 1;
- }
+ for (ilen = 0; ilen < padding - 2; ilen++)
+ pad[ilen] = ilen + 1;
else
- {
- get_random_bytes((void *) pad, padding - 2); /* Random padding */
- }
+ get_random_bytes((void *) pad, padding - 2); /* Random padding */
/* Fix padding length and Next Protocol in padding itself */
pad[padding - 2] = padding - 2;
@@ -921,7 +942,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
crde->crd_flags = CRD_F_ENCRYPT;
crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
- if (tdb->tdb_flags & TDBF_HALFIV)
+ if (tdb->tdb_flags & TDBF_HALFIV)
{
/* Copy half-iv in the packet */
m_copyback(m, crde->crd_inject, tdb->tdb_ivlen, tdb->tdb_iv);
@@ -945,7 +966,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
/* IPsec-specific opaque crypto info */
MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
- M_XDATA, M_NOWAIT);
+ M_XDATA, M_NOWAIT);
if (tc == NULL)
{
m_freem(m);
@@ -954,8 +975,8 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
espstat.esps_crypto++;
return ENOBUFS;
}
- bzero(tc, sizeof(struct tdb_crypto));
+ bzero(tc, sizeof(struct tdb_crypto));
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
@@ -988,7 +1009,10 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
crda->crd_klen = tdb->tdb_amxkeylen * 8;
}
- return crypto_dispatch(crp);
+ if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
+ return crypto_dispatch(crp);
+ else
+ return esp_output_cb(crp);
}
/*
@@ -1040,7 +1064,7 @@ esp_output_cb(void *op)
}
/* Shouldn't happen... */
- if (!m)
+ if (m == NULL)
{
espstat.esps_crypto++;
DPRINTF(("esp_output_cb(): bogus returned buffer from crypto\n"));