summaryrefslogtreecommitdiff
path: root/net/ipv6/esp6.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-10-10 21:11:34 -0700
committerDavid S. Miller <davem@davemloft.net>2005-10-10 21:11:34 -0700
commitd4875b049b2e6401a6e1fae90b7f09e20a636fcf (patch)
treea5021c091cbd141675cdd90ac330d33188284c03 /net/ipv6/esp6.c
parenta02a64223eddb410712b015fb3342c9a316ab70b (diff)
[IPSEC] Fix block size/MTU bugs in ESP
This patch fixes the following bugs in ESP: * Fix transport mode MTU overestimate. This means that the inner MTU is smaller than it needs be. Worse yet, given an input MTU which is a multiple of 4 it will always produce an estimate which is not a multiple of 4. For example, given a standard ESP/3DES/MD5 transform and an MTU of 1500, the resulting MTU for transport mode is 1462 when it should be 1464. The reason for this is because IP header lengths are always a multiple of 4 for IPv4 and 8 for IPv6. * Ensure that the block size is at least 4. This is required by RFC2406 and corresponds to what the esp_output function does. At the moment this only affects crypto_null as its block size is 1. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r--net/ipv6/esp6.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 0c7d7b42c80b..40d9a1935ab5 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -134,7 +134,7 @@ static int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, stru
struct ipv6_esp_hdr *esph;
struct esp_data *esp = x->data;
struct sk_buff *trailer;
- int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+ int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
int alen = esp->auth.icv_trunc_len;
int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen;
@@ -236,13 +236,14 @@ out_nofree:
static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
{
struct esp_data *esp = x->data;
- u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+ u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
if (x->props.mode) {
mtu = ALIGN(mtu + 2, blksize);
} else {
/* The worst case. */
- mtu += 2 + blksize;
+ u32 padsize = ((blksize - 1) & 7) + 1;
+ mtu = ALIGN(mtu + 2, padsize) + blksize - padsize;
}
if (esp->conf.padlen)
mtu = ALIGN(mtu, esp->conf.padlen);