aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-01-28 22:37:29 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:03 -0500
commit1a6509d991225ad210de54c63314fd9542922095 (patch)
treeafe5c560388558bebd3e21b7c6f789a28a323a51 /net/ipv4
parent6fbf2cb77461a0cd0675228d20dd0f70d7b2251f (diff)
[IPSEC]: Add support for combined mode algorithms
This patch adds support for combined mode algorithms with GCM being the first algorithm supported. Combined mode algorithms can be added through the xfrm_user interface using the new algorithm payload type XFRMA_ALG_AEAD. Each algorithms is identified by its name and the ICV length. For the purposes of matching algorithms in xfrm_tmpl structures, combined mode algorithms occupy the same name space as encryption algorithms. This is in line with how they are negotiated using IKE. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/esp4.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index c4047223bfbe..fac4f102c9f9 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -439,32 +439,53 @@ static void esp_destroy(struct xfrm_state *x)
439 kfree(esp); 439 kfree(esp);
440} 440}
441 441
442static int esp_init_state(struct xfrm_state *x) 442static int esp_init_aead(struct xfrm_state *x)
443{ 443{
444 struct esp_data *esp = NULL; 444 struct esp_data *esp = x->data;
445 struct crypto_aead *aead;
446 int err;
447
448 aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
449 err = PTR_ERR(aead);
450 if (IS_ERR(aead))
451 goto error;
452
453 esp->aead = aead;
454
455 err = crypto_aead_setkey(aead, x->aead->alg_key,
456 (x->aead->alg_key_len + 7) / 8);
457 if (err)
458 goto error;
459
460 err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
461 if (err)
462 goto error;
463
464error:
465 return err;
466}
467
468static int esp_init_authenc(struct xfrm_state *x)
469{
470 struct esp_data *esp = x->data;
445 struct crypto_aead *aead; 471 struct crypto_aead *aead;
446 struct crypto_authenc_key_param *param; 472 struct crypto_authenc_key_param *param;
447 struct rtattr *rta; 473 struct rtattr *rta;
448 char *key; 474 char *key;
449 char *p; 475 char *p;
450 char authenc_name[CRYPTO_MAX_ALG_NAME]; 476 char authenc_name[CRYPTO_MAX_ALG_NAME];
451 u32 align;
452 unsigned int keylen; 477 unsigned int keylen;
453 int err; 478 int err;
454 479
480 err = -EINVAL;
455 if (x->ealg == NULL) 481 if (x->ealg == NULL)
456 return -EINVAL; 482 goto error;
457 483
484 err = -ENAMETOOLONG;
458 if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)", 485 if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
459 x->aalg ? x->aalg->alg_name : "digest_null", 486 x->aalg ? x->aalg->alg_name : "digest_null",
460 x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME) 487 x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
461 return -ENAMETOOLONG; 488 goto error;
462
463 esp = kzalloc(sizeof(*esp), GFP_KERNEL);
464 if (esp == NULL)
465 return -ENOMEM;
466
467 x->data = esp;
468 489
469 aead = crypto_alloc_aead(authenc_name, 0, 0); 490 aead = crypto_alloc_aead(authenc_name, 0, 0);
470 err = PTR_ERR(aead); 491 err = PTR_ERR(aead);
@@ -512,8 +533,6 @@ static int esp_init_state(struct xfrm_state *x)
512 goto free_key; 533 goto free_key;
513 } 534 }
514 535
515 esp->padlen = 0;
516
517 param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8); 536 param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
518 memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8); 537 memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
519 538
@@ -522,9 +541,35 @@ static int esp_init_state(struct xfrm_state *x)
522free_key: 541free_key:
523 kfree(key); 542 kfree(key);
524 543
544error:
545 return err;
546}
547
548static int esp_init_state(struct xfrm_state *x)
549{
550 struct esp_data *esp;
551 struct crypto_aead *aead;
552 u32 align;
553 int err;
554
555 esp = kzalloc(sizeof(*esp), GFP_KERNEL);
556 if (esp == NULL)
557 return -ENOMEM;
558
559 x->data = esp;
560
561 if (x->aead)
562 err = esp_init_aead(x);
563 else
564 err = esp_init_authenc(x);
565
525 if (err) 566 if (err)
526 goto error; 567 goto error;
527 568
569 aead = esp->aead;
570
571 esp->padlen = 0;
572
528 x->props.header_len = sizeof(struct ip_esp_hdr) + 573 x->props.header_len = sizeof(struct ip_esp_hdr) +
529 crypto_aead_ivsize(aead); 574 crypto_aead_ivsize(aead);
530 if (x->props.mode == XFRM_MODE_TUNNEL) 575 if (x->props.mode == XFRM_MODE_TUNNEL)