diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-28 22:37:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:27:03 -0500 |
commit | 1a6509d991225ad210de54c63314fd9542922095 (patch) | |
tree | afe5c560388558bebd3e21b7c6f789a28a323a51 /net/xfrm/xfrm_algo.c | |
parent | 6fbf2cb77461a0cd0675228d20dd0f70d7b2251f (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/xfrm/xfrm_algo.c')
-rw-r--r-- | net/xfrm/xfrm_algo.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 02e3ecf9585d..6cc15250de69 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -28,6 +28,105 @@ | |||
28 | * that instantiated crypto transforms have correct parameters for IPsec | 28 | * that instantiated crypto transforms have correct parameters for IPsec |
29 | * purposes. | 29 | * purposes. |
30 | */ | 30 | */ |
31 | static struct xfrm_algo_desc aead_list[] = { | ||
32 | { | ||
33 | .name = "rfc4106(gcm(aes))", | ||
34 | |||
35 | .uinfo = { | ||
36 | .aead = { | ||
37 | .icv_truncbits = 64, | ||
38 | } | ||
39 | }, | ||
40 | |||
41 | .desc = { | ||
42 | .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8, | ||
43 | .sadb_alg_ivlen = 8, | ||
44 | .sadb_alg_minbits = 128, | ||
45 | .sadb_alg_maxbits = 256 | ||
46 | } | ||
47 | }, | ||
48 | { | ||
49 | .name = "rfc4106(gcm(aes))", | ||
50 | |||
51 | .uinfo = { | ||
52 | .aead = { | ||
53 | .icv_truncbits = 96, | ||
54 | } | ||
55 | }, | ||
56 | |||
57 | .desc = { | ||
58 | .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12, | ||
59 | .sadb_alg_ivlen = 8, | ||
60 | .sadb_alg_minbits = 128, | ||
61 | .sadb_alg_maxbits = 256 | ||
62 | } | ||
63 | }, | ||
64 | { | ||
65 | .name = "rfc4106(gcm(aes))", | ||
66 | |||
67 | .uinfo = { | ||
68 | .aead = { | ||
69 | .icv_truncbits = 128, | ||
70 | } | ||
71 | }, | ||
72 | |||
73 | .desc = { | ||
74 | .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16, | ||
75 | .sadb_alg_ivlen = 8, | ||
76 | .sadb_alg_minbits = 128, | ||
77 | .sadb_alg_maxbits = 256 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | .name = "rfc4309(ccm(aes))", | ||
82 | |||
83 | .uinfo = { | ||
84 | .aead = { | ||
85 | .icv_truncbits = 64, | ||
86 | } | ||
87 | }, | ||
88 | |||
89 | .desc = { | ||
90 | .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8, | ||
91 | .sadb_alg_ivlen = 8, | ||
92 | .sadb_alg_minbits = 128, | ||
93 | .sadb_alg_maxbits = 256 | ||
94 | } | ||
95 | }, | ||
96 | { | ||
97 | .name = "rfc4309(ccm(aes))", | ||
98 | |||
99 | .uinfo = { | ||
100 | .aead = { | ||
101 | .icv_truncbits = 96, | ||
102 | } | ||
103 | }, | ||
104 | |||
105 | .desc = { | ||
106 | .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12, | ||
107 | .sadb_alg_ivlen = 8, | ||
108 | .sadb_alg_minbits = 128, | ||
109 | .sadb_alg_maxbits = 256 | ||
110 | } | ||
111 | }, | ||
112 | { | ||
113 | .name = "rfc4309(ccm(aes))", | ||
114 | |||
115 | .uinfo = { | ||
116 | .aead = { | ||
117 | .icv_truncbits = 128, | ||
118 | } | ||
119 | }, | ||
120 | |||
121 | .desc = { | ||
122 | .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16, | ||
123 | .sadb_alg_ivlen = 8, | ||
124 | .sadb_alg_minbits = 128, | ||
125 | .sadb_alg_maxbits = 256 | ||
126 | } | ||
127 | }, | ||
128 | }; | ||
129 | |||
31 | static struct xfrm_algo_desc aalg_list[] = { | 130 | static struct xfrm_algo_desc aalg_list[] = { |
32 | { | 131 | { |
33 | .name = "hmac(digest_null)", | 132 | .name = "hmac(digest_null)", |
@@ -332,6 +431,11 @@ static struct xfrm_algo_desc calg_list[] = { | |||
332 | }, | 431 | }, |
333 | }; | 432 | }; |
334 | 433 | ||
434 | static inline int aead_entries(void) | ||
435 | { | ||
436 | return ARRAY_SIZE(aead_list); | ||
437 | } | ||
438 | |||
335 | static inline int aalg_entries(void) | 439 | static inline int aalg_entries(void) |
336 | { | 440 | { |
337 | return ARRAY_SIZE(aalg_list); | 441 | return ARRAY_SIZE(aalg_list); |
@@ -354,6 +458,13 @@ struct xfrm_algo_list { | |||
354 | u32 mask; | 458 | u32 mask; |
355 | }; | 459 | }; |
356 | 460 | ||
461 | static const struct xfrm_algo_list xfrm_aead_list = { | ||
462 | .algs = aead_list, | ||
463 | .entries = ARRAY_SIZE(aead_list), | ||
464 | .type = CRYPTO_ALG_TYPE_AEAD, | ||
465 | .mask = CRYPTO_ALG_TYPE_MASK, | ||
466 | }; | ||
467 | |||
357 | static const struct xfrm_algo_list xfrm_aalg_list = { | 468 | static const struct xfrm_algo_list xfrm_aalg_list = { |
358 | .algs = aalg_list, | 469 | .algs = aalg_list, |
359 | .entries = ARRAY_SIZE(aalg_list), | 470 | .entries = ARRAY_SIZE(aalg_list), |
@@ -461,6 +572,33 @@ struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) | |||
461 | } | 572 | } |
462 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); | 573 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); |
463 | 574 | ||
575 | struct xfrm_aead_name { | ||
576 | const char *name; | ||
577 | int icvbits; | ||
578 | }; | ||
579 | |||
580 | static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry, | ||
581 | const void *data) | ||
582 | { | ||
583 | const struct xfrm_aead_name *aead = data; | ||
584 | const char *name = aead->name; | ||
585 | |||
586 | return aead->icvbits == entry->uinfo.aead.icv_truncbits && name && | ||
587 | !strcmp(name, entry->name); | ||
588 | } | ||
589 | |||
590 | struct xfrm_algo_desc *xfrm_aead_get_byname(char *name, int icv_len, int probe) | ||
591 | { | ||
592 | struct xfrm_aead_name data = { | ||
593 | .name = name, | ||
594 | .icvbits = icv_len, | ||
595 | }; | ||
596 | |||
597 | return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data, | ||
598 | probe); | ||
599 | } | ||
600 | EXPORT_SYMBOL_GPL(xfrm_aead_get_byname); | ||
601 | |||
464 | struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) | 602 | struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) |
465 | { | 603 | { |
466 | if (idx >= aalg_entries()) | 604 | if (idx >= aalg_entries()) |