aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ah4.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-20 00:24:50 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-20 21:46:18 -0400
commit07d4ee583e21830ec5604d31f65cdc60a6eca19e (patch)
tree32962ef0dd13d0d1f66b143ca5d03a88d8b9f772 /net/ipv4/ah4.c
parente9d41164e2fdd897fe4520c2079ea0000f6e0ec3 (diff)
[IPSEC]: Use HMAC template and hash interface
This patch converts IPsec to use the new HMAC template. The names of existing simple digest algorithms may still be used to refer to their HMAC composites. The same structure can be used by other MACs such as AES-XCBC-MAC. This patch also switches from the digest interface to hash. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ah4.c')
-rw-r--r--net/ipv4/ah4.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 1366bc6ce6a5..2b98943e6b02 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -1,3 +1,4 @@
1#include <linux/err.h>
1#include <linux/module.h> 2#include <linux/module.h>
2#include <net/ip.h> 3#include <net/ip.h>
3#include <net/xfrm.h> 4#include <net/xfrm.h>
@@ -97,7 +98,10 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
97 ah->spi = x->id.spi; 98 ah->spi = x->id.spi;
98 ah->seq_no = htonl(++x->replay.oseq); 99 ah->seq_no = htonl(++x->replay.oseq);
99 xfrm_aevent_doreplay(x); 100 xfrm_aevent_doreplay(x);
100 ahp->icv(ahp, skb, ah->auth_data); 101 err = ah_mac_digest(ahp, skb, ah->auth_data);
102 if (err)
103 goto error;
104 memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len);
101 105
102 top_iph->tos = iph->tos; 106 top_iph->tos = iph->tos;
103 top_iph->ttl = iph->ttl; 107 top_iph->ttl = iph->ttl;
@@ -119,6 +123,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
119{ 123{
120 int ah_hlen; 124 int ah_hlen;
121 int ihl; 125 int ihl;
126 int err = -EINVAL;
122 struct iphdr *iph; 127 struct iphdr *iph;
123 struct ip_auth_hdr *ah; 128 struct ip_auth_hdr *ah;
124 struct ah_data *ahp; 129 struct ah_data *ahp;
@@ -166,8 +171,11 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
166 171
167 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); 172 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
168 skb_push(skb, ihl); 173 skb_push(skb, ihl);
169 ahp->icv(ahp, skb, ah->auth_data); 174 err = ah_mac_digest(ahp, skb, ah->auth_data);
170 if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { 175 if (err)
176 goto out;
177 err = -EINVAL;
178 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
171 x->stats.integrity_failed++; 179 x->stats.integrity_failed++;
172 goto out; 180 goto out;
173 } 181 }
@@ -179,7 +187,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
179 return 0; 187 return 0;
180 188
181out: 189out:
182 return -EINVAL; 190 return err;
183} 191}
184 192
185static void ah4_err(struct sk_buff *skb, u32 info) 193static void ah4_err(struct sk_buff *skb, u32 info)
@@ -204,6 +212,7 @@ static int ah_init_state(struct xfrm_state *x)
204{ 212{
205 struct ah_data *ahp = NULL; 213 struct ah_data *ahp = NULL;
206 struct xfrm_algo_desc *aalg_desc; 214 struct xfrm_algo_desc *aalg_desc;
215 struct crypto_hash *tfm;
207 216
208 if (!x->aalg) 217 if (!x->aalg)
209 goto error; 218 goto error;
@@ -221,24 +230,27 @@ static int ah_init_state(struct xfrm_state *x)
221 230
222 ahp->key = x->aalg->alg_key; 231 ahp->key = x->aalg->alg_key;
223 ahp->key_len = (x->aalg->alg_key_len+7)/8; 232 ahp->key_len = (x->aalg->alg_key_len+7)/8;
224 ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 233 tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC);
225 if (!ahp->tfm) 234 if (IS_ERR(tfm))
235 goto error;
236
237 ahp->tfm = tfm;
238 if (crypto_hash_setkey(tfm, ahp->key, ahp->key_len))
226 goto error; 239 goto error;
227 ahp->icv = ah_hmac_digest;
228 240
229 /* 241 /*
230 * Lookup the algorithm description maintained by xfrm_algo, 242 * Lookup the algorithm description maintained by xfrm_algo,
231 * verify crypto transform properties, and store information 243 * verify crypto transform properties, and store information
232 * we need for AH processing. This lookup cannot fail here 244 * we need for AH processing. This lookup cannot fail here
233 * after a successful crypto_alloc_tfm(). 245 * after a successful crypto_alloc_hash().
234 */ 246 */
235 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 247 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
236 BUG_ON(!aalg_desc); 248 BUG_ON(!aalg_desc);
237 249
238 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 250 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
239 crypto_tfm_alg_digestsize(ahp->tfm)) { 251 crypto_hash_digestsize(tfm)) {
240 printk(KERN_INFO "AH: %s digestsize %u != %hu\n", 252 printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
241 x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm), 253 x->aalg->alg_name, crypto_hash_digestsize(tfm),
242 aalg_desc->uinfo.auth.icv_fullbits/8); 254 aalg_desc->uinfo.auth.icv_fullbits/8);
243 goto error; 255 goto error;
244 } 256 }
@@ -262,7 +274,7 @@ static int ah_init_state(struct xfrm_state *x)
262error: 274error:
263 if (ahp) { 275 if (ahp) {
264 kfree(ahp->work_icv); 276 kfree(ahp->work_icv);
265 crypto_free_tfm(ahp->tfm); 277 crypto_free_hash(ahp->tfm);
266 kfree(ahp); 278 kfree(ahp);
267 } 279 }
268 return -EINVAL; 280 return -EINVAL;
@@ -277,7 +289,7 @@ static void ah_destroy(struct xfrm_state *x)
277 289
278 kfree(ahp->work_icv); 290 kfree(ahp->work_icv);
279 ahp->work_icv = NULL; 291 ahp->work_icv = NULL;
280 crypto_free_tfm(ahp->tfm); 292 crypto_free_hash(ahp->tfm);
281 ahp->tfm = NULL; 293 ahp->tfm = NULL;
282 kfree(ahp); 294 kfree(ahp);
283} 295}