Messages in this thread Patch in this message | | | Date | Thu, 30 Dec 2004 03:48:36 -0500 | From | David Dillow <> | Subject | [RFC 2.6.10 10/22] AH, ESP: Add offloading of outbound packets |
| |
# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/12/30 00:44:50-05:00 dave@thedillows.org # Add crypto processing for outbound AH and ESP xfrms (IPv4). # # Signed-off-by: David Dillow <dave@thedillows.org> # # net/ipv4/esp4.c # 2004/12/30 00:44:32-05:00 dave@thedillows.org +35 -21 # Add crypto offload for outbound ESP (IPv4) xfrms. Note that we always # generate a random IV, as we are not guaranteed to have any state in # the software crypto engine (we may have always been offloaded), and # we cannot rely on secure IV generation by the NIC driver/hw. # # Signed-off-by: David Dillow <dave@thedillows.org> # # net/ipv4/ah4.c # 2004/12/30 00:44:32-05:00 dave@thedillows.org +31 -21 # Add crypto offload for outbound AH (IPv4) xfrms. Note that the NIC # driver/hw is responsible for zeroing the mutable IP header fields. # # Signed-off-by: David Dillow <dave@thedillows.org> # diff -Nru a/net/ipv4/ah4.c b/net/ipv4/ah4.c --- a/net/ipv4/ah4.c 2004-12-30 01:10:14 -05:00 +++ b/net/ipv4/ah4.c 2004-12-30 01:10:14 -05:00 @@ -83,31 +83,41 @@ ah->spi = x->id.spi; ah->seq_no = htonl(x->replay.oseq + 1); - iph->tos = top_iph->tos; - iph->ttl = top_iph->ttl; - iph->frag_off = top_iph->frag_off; - - if (top_iph->ihl != 5) { - iph->daddr = top_iph->daddr; - memcpy(iph+1, top_iph+1, top_iph->ihl*4 - sizeof(struct iphdr)); - err = ip_clear_mutable_options(top_iph, &top_iph->daddr); - if (err) + if (dst->xfrm_offload) { + err = -ENOMEM; + xfrm_offload_hold(dst->xfrm_offload); + if (skb_push_xfrm_offload(skb, dst->xfrm_offload)) { + xfrm_offload_release(dst->xfrm_offload); goto error; - } + } + } else { + /* Not offloaded, manually calculate the auth hash */ + iph->tos = top_iph->tos; + iph->ttl = top_iph->ttl; + iph->frag_off = top_iph->frag_off; + + if (top_iph->ihl != 5) { + iph->daddr = top_iph->daddr; + memcpy(iph+1, top_iph+1, top_iph->ihl*4 - sizeof(struct iphdr)); + err = ip_clear_mutable_options(top_iph, &top_iph->daddr); + if (err) + goto error; + } - top_iph->tos = 0; - top_iph->frag_off = 0; - top_iph->ttl = 0; - top_iph->check = 0; + top_iph->tos = 0; + top_iph->frag_off = 0; + top_iph->ttl = 0; + top_iph->check = 0; - ahp->icv(ahp, skb, ah->auth_data); + ahp->icv(ahp, skb, ah->auth_data); - top_iph->tos = iph->tos; - top_iph->ttl = iph->ttl; - top_iph->frag_off = iph->frag_off; - if (top_iph->ihl != 5) { - top_iph->daddr = iph->daddr; - memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr)); + top_iph->tos = iph->tos; + top_iph->ttl = iph->ttl; + top_iph->frag_off = iph->frag_off; + if (top_iph->ihl != 5) { + top_iph->daddr = iph->daddr; + memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr)); + } } /* Delay incrementing the replay sequence until we know we're going diff -Nru a/net/ipv4/esp4.c b/net/ipv4/esp4.c --- a/net/ipv4/esp4.c 2004-12-30 01:10:14 -05:00 +++ b/net/ipv4/esp4.c 2004-12-30 01:10:14 -05:00 @@ -98,33 +98,47 @@ esph->spi = x->id.spi; esph->seq_no = htonl(++x->replay.oseq); - if (esp->conf.ivlen) - crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); + if (dst->xfrm_offload) { + xfrm_offload_hold(dst->xfrm_offload); + if (skb_push_xfrm_offload(skb, dst->xfrm_offload)) { + xfrm_offload_release(dst->xfrm_offload); + goto error; + } + + if (esp->conf.ivlen) + get_random_bytes(esph->enc_data, esp->conf.ivlen); + } else { + if (esp->conf.ivlen) + crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); + + do { + struct scatterlist *sg = &esp->sgbuf[0]; - do { - struct scatterlist *sg = &esp->sgbuf[0]; + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { + sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); + if (!sg) + goto error; + } + skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); + crypto_cipher_encrypt(tfm, sg, sg, clen); + if (unlikely(sg != &esp->sgbuf[0])) + kfree(sg); + } while (0); - if (unlikely(nfrags > ESP_NUM_FAST_SG)) { - sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); - if (!sg) - goto error; + if (esp->conf.ivlen) { + memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); + crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); + } + + if (esp->auth.icv_full_len) { + esp->auth.icv(esp, skb, (u8*)esph-skb->data, + sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); } - skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); - crypto_cipher_encrypt(tfm, sg, sg, clen); - if (unlikely(sg != &esp->sgbuf[0])) - kfree(sg); - } while (0); - - if (esp->conf.ivlen) { - memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); - crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); } - if (esp->auth.icv_full_len) { - esp->auth.icv(esp, skb, (u8*)esph-skb->data, - sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); + /* Need to account for auth data, offloading or not... */ + if (esp->auth.icv_full_len) pskb_put(skb, trailer, alen); - } ip_send_check(top_iph); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |