aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c53
1 files changed, 5 insertions, 48 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 334d21c23da9..0ae0311082fb 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -738,23 +738,17 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
738 struct in6_addr *daddr, 738 struct in6_addr *daddr,
739 struct tcphdr *th, unsigned int tcplen) 739 struct tcphdr *th, unsigned int tcplen)
740{ 740{
741 struct scatterlist sg[4];
742 __u16 data_len;
743 int block = 0;
744 __sum16 cksum;
745 struct tcp_md5sig_pool *hp; 741 struct tcp_md5sig_pool *hp;
746 struct tcp6_pseudohdr *bp; 742 struct tcp6_pseudohdr *bp;
747 struct hash_desc *desc;
748 int err; 743 int err;
749 unsigned int nbytes = 0;
750 744
751 hp = tcp_get_md5sig_pool(); 745 hp = tcp_get_md5sig_pool();
752 if (!hp) { 746 if (!hp) {
753 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__); 747 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__);
754 goto clear_hash_noput; 748 goto clear_hash_noput;
755 } 749 }
750
756 bp = &hp->md5_blk.ip6; 751 bp = &hp->md5_blk.ip6;
757 desc = &hp->md5_desc;
758 752
759 /* 1. TCP pseudo-header (RFC2460) */ 753 /* 1. TCP pseudo-header (RFC2460) */
760 ipv6_addr_copy(&bp->saddr, saddr); 754 ipv6_addr_copy(&bp->saddr, saddr);
@@ -762,51 +756,14 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
762 bp->len = htonl(tcplen); 756 bp->len = htonl(tcplen);
763 bp->protocol = htonl(IPPROTO_TCP); 757 bp->protocol = htonl(IPPROTO_TCP);
764 758
765 sg_init_table(sg, 4); 759 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
766 760 th, tcplen, hp);
767 sg_set_buf(&sg[block++], bp, sizeof(*bp));
768 nbytes += sizeof(*bp);
769
770 /* 2. TCP header, excluding options */
771 cksum = th->check;
772 th->check = 0;
773 sg_set_buf(&sg[block++], th, sizeof(*th));
774 nbytes += sizeof(*th);
775
776 /* 3. TCP segment data (if any) */
777 data_len = tcplen - (th->doff << 2);
778 if (data_len > 0) {
779 u8 *data = (u8 *)th + (th->doff << 2);
780 sg_set_buf(&sg[block++], data, data_len);
781 nbytes += data_len;
782 }
783
784 /* 4. shared key */
785 sg_set_buf(&sg[block++], key->key, key->keylen);
786 nbytes += key->keylen;
787
788 sg_mark_end(&sg[block - 1]);
789 761
790 /* Now store the hash into the packet */ 762 if (err)
791 err = crypto_hash_init(desc);
792 if (err) {
793 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
794 goto clear_hash;
795 }
796 err = crypto_hash_update(desc, sg, nbytes);
797 if (err) {
798 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
799 goto clear_hash;
800 }
801 err = crypto_hash_final(desc, md5_hash);
802 if (err) {
803 printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
804 goto clear_hash; 763 goto clear_hash;
805 }
806 764
807 /* Reset header, and free up the crypto */ 765 /* Free up the crypto pool */
808 tcp_put_md5sig_pool(); 766 tcp_put_md5sig_pool();
809 th->check = cksum;
810out: 767out:
811 return 0; 768 return 0;
812clear_hash: 769clear_hash: