Commit 040253c931e336360453c8d81f76d1b010b2b5e7
Committed by
David S. Miller
1 parent
d979e20f2b
Exists in
master
and in
7 other branches
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
net/ipv6/esp6.c
... | ... | @@ -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)); |