diff options
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r-- | net/ipv6/esp6.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 2ebfd281e721..e78680a9985b 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -99,8 +99,13 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
99 | esph->seq_no = htonl(++x->replay.oseq); | 99 | esph->seq_no = htonl(++x->replay.oseq); |
100 | xfrm_aevent_doreplay(x); | 100 | xfrm_aevent_doreplay(x); |
101 | 101 | ||
102 | if (esp->conf.ivlen) | 102 | if (esp->conf.ivlen) { |
103 | if (unlikely(!esp->conf.ivinitted)) { | ||
104 | get_random_bytes(esp->conf.ivec, esp->conf.ivlen); | ||
105 | esp->conf.ivinitted = 1; | ||
106 | } | ||
103 | crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen); | 107 | crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen); |
108 | } | ||
104 | 109 | ||
105 | do { | 110 | do { |
106 | struct scatterlist *sg = &esp->sgbuf[0]; | 111 | struct scatterlist *sg = &esp->sgbuf[0]; |
@@ -237,7 +242,7 @@ static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) | |||
237 | struct esp_data *esp = x->data; | 242 | struct esp_data *esp = x->data; |
238 | u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); | 243 | u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); |
239 | 244 | ||
240 | if (x->props.mode) { | 245 | if (x->props.mode == XFRM_MODE_TUNNEL) { |
241 | mtu = ALIGN(mtu + 2, blksize); | 246 | mtu = ALIGN(mtu + 2, blksize); |
242 | } else { | 247 | } else { |
243 | /* The worst case. */ | 248 | /* The worst case. */ |
@@ -353,12 +358,12 @@ static int esp6_init_state(struct xfrm_state *x) | |||
353 | esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); | 358 | esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); |
354 | if (unlikely(esp->conf.ivec == NULL)) | 359 | if (unlikely(esp->conf.ivec == NULL)) |
355 | goto error; | 360 | goto error; |
356 | get_random_bytes(esp->conf.ivec, esp->conf.ivlen); | 361 | esp->conf.ivinitted = 0; |
357 | } | 362 | } |
358 | if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len)) | 363 | if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len)) |
359 | goto error; | 364 | goto error; |
360 | x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; | 365 | x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; |
361 | if (x->props.mode) | 366 | if (x->props.mode == XFRM_MODE_TUNNEL) |
362 | x->props.header_len += sizeof(struct ipv6hdr); | 367 | x->props.header_len += sizeof(struct ipv6hdr); |
363 | x->data = esp; | 368 | x->data = esp; |
364 | return 0; | 369 | return 0; |
@@ -379,7 +384,8 @@ static struct xfrm_type esp6_type = | |||
379 | .destructor = esp6_destroy, | 384 | .destructor = esp6_destroy, |
380 | .get_max_size = esp6_get_max_size, | 385 | .get_max_size = esp6_get_max_size, |
381 | .input = esp6_input, | 386 | .input = esp6_input, |
382 | .output = esp6_output | 387 | .output = esp6_output, |
388 | .hdr_offset = xfrm6_find_1stfragopt, | ||
383 | }; | 389 | }; |
384 | 390 | ||
385 | static struct inet6_protocol esp6_protocol = { | 391 | static struct inet6_protocol esp6_protocol = { |