Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163125389
D22445.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D22445.id.diff
View Options
Index: lib/libipsec/pfkey.c
===================================================================
--- lib/libipsec/pfkey.c
+++ lib/libipsec/pfkey.c
@@ -1825,6 +1825,7 @@
case SADB_X_EXT_SA_REPLAY:
case SADB_X_EXT_NEW_ADDRESS_SRC:
case SADB_X_EXT_NEW_ADDRESS_DST:
+ case SADB_X_EXT_SA_TFC_LENGTH:
mhp[ext->sadb_ext_type] = (caddr_t)ext;
break;
default:
Index: lib/libipsec/pfkey_dump.c
===================================================================
--- lib/libipsec/pfkey_dump.c
+++ lib/libipsec/pfkey_dump.c
@@ -205,6 +205,7 @@
struct sadb_ident *m_sid, *m_did;
struct sadb_sens *m_sens;
struct sadb_x_sa_replay *m_sa_replay;
+ struct sadb_x_sa_tfc_length *m_sa_tfc_length;
struct sadb_x_nat_t_type *natt_type;
struct sadb_x_nat_t_port *natt_sport, *natt_dport;
struct sadb_address *natt_oai, *natt_oar;
@@ -233,6 +234,7 @@
m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
+ m_sa_tfc_length = (struct sadb_x_sa_tfc_length *)mhp[SADB_X_EXT_SA_TFC_LENGTH];
natt_type = (struct sadb_x_nat_t_type *)mhp[SADB_X_EXT_NAT_T_TYPE];
natt_sport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_SPORT];
natt_dport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_DPORT];
@@ -325,6 +327,10 @@
m_sa->sadb_sa_replay,
m_sa->sadb_sa_flags);
+ /* tfc padding length */
+ printf("tfcpadding=%d ", m_sa_tfc_length ?
+ m_sa_tfc_length->sadb_x_sa_tfc_length_length : 0);
+
/* state */
printf("state=");
GETMSGSTR(str_state, m_sa->sadb_sa_state);
Index: sys/net/pfkeyv2.h
===================================================================
--- sys/net/pfkeyv2.h
+++ sys/net/pfkeyv2.h
@@ -297,6 +297,14 @@
};
_Static_assert(sizeof(struct sadb_x_sa_replay) == 8, "struct size mismatch");
+/* TFC padding length */
+struct sadb_x_sa_tfc_length {
+ u_int16_t sadb_x_sa_tfc_length_len;
+ u_int16_t sadb_x_sa_tfc_length_exttype;
+ int32_t sadb_x_sa_tfc_length_length;
+};
+_Static_assert(sizeof(struct sadb_x_sa_tfc_length) == 8, "struct size mismatch");
+
#define SADB_EXT_RESERVED 0
#define SADB_EXT_SA 1
#define SADB_EXT_LIFETIME_CURRENT 2
@@ -327,7 +335,8 @@
#define SADB_X_EXT_SA_REPLAY 26 /* Replay window override. */
#define SADB_X_EXT_NEW_ADDRESS_SRC 27
#define SADB_X_EXT_NEW_ADDRESS_DST 28
-#define SADB_EXT_MAX 28
+#define SADB_X_EXT_SA_TFC_LENGTH 29
+#define SADB_EXT_MAX 29
#define SADB_SATYPE_UNSPEC 0
#define SADB_SATYPE_AH 2
Index: sys/netipsec/ipsec_mbuf.c
===================================================================
--- sys/netipsec/ipsec_mbuf.c
+++ sys/netipsec/ipsec_mbuf.c
@@ -215,7 +215,15 @@
if (pad > M_TRAILINGSPACE(m0)) {
/* Add an mbuf to the chain. */
- MGET(m1, M_NOWAIT, MT_DATA);
+ if (pad > MCLBYTES) {
+ m_freem(m0);
+ DPRINTF(("%s: padding is too big (%d, max %d)\n", __func__, pad, MCLBYTES));
+ return NULL;
+ }
+ if (pad > MHLEN)
+ m1 = m_getcl(M_NOWAIT, MT_DATA, 0);
+ else
+ MGET(m1, M_NOWAIT, MT_DATA);
if (m1 == NULL) {
m_freem(m0);
DPRINTF(("%s: unable to get extra mbuf\n", __func__));
Index: sys/netipsec/key.c
===================================================================
--- sys/netipsec/key.c
+++ sys/netipsec/key.c
@@ -385,6 +385,7 @@
sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */
sizeof(struct sadb_address), /* SADB_X_EXT_NEW_ADDRESS_SRC */
sizeof(struct sadb_address), /* SADB_X_EXT_NEW_ADDRESS_DST */
+ sizeof(struct sadb_x_sa_tfc_length),/* SADB_X_EXT_SA_TFC_LENGTH */
};
_Static_assert(sizeof(minsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch");
@@ -418,6 +419,7 @@
sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */
0, /* SADB_X_EXT_NEW_ADDRESS_SRC */
0, /* SADB_X_EXT_NEW_ADDRESS_DST */
+ sizeof(struct sadb_x_sa_tfc_length),/* SADB_X_EXT_SA_TFC_LENGTH */
};
_Static_assert(sizeof(maxsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch");
@@ -666,6 +668,7 @@
static struct mbuf *key_setsadbxtype(u_int16_t);
static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t);
static struct mbuf *key_setsadbxsareplay(u_int32_t);
+static struct mbuf *key_setsadbxsatfclength(int32_t);
static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
u_int32_t, u_int32_t);
static struct seckey *key_dup_keymsg(const struct sadb_key *, size_t,
@@ -3377,6 +3380,45 @@
}
}
+ /* TFC padding */
+ sav->tfc = 0;
+ if (!SADB_CHECKHDR(mhp, SADB_X_EXT_SA_TFC_LENGTH)) {
+ int maxpacketsize;
+ if (SADB_CHECKLEN(mhp, SADB_X_EXT_SA_TFC_LENGTH)) {
+ error = EINVAL;
+ goto fail;
+ }
+ error = 0;
+ sav->tfc = ((const struct sadb_x_sa_tfc_length*)
+ mhp->ext[SADB_X_EXT_SA_TFC_LENGTH])->sadb_x_sa_tfc_length_length;
+ switch (sav->sah->saidx.dst.sa.sa_family)
+ {
+#ifdef INET
+ case AF_INET:
+ maxpacketsize = IP_MAXPACKET;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ maxpacketsize = IPV6_MAXPACKET;
+ break;
+#endif /* INET6 */
+ default:
+ DPRINTF(("%s: unknown/unsupported protocol "
+ "family %d, SA %s/%08lx\n", __func__,
+ saidx->dst.sa.sa_family, ipsec_address(&saidx->dst,
+ buf, sizeof(buf)), (u_long) ntohl(sav->spi)));
+ error = EPFNOSUPPORT;
+ goto fail;
+ }
+ if (sav->tfc > maxpacketsize) {
+ ipseclog((LOG_DEBUG, "%s: invalid tfc value.\n",
+ __func__));
+ error = EINVAL;
+ goto fail;
+ }
+ }
+
/* Authentication keys */
if (!SADB_CHECKHDR(mhp, SADB_EXT_KEY_AUTH)) {
if (SADB_CHECKLEN(mhp, SADB_EXT_KEY_AUTH)) {
@@ -3560,7 +3602,7 @@
SADB_X_EXT_NAT_T_TYPE,
SADB_X_EXT_NAT_T_SPORT, SADB_X_EXT_NAT_T_DPORT,
SADB_X_EXT_NAT_T_OAI, SADB_X_EXT_NAT_T_OAR,
- SADB_X_EXT_NAT_T_FRAG,
+ SADB_X_EXT_NAT_T_FRAG, SADB_X_EXT_SA_TFC_LENGTH,
};
uint32_t replay_count;
@@ -3598,6 +3640,15 @@
goto fail;
break;
+ case SADB_X_EXT_SA_TFC_LENGTH:
+ if (sav->tfc <= 0)
+ continue;
+
+ m = key_setsadbxsatfclength(sav->tfc);
+ if (!m)
+ goto fail;
+ break;
+
case SADB_EXT_ADDRESS_SRC:
m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
&sav->sah->saidx.src.sa,
@@ -3921,6 +3972,32 @@
return m;
}
+/*
+ * Set data into sadb_x_sa_tfc_length
+ */
+static struct mbuf *
+key_setsadbxsatfclength(int32_t tfc_length)
+{
+ struct mbuf *m;
+ struct sadb_x_sa_tfc_length *p;
+ size_t len;
+
+ len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa_tfc_length));
+ m = m_get2(len, M_NOWAIT, MT_DATA, 0);
+ if (m == NULL)
+ return (NULL);
+ m_align(m, len);
+ m->m_len = len;
+ p = mtod(m, struct sadb_x_sa_tfc_length *);
+
+ bzero(p, len);
+ p->sadb_x_sa_tfc_length_len = PFKEY_UNIT64(len);
+ p->sadb_x_sa_tfc_length_exttype = SADB_X_EXT_SA_TFC_LENGTH;
+ p->sadb_x_sa_tfc_length_length = tfc_length;
+
+ return m;
+}
+
/*
* Set a type in sadb_x_nat_t_type.
*/
@@ -5840,6 +5917,14 @@
}
sav->natt->cksum = cksum;
}
+
+ if (sav->tfc > 0) {
+ if (sav->tfc > sizeof(struct ip) + sizeof(struct udphdr))
+ sav->tfc -= sizeof(struct ip) + sizeof(struct udphdr);
+ else
+ sav->tfc = 0;
+ }
+
return (0);
}
@@ -8069,6 +8154,7 @@
case SADB_X_EXT_SA_REPLAY:
case SADB_X_EXT_NEW_ADDRESS_SRC:
case SADB_X_EXT_NEW_ADDRESS_DST:
+ case SADB_X_EXT_SA_TFC_LENGTH:
/* duplicate check */
/*
* XXX Are there duplication payloads of either
Index: sys/netipsec/key_debug.c
===================================================================
--- sys/netipsec/key_debug.c
+++ sys/netipsec/key_debug.c
@@ -78,6 +78,7 @@
static void kdebug_sadb_x_sa2(struct sadb_ext *);
static void kdebug_sadb_x_sa_replay(struct sadb_ext *);
static void kdebug_sadb_x_natt(struct sadb_ext *);
+static void kdebug_sadb_x_sa_tfc_length(struct sadb_ext *);
#ifndef _KERNEL
#define panic(fmt, ...) { printf(fmt, ## __VA_ARGS__); exit(-1); }
@@ -253,6 +254,9 @@
case SADB_X_EXT_NAT_T_DPORT:
kdebug_sadb_x_natt(ext);
break;
+ case SADB_X_EXT_SA_TFC_LENGTH:
+ kdebug_sadb_x_sa_tfc_length(ext);
+ break;
default:
printf("%s: invalid ext_type %u\n", __func__,
ext->sadb_ext_type);
@@ -519,6 +523,20 @@
}
}
+static void
+kdebug_sadb_x_sa_tfc_length(struct sadb_ext *ext)
+{
+ struct sadb_x_sa_tfc_length *tfc_length;
+
+ /* sanity check */
+ if (ext == NULL)
+ panic("%s: NULL pointer was passed.\n", __func__);
+
+ tfc_length = (struct sadb_x_sa_tfc_length *)ext;
+ printf("sadb_x_sa_tfc_length{ length=%d }\n",
+ tfc_length->sadb_x_sa_tfc_length_length);
+}
+
void
kdebug_sadb_x_policy(struct sadb_ext *ext)
{
Index: sys/netipsec/keydb.h
===================================================================
--- sys/netipsec/keydb.h
+++ sys/netipsec/keydb.h
@@ -185,6 +185,8 @@
uint64_t cntr; /* counter for GCM and CTR */
volatile u_int refcnt; /* reference count */
+
+ int32_t tfc; /* TFC padding length (ESPv3) */
};
#define SECASVAR_LOCK(_sav) mtx_lock((_sav)->lock)
Index: sys/netipsec/xform_esp.c
===================================================================
--- sys/netipsec/xform_esp.c
+++ sys/netipsec/xform_esp.c
@@ -59,6 +59,7 @@
#include <netinet/ip.h>
#include <netinet/ip_ecn.h>
#include <netinet/ip6.h>
+#include <netinet/udp.h>
#include <netipsec/ipsec.h>
#include <netipsec/ah.h>
@@ -637,9 +638,10 @@
uint8_t *ivp;
uint64_t cntr;
crypto_session_t cryptoid;
- int hlen, rlen, padding, blks, alen, i, roff;
- int error, maxpacketsize;
+ int hlen, rlen, padding, blks, alen, i, j, roff;
+ int error, maxpacketsize, tfclen;
uint8_t prot;
+ int pktlen;
IPSEC_ASSERT(sav != NULL, ("null SA"));
esph = sav->tdb_authalgxform;
@@ -657,9 +659,6 @@
*/
blks = MAX(4, espx->blocksize); /* Cipher blocksize */
- /* XXX clamp padding length a la KAME??? */
- padding = ((blks - ((rlen + 2) % blks)) % blks) + 2;
-
alen = xform_ah_authsize(esph);
ESPSTAT_INC(esps_output);
@@ -686,15 +685,32 @@
error = EPFNOSUPPORT;
goto bad;
}
+
+ pktlen = skip + hlen + rlen + alen;
+ if (sav->tfc > 0 && sav->tfc > pktlen) {
+ tfclen = sav->tfc - pktlen;
+ /* XXX clamp padding length a la KAME??? */
+ padding = ((blks - ((rlen + tfclen + 2) % blks)) % blks) + 2;
+ pktlen += padding + tfclen;
+ if (pktlen > maxpacketsize && tfclen > blks)
+ tfclen -= blks;
+ }
+ else {
+ tfclen = 0;
+ /* XXX clamp padding length a la KAME??? */
+ padding = ((blks - ((rlen + 2) % blks)) % blks) + 2;
+ pktlen += padding;
+ }
+
/*
DPRINTF(("%s: skip %d hlen %d rlen %d padding %d alen %d blksd %d\n",
__func__, skip, hlen, rlen, padding, alen, blks)); */
- if (skip + hlen + rlen + padding + alen > maxpacketsize) {
+ if (pktlen > maxpacketsize) {
DPRINTF(("%s: packet in SA %s/%08lx got too big "
"(len %u, max len %u)\n", __func__,
ipsec_address(&saidx->dst, buf, sizeof(buf)),
(u_long) ntohl(sav->spi),
- skip + hlen + rlen + padding + alen, maxpacketsize));
+ pktlen, maxpacketsize));
ESPSTAT_INC(esps_toobig);
error = EMSGSIZE;
goto bad;
@@ -746,6 +762,35 @@
cntr = sav->cntr++;
SECASVAR_UNLOCK(sav);
+ /*
+ * Add TFC padding
+ */
+ for (i = 0; i < tfclen; i += MCLBYTES) {
+ int pad_len = MIN(tfclen - i, MCLBYTES);
+ pad = (u_char*) m_pad(m, pad_len);
+ if (pad == NULL) {
+ DPRINTF(("%s: m_pad failed for SA %s/%08lx\n", __func__,
+ ipsec_address(&saidx->dst, buf, sizeof(buf)),
+ (u_long) ntohl(sav->spi)));
+ m = NULL; /* NB: free'd by m_pad */
+ error = ENOBUFS;
+ goto bad;
+ }
+
+ switch (sav->flags & SADB_X_EXT_PMASK) {
+ case SADB_X_EXT_PRAND:
+ (void) read_random(pad, pad_len);
+ break;
+ case SADB_X_EXT_PZERO:
+ bzero(pad, pad_len);
+ break;
+ case SADB_X_EXT_PSEQ:
+ for (j = 0; j < pad_len; j++)
+ pad[j] = i + j + 1;
+ break;
+ }
+ }
+
/*
* Add padding -- better to do it ourselves than use the crypto engine,
* although if/when we support compression, we'd have to do that.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jul 21, 7:32 AM (20 m, 54 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35308732
Default Alt Text
D22445.id.diff (11 KB)
Attached To
Mode
D22445: Add ESP TFC padding support
Attached
Detach File
Event Timeline
Log In to Comment