aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/esp6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r--net/ipv6/esp6.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 46a7e687948e..2ebfd281e721 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -125,9 +125,9 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
125 } 125 }
126 126
127 if (esp->auth.icv_full_len) { 127 if (esp->auth.icv_full_len) {
128 esp->auth.icv(esp, skb, (u8*)esph-skb->data, 128 err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
129 sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); 129 sizeof(*esph) + esp->conf.ivlen + clen);
130 pskb_put(skb, trailer, alen); 130 memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
131 } 131 }
132 132
133error: 133error:
@@ -162,15 +162,16 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
162 162
163 /* If integrity check is required, do this. */ 163 /* If integrity check is required, do this. */
164 if (esp->auth.icv_full_len) { 164 if (esp->auth.icv_full_len) {
165 u8 sum[esp->auth.icv_full_len]; 165 u8 sum[alen];
166 u8 sum1[alen];
167 166
168 esp->auth.icv(esp, skb, 0, skb->len-alen, sum); 167 ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
168 if (ret)
169 goto out;
169 170
170 if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) 171 if (skb_copy_bits(skb, skb->len - alen, sum, alen))
171 BUG(); 172 BUG();
172 173
173 if (unlikely(memcmp(sum, sum1, alen))) { 174 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
174 x->stats.integrity_failed++; 175 x->stats.integrity_failed++;
175 ret = -EINVAL; 176 ret = -EINVAL;
176 goto out; 177 goto out;
@@ -279,7 +280,7 @@ static void esp6_destroy(struct xfrm_state *x)
279 esp->conf.tfm = NULL; 280 esp->conf.tfm = NULL;
280 kfree(esp->conf.ivec); 281 kfree(esp->conf.ivec);
281 esp->conf.ivec = NULL; 282 esp->conf.ivec = NULL;
282 crypto_free_tfm(esp->auth.tfm); 283 crypto_free_hash(esp->auth.tfm);
283 esp->auth.tfm = NULL; 284 esp->auth.tfm = NULL;
284 kfree(esp->auth.work_icv); 285 kfree(esp->auth.work_icv);
285 esp->auth.work_icv = NULL; 286 esp->auth.work_icv = NULL;
@@ -308,24 +309,29 @@ static int esp6_init_state(struct xfrm_state *x)
308 309
309 if (x->aalg) { 310 if (x->aalg) {
310 struct xfrm_algo_desc *aalg_desc; 311 struct xfrm_algo_desc *aalg_desc;
312 struct crypto_hash *hash;
311 313
312 esp->auth.key = x->aalg->alg_key; 314 esp->auth.key = x->aalg->alg_key;
313 esp->auth.key_len = (x->aalg->alg_key_len+7)/8; 315 esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
314 esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 316 hash = crypto_alloc_hash(x->aalg->alg_name, 0,
315 if (esp->auth.tfm == NULL) 317 CRYPTO_ALG_ASYNC);
318 if (IS_ERR(hash))
319 goto error;
320
321 esp->auth.tfm = hash;
322 if (crypto_hash_setkey(hash, esp->auth.key, esp->auth.key_len))
316 goto error; 323 goto error;
317 esp->auth.icv = esp_hmac_digest;
318 324
319 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 325 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
320 BUG_ON(!aalg_desc); 326 BUG_ON(!aalg_desc);
321 327
322 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 328 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
323 crypto_tfm_alg_digestsize(esp->auth.tfm)) { 329 crypto_hash_digestsize(hash)) {
324 printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", 330 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
325 x->aalg->alg_name, 331 x->aalg->alg_name,
326 crypto_tfm_alg_digestsize(esp->auth.tfm), 332 crypto_hash_digestsize(hash),
327 aalg_desc->uinfo.auth.icv_fullbits/8); 333 aalg_desc->uinfo.auth.icv_fullbits/8);
328 goto error; 334 goto error;
329 } 335 }
330 336
331 esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 337 esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;