* [PATCH 1/3] xfrm: Add Traffic Flow Confidentiality padding XFRM attribute
2010-12-08 14:37 [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Martin Willi
@ 2010-12-08 14:37 ` Martin Willi
2010-12-08 14:37 ` [PATCH 2/3] xfrm: Traffic Flow Confidentiality for IPv4 ESP Martin Willi
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, netdev
The XFRMA_TFCPAD attribute for XFRM state installation configures
Traffic Flow Confidentiality by padding ESP packets to a specified
length.
Signed-off-by: Martin Willi <martin@strongswan.org>
---
include/linux/xfrm.h | 1 +
include/net/xfrm.h | 1 +
net/xfrm/xfrm_user.c | 19 +++++++++++++++++--
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b971e38..930fdd2 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -283,6 +283,7 @@ enum xfrm_attr_type_t {
XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */
XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */
XFRMA_MARK, /* struct xfrm_mark */
+ XFRMA_TFCPAD, /* __u32 */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index bcfb6b2..bdcade7 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -143,6 +143,7 @@ struct xfrm_state {
struct xfrm_id id;
struct xfrm_selector sel;
struct xfrm_mark mark;
+ u32 tfcpad;
u32 genid;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 8bae6b2..8eb8895 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -148,7 +148,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
!attrs[XFRMA_ALG_AUTH_TRUNC]) ||
attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_CRYPT] ||
- attrs[XFRMA_ALG_COMP])
+ attrs[XFRMA_ALG_COMP] ||
+ attrs[XFRMA_TFCPAD])
goto out;
break;
@@ -165,6 +166,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_CRYPT]) &&
attrs[XFRMA_ALG_AEAD])
goto out;
+ if (attrs[XFRMA_TFCPAD] &&
+ p->mode != XFRM_MODE_TUNNEL)
+ goto out;
break;
case IPPROTO_COMP:
@@ -172,7 +176,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_AUTH] ||
attrs[XFRMA_ALG_AUTH_TRUNC] ||
- attrs[XFRMA_ALG_CRYPT])
+ attrs[XFRMA_ALG_CRYPT] ||
+ attrs[XFRMA_TFCPAD])
goto out;
break;
@@ -186,6 +191,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_CRYPT] ||
attrs[XFRMA_ENCAP] ||
attrs[XFRMA_SEC_CTX] ||
+ attrs[XFRMA_TFCPAD] ||
!attrs[XFRMA_COADDR])
goto out;
break;
@@ -439,6 +445,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
goto error;
}
+ if (attrs[XFRMA_TFCPAD])
+ x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]);
+
if (attrs[XFRMA_COADDR]) {
x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
sizeof(*x->coaddr), GFP_KERNEL);
@@ -688,6 +697,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
if (x->encap)
NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+ if (x->tfcpad)
+ NLA_PUT_U32(skb, XFRMA_TFCPAD, x->tfcpad);
+
if (xfrm_mark_put(skb, &x->mark))
goto nla_put_failure;
@@ -2122,6 +2134,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
[XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
[XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) },
[XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) },
+ [XFRMA_TFCPAD] = { .type = NLA_U32 },
};
static struct xfrm_link {
@@ -2301,6 +2314,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
l += nla_total_size(sizeof(*x->calg));
if (x->encap)
l += nla_total_size(sizeof(*x->encap));
+ if (x->tfcpad)
+ l += nla_total_size(sizeof(x->tfcpad));
if (x->security)
l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) +
x->security->ctx_len);
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/3] xfrm: Traffic Flow Confidentiality for IPv4 ESP
2010-12-08 14:37 [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Martin Willi
2010-12-08 14:37 ` [PATCH 1/3] xfrm: Add Traffic Flow Confidentiality padding XFRM attribute Martin Willi
@ 2010-12-08 14:37 ` Martin Willi
2010-12-08 14:37 ` [PATCH 3/3] xfrm: Traffic Flow Confidentiality for IPv6 ESP Martin Willi
2010-12-09 12:47 ` [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Herbert Xu
3 siblings, 0 replies; 7+ messages in thread
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, netdev
Add TFC padding to all packets smaller than the boundary configured
on the xfrm state. If the boundary is larger than the PMTU, limit
padding to the PMTU.
Signed-off-by: Martin Willi <martin@strongswan.org>
---
net/ipv4/esp4.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 14ca1f1..e42a905 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -23,6 +23,8 @@ struct esp_skb_cb {
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
+
/*
* Allocate an AEAD request structure with extra space for SG and IV.
*
@@ -117,25 +119,35 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
int blksize;
int clen;
int alen;
+ int plen;
+ int tfclen;
int nfrags;
/* skb is pure payload to encrypt */
err = -ENOMEM;
- /* Round to block size */
- clen = skb->len;
-
esp = x->data;
aead = esp->aead;
alen = crypto_aead_authsize(aead);
+ tfclen = 0;
+ if (x->tfcpad) {
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 padto;
+
+ padto = min(x->tfcpad, esp4_get_mtu(x, dst->child_mtu_cached));
+ if (skb->len < padto)
+ tfclen = padto - skb->len;
+ }
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
- clen = ALIGN(clen + 2, blksize);
+ clen = ALIGN(skb->len + 2 + tfclen, blksize);
if (esp->padlen)
clen = ALIGN(clen, esp->padlen);
+ plen = clen - skb->len - tfclen;
- if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+ err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+ if (err < 0)
goto error;
nfrags = err;
@@ -150,13 +162,17 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
/* Fill padding... */
tail = skb_tail_pointer(trailer);
+ if (tfclen) {
+ memset(tail, 0, tfclen);
+ tail += tfclen;
+ }
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i = 0; i < plen - 2; i++)
tail[i] = i + 1;
} while (0);
- tail[clen - skb->len - 2] = (clen - skb->len) - 2;
- tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ tail[plen - 2] = plen - 2;
+ tail[plen - 1] = *skb_mac_header(skb);
pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/3] xfrm: Traffic Flow Confidentiality for IPv6 ESP
2010-12-08 14:37 [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Martin Willi
2010-12-08 14:37 ` [PATCH 1/3] xfrm: Add Traffic Flow Confidentiality padding XFRM attribute Martin Willi
2010-12-08 14:37 ` [PATCH 2/3] xfrm: Traffic Flow Confidentiality for IPv4 ESP Martin Willi
@ 2010-12-08 14:37 ` Martin Willi
2010-12-09 12:47 ` [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Herbert Xu
3 siblings, 0 replies; 7+ messages in thread
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, netdev
Add TFC padding to all packets smaller than the boundary configured
on the xfrm state. If the boundary is larger than the PMTU, limit
padding to the PMTU.
Signed-off-by: Martin Willi <martin@strongswan.org>
---
net/ipv6/esp6.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index ee9b93b..1b5c982 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -49,6 +49,8 @@ struct esp_skb_cb {
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+static u32 esp6_get_mtu(struct xfrm_state *x, int mtu);
+
/*
* Allocate an AEAD request structure with extra space for SG and IV.
*
@@ -140,6 +142,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
int blksize;
int clen;
int alen;
+ int plen;
+ int tfclen;
int nfrags;
u8 *iv;
u8 *tail;
@@ -148,18 +152,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* skb is pure payload to encrypt */
err = -ENOMEM;
- /* Round to block size */
- clen = skb->len;
-
aead = esp->aead;
alen = crypto_aead_authsize(aead);
+ tfclen = 0;
+ if (x->tfcpad) {
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 padto;
+
+ padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached));
+ if (skb->len < padto)
+ tfclen = padto - skb->len;
+ }
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
- clen = ALIGN(clen + 2, blksize);
+ clen = ALIGN(skb->len + 2 + tfclen, blksize);
if (esp->padlen)
clen = ALIGN(clen, esp->padlen);
+ plen = clen - skb->len - tfclen;
- if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+ err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+ if (err < 0)
goto error;
nfrags = err;
@@ -174,13 +186,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* Fill padding... */
tail = skb_tail_pointer(trailer);
+ if (tfclen) {
+ memset(tail, 0, tfclen);
+ tail += tfclen;
+ }
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i = 0; i < plen - 2; i++)
tail[i] = i + 1;
} while (0);
- tail[clen-skb->len - 2] = (clen - skb->len) - 2;
- tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ tail[plen - 2] = plen - 2;
+ tail[plen - 1] = *skb_mac_header(skb);
pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3)
2010-12-08 14:37 [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Martin Willi
` (2 preceding siblings ...)
2010-12-08 14:37 ` [PATCH 3/3] xfrm: Traffic Flow Confidentiality for IPv6 ESP Martin Willi
@ 2010-12-09 12:47 ` Herbert Xu
2010-12-10 22:44 ` David Miller
3 siblings, 1 reply; 7+ messages in thread
From: Herbert Xu @ 2010-12-09 12:47 UTC (permalink / raw)
To: Martin Willi; +Cc: linux-crypto, netdev
On Wed, Dec 08, 2010 at 03:37:48PM +0100, Martin Willi wrote:
> The following patchset adds Traffic Flow Confidentiality padding. The
> first patch introduces a new Netlink XFRM attribute to configure TFC via
> userspace. Patch two and three implement the padding logic in IPv4 and
> IPv6 ESP. Padding is always done using the RFC4303 format an is clamped
> to the PMTU.
>
> Changes from v2:
> - Remove unused flag field in attribute, use a plain u32 as attribute payload
> - Reject installation of TFC padding on non-tunnel SAs
Looks good to me. Thanks for the hard work Martin!
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3)
2010-12-09 12:47 ` [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3) Herbert Xu
@ 2010-12-10 22:44 ` David Miller
0 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2010-12-10 22:44 UTC (permalink / raw)
To: herbert; +Cc: martin, linux-crypto, netdev
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 9 Dec 2010 20:47:32 +0800
> On Wed, Dec 08, 2010 at 03:37:48PM +0100, Martin Willi wrote:
>> The following patchset adds Traffic Flow Confidentiality padding. The
>> first patch introduces a new Netlink XFRM attribute to configure TFC via
>> userspace. Patch two and three implement the padding logic in IPv4 and
>> IPv6 ESP. Padding is always done using the RFC4303 format an is clamped
>> to the PMTU.
>>
>> Changes from v2:
>> - Remove unused flag field in attribute, use a plain u32 as attribute payload
>> - Reject installation of TFC padding on non-tunnel SAs
>
> Looks good to me. Thanks for the hard work Martin!
>
> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
All applied, thanks everyone!
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] xfrm: Traffic Flow Confidentiality for IPv6 ESP
2010-12-07 10:29 [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v2) Martin Willi
@ 2010-12-07 10:29 ` Martin Willi
0 siblings, 0 replies; 7+ messages in thread
From: Martin Willi @ 2010-12-07 10:29 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, netdev
Add TFC padding to all packets smaller than the boundary configured
on the xfrm state. If the boundary is larger than the PMTU, limit
padding to the PMTU.
Signed-off-by: Martin Willi <martin@strongswan.org>
---
net/ipv6/esp6.c | 33 +++++++++++++++++++++++++--------
1 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index ee9b93b..8b493b0 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -49,6 +49,8 @@ struct esp_skb_cb {
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+static u32 esp6_get_mtu(struct xfrm_state *x, int mtu);
+
/*
* Allocate an AEAD request structure with extra space for SG and IV.
*
@@ -140,6 +142,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
int blksize;
int clen;
int alen;
+ int plen;
+ int tfclen;
int nfrags;
u8 *iv;
u8 *tail;
@@ -148,18 +152,27 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* skb is pure payload to encrypt */
err = -ENOMEM;
- /* Round to block size */
- clen = skb->len;
-
aead = esp->aead;
alen = crypto_aead_authsize(aead);
+ tfclen = 0;
+ if (x->tfc.pad && x->props.mode == XFRM_MODE_TUNNEL) {
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 mtu, padto;
+
+ mtu = esp6_get_mtu(x, dst->child_mtu_cached);
+ padto = min_t(u32, x->tfc.pad, mtu);
+ if (skb->len < padto)
+ tfclen = padto - skb->len;
+ }
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
- clen = ALIGN(clen + 2, blksize);
+ clen = ALIGN(skb->len + 2 + tfclen, blksize);
if (esp->padlen)
clen = ALIGN(clen, esp->padlen);
+ plen = clen - skb->len - tfclen;
- if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+ err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+ if (err < 0)
goto error;
nfrags = err;
@@ -174,13 +187,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* Fill padding... */
tail = skb_tail_pointer(trailer);
+ if (tfclen) {
+ memset(tail, 0, tfclen);
+ tail += tfclen;
+ }
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i = 0; i < plen - 2; i++)
tail[i] = i + 1;
} while (0);
- tail[clen-skb->len - 2] = (clen - skb->len) - 2;
- tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ tail[plen - 2] = plen - 2;
+ tail[plen - 1] = *skb_mac_header(skb);
pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread