aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/esp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/esp4.c')
-rw-r--r--net/ipv4/esp4.c36
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 }