aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c52
1 files changed, 4 insertions, 48 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f25445d21bdf..e331cdbd0953 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1006,15 +1006,9 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1006 struct tcphdr *th, 1006 struct tcphdr *th,
1007 unsigned int tcplen) 1007 unsigned int tcplen)
1008{ 1008{
1009 struct scatterlist sg[4];
1010 __u16 data_len;
1011 int block = 0;
1012 __sum16 old_checksum;
1013 struct tcp_md5sig_pool *hp; 1009 struct tcp_md5sig_pool *hp;
1014 struct tcp4_pseudohdr *bp; 1010 struct tcp4_pseudohdr *bp;
1015 struct hash_desc *desc;
1016 int err; 1011 int err;
1017 unsigned int nbytes = 0;
1018 1012
1019 /* 1013 /*
1020 * Okay, so RFC2385 is turned on for this connection, 1014 * Okay, so RFC2385 is turned on for this connection,
@@ -1026,10 +1020,9 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1026 goto clear_hash_noput; 1020 goto clear_hash_noput;
1027 1021
1028 bp = &hp->md5_blk.ip4; 1022 bp = &hp->md5_blk.ip4;
1029 desc = &hp->md5_desc;
1030 1023
1031 /* 1024 /*
1032 * 1. the TCP pseudo-header (in the order: source IP address, 1025 * The TCP pseudo-header (in the order: source IP address,
1033 * destination IP address, zero-padded protocol number, and 1026 * destination IP address, zero-padded protocol number, and
1034 * segment length) 1027 * segment length)
1035 */ 1028 */
@@ -1039,50 +1032,13 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1039 bp->protocol = IPPROTO_TCP; 1032 bp->protocol = IPPROTO_TCP;
1040 bp->len = htons(tcplen); 1033 bp->len = htons(tcplen);
1041 1034
1042 sg_init_table(sg, 4); 1035 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
1043 1036 th, tcplen, hp);
1044 sg_set_buf(&sg[block++], bp, sizeof(*bp));
1045 nbytes += sizeof(*bp);
1046
1047 /* 2. the TCP header, excluding options, and assuming a
1048 * checksum of zero/
1049 */
1050 old_checksum = th->check;
1051 th->check = 0;
1052 sg_set_buf(&sg[block++], th, sizeof(struct tcphdr));
1053 nbytes += sizeof(struct tcphdr);
1054
1055 /* 3. the TCP segment data (if any) */
1056 data_len = tcplen - (th->doff << 2);
1057 if (data_len > 0) {
1058 unsigned char *data = (unsigned char *)th + (th->doff << 2);
1059 sg_set_buf(&sg[block++], data, data_len);
1060 nbytes += data_len;
1061 }
1062
1063 /* 4. an independently-specified key or password, known to both
1064 * TCPs and presumably connection-specific
1065 */
1066 sg_set_buf(&sg[block++], key->key, key->keylen);
1067 nbytes += key->keylen;
1068
1069 sg_mark_end(&sg[block - 1]);
1070
1071 /* Now store the Hash into the packet */
1072 err = crypto_hash_init(desc);
1073 if (err)
1074 goto clear_hash;
1075 err = crypto_hash_update(desc, sg, nbytes);
1076 if (err)
1077 goto clear_hash;
1078 err = crypto_hash_final(desc, md5_hash);
1079 if (err) 1037 if (err)
1080 goto clear_hash; 1038 goto clear_hash;
1081 1039
1082 /* Reset header, and free up the crypto */ 1040 /* Free up the crypto pool */
1083 tcp_put_md5sig_pool(); 1041 tcp_put_md5sig_pool();
1084 th->check = old_checksum;
1085
1086out: 1042out:
1087 return 0; 1043 return 0;
1088clear_hash: 1044clear_hash: