|
@@ -526,26 +526,33 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, char __user *optval,
|
|
|
AF_INET6, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
|
|
|
}
|
|
|
|
|
|
-static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
|
|
|
- const struct in6_addr *daddr,
|
|
|
- const struct in6_addr *saddr, int nbytes)
|
|
|
+static int tcp_v6_md5_hash_headers(struct tcp_md5sig_pool *hp,
|
|
|
+ const struct in6_addr *daddr,
|
|
|
+ const struct in6_addr *saddr,
|
|
|
+ const struct tcphdr *th, int nbytes)
|
|
|
{
|
|
|
struct tcp6_pseudohdr *bp;
|
|
|
struct scatterlist sg;
|
|
|
+ struct tcphdr *_th;
|
|
|
|
|
|
- bp = &hp->md5_blk.ip6;
|
|
|
+ bp = hp->scratch;
|
|
|
/* 1. TCP pseudo-header (RFC2460) */
|
|
|
bp->saddr = *saddr;
|
|
|
bp->daddr = *daddr;
|
|
|
bp->protocol = cpu_to_be32(IPPROTO_TCP);
|
|
|
bp->len = cpu_to_be32(nbytes);
|
|
|
|
|
|
- sg_init_one(&sg, bp, sizeof(*bp));
|
|
|
- ahash_request_set_crypt(hp->md5_req, &sg, NULL, sizeof(*bp));
|
|
|
+ _th = (struct tcphdr *)(bp + 1);
|
|
|
+ memcpy(_th, th, sizeof(*th));
|
|
|
+ _th->check = 0;
|
|
|
+
|
|
|
+ sg_init_one(&sg, bp, sizeof(*bp) + sizeof(*th));
|
|
|
+ ahash_request_set_crypt(hp->md5_req, &sg, NULL,
|
|
|
+ sizeof(*bp) + sizeof(*th));
|
|
|
return crypto_ahash_update(hp->md5_req);
|
|
|
}
|
|
|
|
|
|
-static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
|
|
|
+static int tcp_v6_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
|
|
|
const struct in6_addr *daddr, struct in6_addr *saddr,
|
|
|
const struct tcphdr *th)
|
|
|
{
|
|
@@ -559,9 +566,7 @@ static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
|
|
|
|
|
|
if (crypto_ahash_init(req))
|
|
|
goto clear_hash;
|
|
|
- if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, th->doff << 2))
|
|
|
- goto clear_hash;
|
|
|
- if (tcp_md5_hash_header(hp, th))
|
|
|
+ if (tcp_v6_md5_hash_headers(hp, daddr, saddr, th, th->doff << 2))
|
|
|
goto clear_hash;
|
|
|
if (tcp_md5_hash_key(hp, key))
|
|
|
goto clear_hash;
|
|
@@ -606,9 +611,7 @@ static int tcp_v6_md5_hash_skb(char *md5_hash,
|
|
|
if (crypto_ahash_init(req))
|
|
|
goto clear_hash;
|
|
|
|
|
|
- if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, skb->len))
|
|
|
- goto clear_hash;
|
|
|
- if (tcp_md5_hash_header(hp, th))
|
|
|
+ if (tcp_v6_md5_hash_headers(hp, daddr, saddr, th, skb->len))
|
|
|
goto clear_hash;
|
|
|
if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2))
|
|
|
goto clear_hash;
|