Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F168641092
D15661.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D15661.diff
View Options
Index: sys/netipsec/xform_ah.c
===================================================================
--- sys/netipsec/xform_ah.c
+++ sys/netipsec/xform_ah.c
@@ -147,11 +147,21 @@
size_t size;
if (sav != NULL) {
- int authsize;
+ int authsize, rplen, align;
+
IPSEC_ASSERT(sav->tdb_authalgxform != NULL, ("null xform"));
/*XXX not right for null algorithm--does it matter??*/
+
+ /* RFC4302: use the correct alignment. */
+ align = sizeof(uint32_t);
+#ifdef INET6
+ if (sav->sah->saidx.dst.sa.sa_family == AF_INET6) {
+ align = sizeof(uint64_t);
+ }
+#endif
+ rplen = HDRSIZE(sav);
authsize = AUTHSIZE(sav);
- size = roundup(authsize, sizeof (u_int32_t)) + HDRSIZE(sav);
+ size = roundup(rplen + authsize, align);
} else {
/* default guess */
size = sizeof (struct ah) + sizeof (u_int32_t) + 16;
@@ -535,7 +545,7 @@
struct xform_data *xd;
struct newah *ah;
uint64_t cryptoid;
- int hl, rplen, authsize, error;
+ int hl, rplen, authsize, ahsize, error;
IPSEC_ASSERT(sav != NULL, ("null SA"));
IPSEC_ASSERT(sav->key_auth != NULL, ("null authentication key"));
@@ -569,23 +579,24 @@
SECASVAR_UNLOCK(sav);
/* Verify AH header length. */
- hl = ah->ah_len * sizeof (u_int32_t);
+ hl = sizeof(struct ah) + (ah->ah_len * sizeof (u_int32_t));
ahx = sav->tdb_authalgxform;
authsize = AUTHSIZE(sav);
- if (hl != authsize + rplen - sizeof (struct ah)) {
+ ahsize = ah_hdrsiz(sav);
+ if (hl != ahsize) {
DPRINTF(("%s: bad authenticator length %u (expecting %lu)"
" for packet in SA %s/%08lx\n", __func__, hl,
- (u_long) (authsize + rplen - sizeof (struct ah)),
+ (u_long)ahsize,
ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
(u_long) ntohl(sav->spi)));
AHSTAT_INC(ahs_badauthl);
error = EACCES;
goto bad;
}
- if (skip + authsize + rplen > m->m_pkthdr.len) {
+ if (skip + ahsize > m->m_pkthdr.len) {
DPRINTF(("%s: bad mbuf length %u (expecting %lu)"
" for packet in SA %s/%08lx\n", __func__,
- m->m_pkthdr.len, (u_long) (skip + authsize + rplen),
+ m->m_pkthdr.len, (u_long)(skip + ahsize),
ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
(u_long) ntohl(sav->spi)));
AHSTAT_INC(ahs_badauthl);
@@ -689,7 +700,7 @@
struct secasindex *saidx;
caddr_t ptr;
uint64_t cryptoid;
- int authsize, rplen, error, skip, protoff;
+ int authsize, rplen, ahsize, error, skip, protoff;
uint8_t nxt;
m = (struct mbuf *) crp->crp_buf;
@@ -736,6 +747,7 @@
/* Figure out header size. */
rplen = HDRSIZE(sav);
authsize = AUTHSIZE(sav);
+ ahsize = ah_hdrsiz(sav);
/* Copy authenticator off the packet. */
m_copydata(m, skip + rplen, authsize, calc);
@@ -784,7 +796,7 @@
/*
* Remove the AH header and authenticator from the mbuf.
*/
- error = m_striphdr(m, skip, rplen + authsize);
+ error = m_striphdr(m, skip, ahsize);
if (error) {
DPRINTF(("%s: mangled mbuf chain for SA %s/%08lx\n", __func__,
ipsec_address(&saidx->dst, buf, sizeof(buf)),
@@ -839,7 +851,7 @@
struct newah *ah;
uint64_t cryptoid;
uint16_t iplen;
- int error, rplen, authsize, maxpacketsize, roff;
+ int error, rplen, authsize, ahsize, maxpacketsize, roff;
uint8_t prot;
IPSEC_ASSERT(sav != NULL, ("null SA"));
@@ -850,6 +862,8 @@
/* Figure out header size. */
rplen = HDRSIZE(sav);
+ authsize = AUTHSIZE(sav);
+ ahsize = ah_hdrsiz(sav);
/* Check for maximum packet size violations. */
switch (sav->sah->saidx.dst.sa.sa_family) {
@@ -873,13 +887,12 @@
error = EPFNOSUPPORT;
goto bad;
}
- authsize = AUTHSIZE(sav);
- if (rplen + authsize + m->m_pkthdr.len > maxpacketsize) {
+ if (ahsize + m->m_pkthdr.len > maxpacketsize) {
DPRINTF(("%s: packet in SA %s/%08lx got too big "
"(len %u, max len %u)\n", __func__,
ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
(u_long) ntohl(sav->spi),
- rplen + authsize + m->m_pkthdr.len, maxpacketsize));
+ ahsize + m->m_pkthdr.len, maxpacketsize));
AHSTAT_INC(ahs_toobig);
error = EMSGSIZE;
goto bad;
@@ -899,11 +912,10 @@
}
/* Inject AH header. */
- mi = m_makespace(m, skip, rplen + authsize, &roff);
+ mi = m_makespace(m, skip, ahsize, &roff);
if (mi == NULL) {
DPRINTF(("%s: failed to inject %u byte AH header for SA "
- "%s/%08lx\n", __func__,
- rplen + authsize,
+ "%s/%08lx\n", __func__, ahsize,
ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
(u_long) ntohl(sav->spi)));
AHSTAT_INC(ahs_hdrops); /*XXX differs from openbsd */
@@ -919,13 +931,17 @@
/* Initialize the AH header. */
m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nxt);
- ah->ah_len = (rplen + authsize - sizeof(struct ah)) / sizeof(u_int32_t);
+ ah->ah_len = (ahsize - sizeof(struct ah)) / sizeof(u_int32_t);
ah->ah_reserve = 0;
ah->ah_spi = sav->spi;
/* Zeroize authenticator. */
m_copyback(m, skip + rplen, authsize, ipseczeroes);
+ /* Zeroize padding */
+ m_copyback(m, skip + rplen + authsize, ahsize - (rplen + authsize),
+ ipseczeroes);
+
/* Insert packet replay counter, as requested. */
SECASVAR_LOCK(sav);
if (sav->replay) {
@@ -994,7 +1010,7 @@
bcopy(((caddr_t)(xd + 1)) +
offsetof(struct ip, ip_len),
(caddr_t) &iplen, sizeof(u_int16_t));
- iplen = htons(ntohs(iplen) + rplen + authsize);
+ iplen = htons(ntohs(iplen) + ahsize);
m_copyback(m, offsetof(struct ip, ip_len),
sizeof(u_int16_t), (caddr_t) &iplen);
break;
@@ -1005,7 +1021,7 @@
bcopy(((caddr_t)(xd + 1)) +
offsetof(struct ip6_hdr, ip6_plen),
(caddr_t) &iplen, sizeof(uint16_t));
- iplen = htons(ntohs(iplen) + rplen + authsize);
+ iplen = htons(ntohs(iplen) + ahsize);
m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
sizeof(uint16_t), (caddr_t) &iplen);
break;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Aug 30, 9:45 AM (15 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37588615
Default Alt Text
D15661.diff (5 KB)
Attached To
Mode
D15661: Correctly handle the padding for IPv6-AH, as specified by RFC4302
Attached
Detach File
Event Timeline
Log In to Comment