Commit 040253c931e336360453c8d81f76d1b010b2b5e7

Authored by Martin Willi
Committed by David S. Miller
1 parent d979e20f2b

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: Martin Willi <martin@strongswan.org>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 24 additions and 8 deletions Side-by-side Diff

... ... @@ -49,6 +49,8 @@
49 49  
50 50 #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
51 51  
  52 +static u32 esp6_get_mtu(struct xfrm_state *x, int mtu);
  53 +
52 54 /*
53 55 * Allocate an AEAD request structure with extra space for SG and IV.
54 56 *
... ... @@ -140,6 +142,8 @@
140 142 int blksize;
141 143 int clen;
142 144 int alen;
  145 + int plen;
  146 + int tfclen;
143 147 int nfrags;
144 148 u8 *iv;
145 149 u8 *tail;
146 150  
147 151  
148 152  
149 153  
... ... @@ -148,18 +152,26 @@
148 152 /* skb is pure payload to encrypt */
149 153 err = -ENOMEM;
150 154  
151   - /* Round to block size */
152   - clen = skb->len;
153   -
154 155 aead = esp->aead;
155 156 alen = crypto_aead_authsize(aead);
156 157  
  158 + tfclen = 0;
  159 + if (x->tfcpad) {
  160 + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
  161 + u32 padto;
  162 +
  163 + padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached));
  164 + if (skb->len < padto)
  165 + tfclen = padto - skb->len;
  166 + }
157 167 blksize = ALIGN(crypto_aead_blocksize(aead), 4);
158   - clen = ALIGN(clen + 2, blksize);
  168 + clen = ALIGN(skb->len + 2 + tfclen, blksize);
159 169 if (esp->padlen)
160 170 clen = ALIGN(clen, esp->padlen);
  171 + plen = clen - skb->len - tfclen;
161 172  
162   - if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
  173 + err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
  174 + if (err < 0)
163 175 goto error;
164 176 nfrags = err;
165 177  
166 178  
167 179  
... ... @@ -174,13 +186,17 @@
174 186  
175 187 /* Fill padding... */
176 188 tail = skb_tail_pointer(trailer);
  189 + if (tfclen) {
  190 + memset(tail, 0, tfclen);
  191 + tail += tfclen;
  192 + }
177 193 do {
178 194 int i;
179   - for (i=0; i<clen-skb->len - 2; i++)
  195 + for (i = 0; i < plen - 2; i++)
180 196 tail[i] = i + 1;
181 197 } while (0);
182   - tail[clen-skb->len - 2] = (clen - skb->len) - 2;
183   - tail[clen - skb->len - 1] = *skb_mac_header(skb);
  198 + tail[plen - 2] = plen - 2;
  199 + tail[plen - 1] = *skb_mac_header(skb);
184 200 pskb_put(skb, trailer, clen - skb->len + alen);
185 201  
186 202 skb_push(skb, -skb_network_offset(skb));