aboutsummaryrefslogtreecommitdiff
path: root/net/ipv4/ah4.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-22 12:51:33 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-22 12:51:33 -0700
commit6bbd9b6d694ff7242d63cda2faac4bd59ee4328e (patch)
tree0641aa896e2ea01f4692973e5fbea429408854f4 /net/ipv4/ah4.c
parenta489d159229fcc07bbb7566ac4fac745b79197ad (diff)
parent3c164bd8153c4644a22dc2101b003c67cd2a0d0a (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (64 commits) [BLOCK] dm-crypt: trivial comment improvements [CRYPTO] api: Deprecate crypto_digest_* and crypto_alg_available [CRYPTO] padlock: Convert padlock-sha to use crypto_hash [CRYPTO] users: Use crypto_comp and crypto_has_* [CRYPTO] api: Add crypto_comp and crypto_has_* [CRYPTO] users: Use crypto_hash interface instead of crypto_digest [SCSI] iscsi: Use crypto_hash interface instead of crypto_digest [CRYPTO] digest: Remove old HMAC implementation [CRYPTO] doc: Update documentation for hash and me [SCTP]: Use HMAC template and hash interface [IPSEC]: Use HMAC template and hash interface [CRYPTO] tcrypt: Use HMAC template and hash interface [CRYPTO] hmac: Add crypto template implementation [CRYPTO] digest: Added user API for new hash type [CRYPTO] api: Mark parts of cipher interface as deprecated [PATCH] scatterlist: Add const to sg_set_buf/sg_init_one pointer argument [CRYPTO] drivers: Remove obsolete block cipher operations [CRYPTO] users: Use block ciphers where applicable [SUNRPC] GSS: Use block ciphers where applicable [IPSEC] ESP: Use block ciphers where applicable ...
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 1366bc6ce6a..2b98943e6b0 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -1,3 +1,4 @@
+#include <linux/err.h>
#include <linux/module.h>
#include <net/ip.h>
#include <net/xfrm.h>
@@ -97,7 +98,10 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
ah->spi = x->id.spi;
ah->seq_no = htonl(++x->replay.oseq);
xfrm_aevent_doreplay(x);
- ahp->icv(ahp, skb, ah->auth_data);
+ err = ah_mac_digest(ahp, skb, ah->auth_data);
+ if (err)
+ goto error;
+ memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len);
top_iph->tos = iph->tos;
top_iph->ttl = iph->ttl;
@@ -119,6 +123,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
{
int ah_hlen;
int ihl;
+ int err = -EINVAL;
struct iphdr *iph;
struct ip_auth_hdr *ah;
struct ah_data *ahp;
@@ -166,8 +171,11 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
skb_push(skb, ihl);
- ahp->icv(ahp, skb, ah->auth_data);
- if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
+ err = ah_mac_digest(ahp, skb, ah->auth_data);
+ if (err)
+ goto out;
+ err = -EINVAL;
+ if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
x->stats.integrity_failed++;
goto out;
}
@@ -179,7 +187,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
return 0;
out:
- return -EINVAL;
+ return err;
}
static void ah4_err(struct sk_buff *skb, u32 info)
@@ -204,6 +212,7 @@ static int ah_init_state(struct xfrm_state *x)
{
struct ah_data *ahp = NULL;
struct xfrm_algo_desc *aalg_desc;
+ struct crypto_hash *tfm;
if (!x->aalg)
goto error;
@@ -221,24 +230,27 @@ static int ah_init_state(struct xfrm_state *x)
ahp->key = x->aalg->alg_key;
ahp->key_len = (x->aalg->alg_key_len+7)/8;
- ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
- if (!ahp->tfm)
+ tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm))
+ goto error;
+
+ ahp->tfm = tfm;
+ if (crypto_hash_setkey(tfm, ahp->key, ahp->key_len))
goto error;
- ahp->icv = ah_hmac_digest;
/*
* Lookup the algorithm description maintained by xfrm_algo,
* verify crypto transform properties, and store information
* we need for AH processing. This lookup cannot fail here
- * after a successful crypto_alloc_tfm().
+ * after a successful crypto_alloc_hash().
*/
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
- crypto_tfm_alg_digestsize(ahp->tfm)) {
+ crypto_hash_digestsize(tfm)) {
printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
- x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm),
+ x->aalg->alg_name, crypto_hash_digestsize(tfm),
aalg_desc->uinfo.auth.icv_fullbits/8);
goto error;
}
@@ -262,7 +274,7 @@ static int ah_init_state(struct xfrm_state *x)
error:
if (ahp) {
kfree(ahp->work_icv);
- crypto_free_tfm(ahp->tfm);
+ crypto_free_hash(ahp->tfm);
kfree(ahp);
}
return -EINVAL;
@@ -277,7 +289,7 @@ static void ah_destroy(struct xfrm_state *x)
kfree(ahp->work_icv);
ahp->work_icv = NULL;
- crypto_free_tfm(ahp->tfm);
+ crypto_free_hash(ahp->tfm);
ahp->tfm = NULL;
kfree(ahp);
}