diff options
Diffstat (limited to 'net/ipv4/esp4.c')
-rw-r--r-- | net/ipv4/esp4.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 7c63ae494742..b428489f6ccd 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -121,9 +121,9 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | if (esp->auth.icv_full_len) { | 123 | if (esp->auth.icv_full_len) { |
124 | esp->auth.icv(esp, skb, (u8*)esph-skb->data, | 124 | err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data, |
125 | sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); | 125 | sizeof(*esph) + esp->conf.ivlen + clen); |
126 | pskb_put(skb, trailer, alen); | 126 | memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen); |
127 | } | 127 | } |
128 | 128 | ||
129 | ip_send_check(top_iph); | 129 | ip_send_check(top_iph); |
@@ -163,15 +163,16 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
163 | 163 | ||
164 | /* If integrity check is required, do this. */ | 164 | /* If integrity check is required, do this. */ |
165 | if (esp->auth.icv_full_len) { | 165 | if (esp->auth.icv_full_len) { |
166 | u8 sum[esp->auth.icv_full_len]; | 166 | u8 sum[alen]; |
167 | u8 sum1[alen]; | ||
168 | |||
169 | esp->auth.icv(esp, skb, 0, skb->len-alen, sum); | ||
170 | 167 | ||
171 | if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) | 168 | err = esp_mac_digest(esp, skb, 0, skb->len - alen); |
169 | if (err) | ||
170 | goto out; | ||
171 | |||
172 | if (skb_copy_bits(skb, skb->len - alen, sum, alen)) | ||
172 | BUG(); | 173 | BUG(); |
173 | 174 | ||
174 | if (unlikely(memcmp(sum, sum1, alen))) { | 175 | if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { |
175 | x->stats.integrity_failed++; | 176 | x->stats.integrity_failed++; |
176 | goto out; | 177 | goto out; |
177 | } | 178 | } |
@@ -307,7 +308,7 @@ static void esp_destroy(struct xfrm_state *x) | |||
307 | esp->conf.tfm = NULL; | 308 | esp->conf.tfm = NULL; |
308 | kfree(esp->conf.ivec); | 309 | kfree(esp->conf.ivec); |
309 | esp->conf.ivec = NULL; | 310 | esp->conf.ivec = NULL; |
310 | crypto_free_tfm(esp->auth.tfm); | 311 | crypto_free_hash(esp->auth.tfm); |
311 | esp->auth.tfm = NULL; | 312 | esp->auth.tfm = NULL; |
312 | kfree(esp->auth.work_icv); | 313 | kfree(esp->auth.work_icv); |
313 | esp->auth.work_icv = NULL; | 314 | esp->auth.work_icv = NULL; |
@@ -333,22 +334,27 @@ static int esp_init_state(struct xfrm_state *x) | |||
333 | 334 | ||
334 | if (x->aalg) { | 335 | if (x->aalg) { |
335 | struct xfrm_algo_desc *aalg_desc; | 336 | struct xfrm_algo_desc *aalg_desc; |
337 | struct crypto_hash *hash; | ||
336 | 338 | ||
337 | esp->auth.key = x->aalg->alg_key; | 339 | esp->auth.key = x->aalg->alg_key; |
338 | esp->auth.key_len = (x->aalg->alg_key_len+7)/8; | 340 | esp->auth.key_len = (x->aalg->alg_key_len+7)/8; |
339 | esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); | 341 | hash = crypto_alloc_hash(x->aalg->alg_name, 0, |
340 | if (esp->auth.tfm == NULL) | 342 | CRYPTO_ALG_ASYNC); |
343 | if (IS_ERR(hash)) | ||
344 | goto error; | ||
345 | |||
346 | esp->auth.tfm = hash; | ||
347 | if (crypto_hash_setkey(hash, esp->auth.key, esp->auth.key_len)) | ||
341 | goto error; | 348 | goto error; |
342 | esp->auth.icv = esp_hmac_digest; | ||
343 | 349 | ||
344 | aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); | 350 | aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); |
345 | BUG_ON(!aalg_desc); | 351 | BUG_ON(!aalg_desc); |
346 | 352 | ||
347 | if (aalg_desc->uinfo.auth.icv_fullbits/8 != | 353 | if (aalg_desc->uinfo.auth.icv_fullbits/8 != |
348 | crypto_tfm_alg_digestsize(esp->auth.tfm)) { | 354 | crypto_hash_digestsize(hash)) { |
349 | NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", | 355 | NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", |
350 | x->aalg->alg_name, | 356 | x->aalg->alg_name, |
351 | crypto_tfm_alg_digestsize(esp->auth.tfm), | 357 | crypto_hash_digestsize(hash), |
352 | aalg_desc->uinfo.auth.icv_fullbits/8); | 358 | aalg_desc->uinfo.auth.icv_fullbits/8); |
353 | goto error; | 359 | goto error; |
354 | } | 360 | } |