diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 53 |
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; | ||
810 | out: | 767 | out: |
811 | return 0; | 768 | return 0; |
812 | clear_hash: | 769 | clear_hash: |