diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ah6.c | 35 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 42 |
2 files changed, 47 insertions, 30 deletions
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 9d4831bd4335..00ffa7bc6c9f 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -213,7 +213,10 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
213 | ah->spi = x->id.spi; | 213 | ah->spi = x->id.spi; |
214 | ah->seq_no = htonl(++x->replay.oseq); | 214 | ah->seq_no = htonl(++x->replay.oseq); |
215 | xfrm_aevent_doreplay(x); | 215 | xfrm_aevent_doreplay(x); |
216 | ahp->icv(ahp, skb, ah->auth_data); | 216 | err = ah_mac_digest(ahp, skb, ah->auth_data); |
217 | if (err) | ||
218 | goto error_free_iph; | ||
219 | memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len); | ||
217 | 220 | ||
218 | err = 0; | 221 | err = 0; |
219 | 222 | ||
@@ -251,6 +254,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
251 | u16 hdr_len; | 254 | u16 hdr_len; |
252 | u16 ah_hlen; | 255 | u16 ah_hlen; |
253 | int nexthdr; | 256 | int nexthdr; |
257 | int err = -EINVAL; | ||
254 | 258 | ||
255 | if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) | 259 | if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) |
256 | goto out; | 260 | goto out; |
@@ -292,8 +296,11 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
292 | memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); | 296 | memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); |
293 | memset(ah->auth_data, 0, ahp->icv_trunc_len); | 297 | memset(ah->auth_data, 0, ahp->icv_trunc_len); |
294 | skb_push(skb, hdr_len); | 298 | skb_push(skb, hdr_len); |
295 | ahp->icv(ahp, skb, ah->auth_data); | 299 | err = ah_mac_digest(ahp, skb, ah->auth_data); |
296 | if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { | 300 | if (err) |
301 | goto free_out; | ||
302 | err = -EINVAL; | ||
303 | if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) { | ||
297 | LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); | 304 | LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); |
298 | x->stats.integrity_failed++; | 305 | x->stats.integrity_failed++; |
299 | goto free_out; | 306 | goto free_out; |
@@ -310,7 +317,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
310 | free_out: | 317 | free_out: |
311 | kfree(tmp_hdr); | 318 | kfree(tmp_hdr); |
312 | out: | 319 | out: |
313 | return -EINVAL; | 320 | return err; |
314 | } | 321 | } |
315 | 322 | ||
316 | static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 323 | static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
@@ -338,6 +345,7 @@ static int ah6_init_state(struct xfrm_state *x) | |||
338 | { | 345 | { |
339 | struct ah_data *ahp = NULL; | 346 | struct ah_data *ahp = NULL; |
340 | struct xfrm_algo_desc *aalg_desc; | 347 | struct xfrm_algo_desc *aalg_desc; |
348 | struct crypto_hash *tfm; | ||
341 | 349 | ||
342 | if (!x->aalg) | 350 | if (!x->aalg) |
343 | goto error; | 351 | goto error; |
@@ -355,24 +363,27 @@ static int ah6_init_state(struct xfrm_state *x) | |||
355 | 363 | ||
356 | ahp->key = x->aalg->alg_key; | 364 | ahp->key = x->aalg->alg_key; |
357 | ahp->key_len = (x->aalg->alg_key_len+7)/8; | 365 | ahp->key_len = (x->aalg->alg_key_len+7)/8; |
358 | ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); | 366 | tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC); |
359 | if (!ahp->tfm) | 367 | if (IS_ERR(tfm)) |
368 | goto error; | ||
369 | |||
370 | ahp->tfm = tfm; | ||
371 | if (crypto_hash_setkey(tfm, ahp->key, ahp->key_len)) | ||
360 | goto error; | 372 | goto error; |
361 | ahp->icv = ah_hmac_digest; | ||
362 | 373 | ||
363 | /* | 374 | /* |
364 | * Lookup the algorithm description maintained by xfrm_algo, | 375 | * Lookup the algorithm description maintained by xfrm_algo, |
365 | * verify crypto transform properties, and store information | 376 | * verify crypto transform properties, and store information |
366 | * we need for AH processing. This lookup cannot fail here | 377 | * we need for AH processing. This lookup cannot fail here |
367 | * after a successful crypto_alloc_tfm(). | 378 | * after a successful crypto_alloc_hash(). |
368 | */ | 379 | */ |
369 | aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); | 380 | aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); |
370 | BUG_ON(!aalg_desc); | 381 | BUG_ON(!aalg_desc); |
371 | 382 | ||
372 | if (aalg_desc->uinfo.auth.icv_fullbits/8 != | 383 | if (aalg_desc->uinfo.auth.icv_fullbits/8 != |
373 | crypto_tfm_alg_digestsize(ahp->tfm)) { | 384 | crypto_hash_digestsize(tfm)) { |
374 | printk(KERN_INFO "AH: %s digestsize %u != %hu\n", | 385 | printk(KERN_INFO "AH: %s digestsize %u != %hu\n", |
375 | x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm), | 386 | x->aalg->alg_name, crypto_hash_digestsize(tfm), |
376 | aalg_desc->uinfo.auth.icv_fullbits/8); | 387 | aalg_desc->uinfo.auth.icv_fullbits/8); |
377 | goto error; | 388 | goto error; |
378 | } | 389 | } |
@@ -396,7 +407,7 @@ static int ah6_init_state(struct xfrm_state *x) | |||
396 | error: | 407 | error: |
397 | if (ahp) { | 408 | if (ahp) { |
398 | kfree(ahp->work_icv); | 409 | kfree(ahp->work_icv); |
399 | crypto_free_tfm(ahp->tfm); | 410 | crypto_free_hash(ahp->tfm); |
400 | kfree(ahp); | 411 | kfree(ahp); |
401 | } | 412 | } |
402 | return -EINVAL; | 413 | return -EINVAL; |
@@ -411,7 +422,7 @@ static void ah6_destroy(struct xfrm_state *x) | |||
411 | 422 | ||
412 | kfree(ahp->work_icv); | 423 | kfree(ahp->work_icv); |
413 | ahp->work_icv = NULL; | 424 | ahp->work_icv = NULL; |
414 | crypto_free_tfm(ahp->tfm); | 425 | crypto_free_hash(ahp->tfm); |
415 | ahp->tfm = NULL; | 426 | ahp->tfm = NULL; |
416 | kfree(ahp); | 427 | kfree(ahp); |
417 | } | 428 | } |
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; |