diff options
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r-- | net/ipv6/esp6.c | 51 |
1 files changed, 16 insertions, 35 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index d3618a78fcac..b8719df0366e 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -164,10 +164,9 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
164 | u8 *iv; | 164 | u8 *iv; |
165 | u8 *tail; | 165 | u8 *tail; |
166 | __be32 *seqhi; | 166 | __be32 *seqhi; |
167 | struct esp_data *esp = x->data; | ||
168 | 167 | ||
169 | /* skb is pure payload to encrypt */ | 168 | /* skb is pure payload to encrypt */ |
170 | aead = esp->aead; | 169 | aead = x->data; |
171 | alen = crypto_aead_authsize(aead); | 170 | alen = crypto_aead_authsize(aead); |
172 | 171 | ||
173 | tfclen = 0; | 172 | tfclen = 0; |
@@ -181,8 +180,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
181 | } | 180 | } |
182 | blksize = ALIGN(crypto_aead_blocksize(aead), 4); | 181 | blksize = ALIGN(crypto_aead_blocksize(aead), 4); |
183 | clen = ALIGN(skb->len + 2 + tfclen, blksize); | 182 | clen = ALIGN(skb->len + 2 + tfclen, blksize); |
184 | if (esp->padlen) | ||
185 | clen = ALIGN(clen, esp->padlen); | ||
186 | plen = clen - skb->len - tfclen; | 183 | plen = clen - skb->len - tfclen; |
187 | 184 | ||
188 | err = skb_cow_data(skb, tfclen + plen + alen, &trailer); | 185 | err = skb_cow_data(skb, tfclen + plen + alen, &trailer); |
@@ -271,8 +268,7 @@ error: | |||
271 | static int esp_input_done2(struct sk_buff *skb, int err) | 268 | static int esp_input_done2(struct sk_buff *skb, int err) |
272 | { | 269 | { |
273 | struct xfrm_state *x = xfrm_input_state(skb); | 270 | struct xfrm_state *x = xfrm_input_state(skb); |
274 | struct esp_data *esp = x->data; | 271 | struct crypto_aead *aead = x->data; |
275 | struct crypto_aead *aead = esp->aead; | ||
276 | int alen = crypto_aead_authsize(aead); | 272 | int alen = crypto_aead_authsize(aead); |
277 | int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); | 273 | int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); |
278 | int elen = skb->len - hlen; | 274 | int elen = skb->len - hlen; |
@@ -325,8 +321,7 @@ static void esp_input_done(struct crypto_async_request *base, int err) | |||
325 | static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | 321 | static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) |
326 | { | 322 | { |
327 | struct ip_esp_hdr *esph; | 323 | struct ip_esp_hdr *esph; |
328 | struct esp_data *esp = x->data; | 324 | struct crypto_aead *aead = x->data; |
329 | struct crypto_aead *aead = esp->aead; | ||
330 | struct aead_request *req; | 325 | struct aead_request *req; |
331 | struct sk_buff *trailer; | 326 | struct sk_buff *trailer; |
332 | int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead); | 327 | int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead); |
@@ -414,9 +409,8 @@ out: | |||
414 | 409 | ||
415 | static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) | 410 | static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) |
416 | { | 411 | { |
417 | struct esp_data *esp = x->data; | 412 | struct crypto_aead *aead = x->data; |
418 | u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); | 413 | u32 blksize = ALIGN(crypto_aead_blocksize(aead), 4); |
419 | u32 align = max_t(u32, blksize, esp->padlen); | ||
420 | unsigned int net_adj; | 414 | unsigned int net_adj; |
421 | 415 | ||
422 | if (x->props.mode != XFRM_MODE_TUNNEL) | 416 | if (x->props.mode != XFRM_MODE_TUNNEL) |
@@ -424,8 +418,8 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) | |||
424 | else | 418 | else |
425 | net_adj = 0; | 419 | net_adj = 0; |
426 | 420 | ||
427 | return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) - | 421 | return ((mtu - x->props.header_len - crypto_aead_authsize(aead) - |
428 | net_adj) & ~(align - 1)) + net_adj - 2; | 422 | net_adj) & ~(blksize - 1)) + net_adj - 2; |
429 | } | 423 | } |
430 | 424 | ||
431 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 425 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
@@ -436,8 +430,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
436 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); | 430 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); |
437 | struct xfrm_state *x; | 431 | struct xfrm_state *x; |
438 | 432 | ||
439 | if (type != ICMPV6_DEST_UNREACH && | 433 | if (type != ICMPV6_PKT_TOOBIG && |
440 | type != ICMPV6_PKT_TOOBIG && | ||
441 | type != NDISC_REDIRECT) | 434 | type != NDISC_REDIRECT) |
442 | return; | 435 | return; |
443 | 436 | ||
@@ -455,18 +448,16 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
455 | 448 | ||
456 | static void esp6_destroy(struct xfrm_state *x) | 449 | static void esp6_destroy(struct xfrm_state *x) |
457 | { | 450 | { |
458 | struct esp_data *esp = x->data; | 451 | struct crypto_aead *aead = x->data; |
459 | 452 | ||
460 | if (!esp) | 453 | if (!aead) |
461 | return; | 454 | return; |
462 | 455 | ||
463 | crypto_free_aead(esp->aead); | 456 | crypto_free_aead(aead); |
464 | kfree(esp); | ||
465 | } | 457 | } |
466 | 458 | ||
467 | static int esp_init_aead(struct xfrm_state *x) | 459 | static int esp_init_aead(struct xfrm_state *x) |
468 | { | 460 | { |
469 | struct esp_data *esp = x->data; | ||
470 | struct crypto_aead *aead; | 461 | struct crypto_aead *aead; |
471 | int err; | 462 | int err; |
472 | 463 | ||
@@ -475,7 +466,7 @@ static int esp_init_aead(struct xfrm_state *x) | |||
475 | if (IS_ERR(aead)) | 466 | if (IS_ERR(aead)) |
476 | goto error; | 467 | goto error; |
477 | 468 | ||
478 | esp->aead = aead; | 469 | x->data = aead; |
479 | 470 | ||
480 | err = crypto_aead_setkey(aead, x->aead->alg_key, | 471 | err = crypto_aead_setkey(aead, x->aead->alg_key, |
481 | (x->aead->alg_key_len + 7) / 8); | 472 | (x->aead->alg_key_len + 7) / 8); |
@@ -492,7 +483,6 @@ error: | |||
492 | 483 | ||
493 | static int esp_init_authenc(struct xfrm_state *x) | 484 | static int esp_init_authenc(struct xfrm_state *x) |
494 | { | 485 | { |
495 | struct esp_data *esp = x->data; | ||
496 | struct crypto_aead *aead; | 486 | struct crypto_aead *aead; |
497 | struct crypto_authenc_key_param *param; | 487 | struct crypto_authenc_key_param *param; |
498 | struct rtattr *rta; | 488 | struct rtattr *rta; |
@@ -527,7 +517,7 @@ static int esp_init_authenc(struct xfrm_state *x) | |||
527 | if (IS_ERR(aead)) | 517 | if (IS_ERR(aead)) |
528 | goto error; | 518 | goto error; |
529 | 519 | ||
530 | esp->aead = aead; | 520 | x->data = aead; |
531 | 521 | ||
532 | keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) + | 522 | keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) + |
533 | (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param)); | 523 | (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param)); |
@@ -582,7 +572,6 @@ error: | |||
582 | 572 | ||
583 | static int esp6_init_state(struct xfrm_state *x) | 573 | static int esp6_init_state(struct xfrm_state *x) |
584 | { | 574 | { |
585 | struct esp_data *esp; | ||
586 | struct crypto_aead *aead; | 575 | struct crypto_aead *aead; |
587 | u32 align; | 576 | u32 align; |
588 | int err; | 577 | int err; |
@@ -590,11 +579,7 @@ static int esp6_init_state(struct xfrm_state *x) | |||
590 | if (x->encap) | 579 | if (x->encap) |
591 | return -EINVAL; | 580 | return -EINVAL; |
592 | 581 | ||
593 | esp = kzalloc(sizeof(*esp), GFP_KERNEL); | 582 | x->data = NULL; |
594 | if (esp == NULL) | ||
595 | return -ENOMEM; | ||
596 | |||
597 | x->data = esp; | ||
598 | 583 | ||
599 | if (x->aead) | 584 | if (x->aead) |
600 | err = esp_init_aead(x); | 585 | err = esp_init_aead(x); |
@@ -604,9 +589,7 @@ static int esp6_init_state(struct xfrm_state *x) | |||
604 | if (err) | 589 | if (err) |
605 | goto error; | 590 | goto error; |
606 | 591 | ||
607 | aead = esp->aead; | 592 | aead = x->data; |
608 | |||
609 | esp->padlen = 0; | ||
610 | 593 | ||
611 | x->props.header_len = sizeof(struct ip_esp_hdr) + | 594 | x->props.header_len = sizeof(struct ip_esp_hdr) + |
612 | crypto_aead_ivsize(aead); | 595 | crypto_aead_ivsize(aead); |
@@ -626,9 +609,7 @@ static int esp6_init_state(struct xfrm_state *x) | |||
626 | } | 609 | } |
627 | 610 | ||
628 | align = ALIGN(crypto_aead_blocksize(aead), 4); | 611 | align = ALIGN(crypto_aead_blocksize(aead), 4); |
629 | if (esp->padlen) | 612 | x->props.trailer_len = align + 1 + crypto_aead_authsize(aead); |
630 | align = max_t(u32, align, esp->padlen); | ||
631 | x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead); | ||
632 | 613 | ||
633 | error: | 614 | error: |
634 | return err; | 615 | return err; |