Commit 040253c9 authored by Martin Willi's avatar Martin Willi Committed by David S. Miller

xfrm: Traffic Flow Confidentiality for IPv6 ESP

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: default avatarMartin Willi <martin@strongswan.org>
Acked-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d979e20f
...@@ -49,6 +49,8 @@ struct esp_skb_cb { ...@@ -49,6 +49,8 @@ struct esp_skb_cb {
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) #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. * 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) ...@@ -140,6 +142,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
int blksize; int blksize;
int clen; int clen;
int alen; int alen;
int plen;
int tfclen;
int nfrags; int nfrags;
u8 *iv; u8 *iv;
u8 *tail; u8 *tail;
...@@ -148,18 +152,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -148,18 +152,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* skb is pure payload to encrypt */ /* skb is pure payload to encrypt */
err = -ENOMEM; err = -ENOMEM;
/* Round to block size */
clen = skb->len;
aead = esp->aead; aead = esp->aead;
alen = crypto_aead_authsize(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); blksize = ALIGN(crypto_aead_blocksize(aead), 4);
clen = ALIGN(clen + 2, blksize); clen = ALIGN(skb->len + 2 + tfclen, blksize);
if (esp->padlen) if (esp->padlen)
clen = ALIGN(clen, 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; goto error;
nfrags = err; nfrags = err;
...@@ -174,13 +186,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -174,13 +186,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* Fill padding... */ /* Fill padding... */
tail = skb_tail_pointer(trailer); tail = skb_tail_pointer(trailer);
if (tfclen) {
memset(tail, 0, tfclen);
tail += tfclen;
}
do { do {
int i; int i;
for (i=0; i<clen-skb->len - 2; i++) for (i = 0; i < plen - 2; i++)
tail[i] = i + 1; tail[i] = i + 1;
} while (0); } while (0);
tail[clen-skb->len - 2] = (clen - skb->len) - 2; tail[plen - 2] = plen - 2;
tail[clen - skb->len - 1] = *skb_mac_header(skb); tail[plen - 1] = *skb_mac_header(skb);
pskb_put(skb, trailer, clen - skb->len + alen); pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb)); skb_push(skb, -skb_network_offset(skb));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment