diff options
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r-- | net/ipv6/esp6.c | 42 |
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 | ||
133 | error: | 133 | error: |
@@ -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; |