aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
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/ipv6
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/ipv6')
-rw-r--r--net/ipv6/esp6.c77
1 files changed, 61 insertions, 16 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index dc821acf3d33..ca48c56c4b17 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -382,35 +382,53 @@ static void esp6_destroy(struct xfrm_state *x)
382 kfree(esp); 382 kfree(esp);
383} 383}
384 384
385static int esp6_init_state(struct xfrm_state *x) 385static int esp_init_aead(struct xfrm_state *x)
386{
387 struct esp_data *esp = x->data;
388 struct crypto_aead *aead;
389 int err;
390
391 aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
392 err = PTR_ERR(aead);
393 if (IS_ERR(aead))
394 goto error;
395
396 esp->aead = aead;
397
398 err = crypto_aead_setkey(aead, x->aead->alg_key,
399 (x->aead->alg_key_len + 7) / 8);
400 if (err)
401 goto error;
402
403 err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
404 if (err)
405 goto error;
406
407error:
408 return err;
409}
410
411static int esp_init_authenc(struct xfrm_state *x)
386{ 412{
387 struct esp_data *esp = NULL; 413 struct esp_data *esp = x->data;
388 struct crypto_aead *aead; 414 struct crypto_aead *aead;
389 struct crypto_authenc_key_param *param; 415 struct crypto_authenc_key_param *param;
390 struct rtattr *rta; 416 struct rtattr *rta;
391 char *key; 417 char *key;
392 char *p; 418 char *p;
393 char authenc_name[CRYPTO_MAX_ALG_NAME]; 419 char authenc_name[CRYPTO_MAX_ALG_NAME];
394 u32 align;
395 unsigned int keylen; 420 unsigned int keylen;
396 int err; 421 int err;
397 422
423 err = -EINVAL;
398 if (x->ealg == NULL) 424 if (x->ealg == NULL)
399 return -EINVAL; 425 goto error;
400
401 if (x->encap)
402 return -EINVAL;
403 426
427 err = -ENAMETOOLONG;
404 if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)", 428 if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
405 x->aalg ? x->aalg->alg_name : "digest_null", 429 x->aalg ? x->aalg->alg_name : "digest_null",
406 x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME) 430 x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
407 return -ENAMETOOLONG; 431 goto error;
408
409 esp = kzalloc(sizeof(*esp), GFP_KERNEL);
410 if (esp == NULL)
411 return -ENOMEM;
412
413 x->data = esp;
414 432
415 aead = crypto_alloc_aead(authenc_name, 0, 0); 433 aead = crypto_alloc_aead(authenc_name, 0, 0);
416 err = PTR_ERR(aead); 434 err = PTR_ERR(aead);
@@ -458,8 +476,6 @@ static int esp6_init_state(struct xfrm_state *x)
458 goto free_key; 476 goto free_key;
459 } 477 }
460 478
461 esp->padlen = 0;
462
463 param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8); 479 param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
464 memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8); 480 memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
465 481
@@ -468,9 +484,38 @@ static int esp6_init_state(struct xfrm_state *x)
468free_key: 484free_key:
469 kfree(key); 485 kfree(key);
470 486
487error:
488 return err;
489}
490
491static int esp6_init_state(struct xfrm_state *x)
492{
493 struct esp_data *esp;
494 struct crypto_aead *aead;
495 u32 align;
496 int err;
497
498 if (x->encap)
499 return -EINVAL;
500
501 esp = kzalloc(sizeof(*esp), GFP_KERNEL);
502 if (esp == NULL)
503 return -ENOMEM;
504
505 x->data = esp;
506
507 if (x->aead)
508 err = esp_init_aead(x);
509 else
510 err = esp_init_authenc(x);
511
471 if (err) 512 if (err)
472 goto error; 513 goto error;
473 514
515 aead = esp->aead;
516
517 esp->padlen = 0;
518
474 x->props.header_len = sizeof(struct ip_esp_hdr) + 519 x->props.header_len = sizeof(struct ip_esp_hdr) +
475 crypto_aead_ivsize(aead); 520 crypto_aead_ivsize(aead);
476 switch (x->props.mode) { 521 switch (x->props.mode) {