]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mptcp: use untruncated hash in ADD_ADDR HMAC
authorTodd Malsbary <todd.malsbary@linux.intel.com>
Fri, 22 May 2020 02:10:49 +0000 (19:10 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 May 2020 21:21:24 +0000 (14:21 -0700)
There is some ambiguity in the RFC as to whether the ADD_ADDR HMAC is
the rightmost 64 bits of the entire hash or of the leftmost 160 bits
of the hash.  The intention, as clarified with the author of the RFC,
is the entire hash.

This change returns the entire hash from
mptcp_crypto_hmac_sha (instead of only the first 160 bits), and moves
any truncation/selection operation on the hash to the caller.

Fixes: 47236da746c3 ("mptcp: use rightmost 64 bits in ADD_ADDR HMAC")
Reviewed-by: Christoph Paasch <cpaasch@apple.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Todd Malsbary <todd.malsbary@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/crypto.c
net/mptcp/options.c
net/mptcp/protocol.h
net/mptcp/subflow.c

index c151628bd4161ac937de0bcd29d038123d03bc9c..0f5a414a936632d16a4647df26472a735611e5ce 100644 (file)
@@ -47,8 +47,6 @@ void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn)
 void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac)
 {
        u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE];
-       __be32 mptcp_hashed_key[SHA256_DIGEST_WORDS];
-       __be32 *hash_out = (__force __be32 *)hmac;
        struct sha256_state state;
        u8 key1be[8];
        u8 key2be[8];
@@ -86,11 +84,7 @@ void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac)
 
        sha256_init(&state);
        sha256_update(&state, input, SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE);
-       sha256_final(&state, (u8 *)mptcp_hashed_key);
-
-       /* takes only first 160 bits */
-       for (i = 0; i < 5; i++)
-               hash_out[i] = mptcp_hashed_key[i];
+       sha256_final(&state, (u8 *)hmac);
 }
 
 #ifdef CONFIG_MPTCP_HMAC_TEST
@@ -101,29 +95,29 @@ struct test_cast {
 };
 
 /* we can't reuse RFC 4231 test vectors, as we have constraint on the
- * input and key size, and we truncate the output.
+ * input and key size.
  */
 static struct test_cast tests[] = {
        {
                .key = "0b0b0b0b0b0b0b0b",
                .msg = "48692054",
-               .result = "8385e24fb4235ac37556b6b886db106284a1da67",
+               .result = "8385e24fb4235ac37556b6b886db106284a1da671699f46db1f235ec622dcafa",
        },
        {
                .key = "aaaaaaaaaaaaaaaa",
                .msg = "dddddddd",
-               .result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492",
+               .result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492984e1eb71aff9022f71046e9",
        },
        {
                .key = "0102030405060708",
                .msg = "cdcdcdcd",
-               .result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6",
+               .result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6f23b4d8c4da736a5dbbc6e7d",
        },
 };
 
 static int __init test_mptcp_crypto(void)
 {
-       char hmac[20], hmac_hex[41];
+       char hmac[32], hmac_hex[65];
        u32 nonce1, nonce2;
        u64 key1, key2;
        u8 msg[8];
@@ -140,11 +134,11 @@ static int __init test_mptcp_crypto(void)
                put_unaligned_be32(nonce2, &msg[4]);
 
                mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
-               for (j = 0; j < 20; ++j)
+               for (j = 0; j < 32; ++j)
                        sprintf(&hmac_hex[j << 1], "%02x", hmac[j] & 0xff);
-               hmac_hex[40] = 0;
+               hmac_hex[64] = 0;
 
-               if (memcmp(hmac_hex, tests[i].result, 40))
+               if (memcmp(hmac_hex, tests[i].result, 64))
                        pr_err("test %d failed, got %s expected %s", i,
                               hmac_hex, tests[i].result);
                else
index b88fae233a625d34c532b2bf8d4be4bd451aa5c5..7793b6011fa7bb5e241074683e567de8b8896a5d 100644 (file)
@@ -7,6 +7,7 @@
 #define pr_fmt(fmt) "MPTCP: " fmt
 
 #include <linux/kernel.h>
+#include <crypto/sha.h>
 #include <net/tcp.h>
 #include <net/mptcp.h>
 #include "protocol.h"
@@ -535,7 +536,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
 static u64 add_addr_generate_hmac(u64 key1, u64 key2, u8 addr_id,
                                  struct in_addr *addr)
 {
-       u8 hmac[MPTCP_ADDR_HMAC_LEN];
+       u8 hmac[SHA256_DIGEST_SIZE];
        u8 msg[7];
 
        msg[0] = addr_id;
@@ -545,14 +546,14 @@ static u64 add_addr_generate_hmac(u64 key1, u64 key2, u8 addr_id,
 
        mptcp_crypto_hmac_sha(key1, key2, msg, 7, hmac);
 
-       return get_unaligned_be64(&hmac[MPTCP_ADDR_HMAC_LEN - sizeof(u64)]);
+       return get_unaligned_be64(&hmac[SHA256_DIGEST_SIZE - sizeof(u64)]);
 }
 
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
 static u64 add_addr6_generate_hmac(u64 key1, u64 key2, u8 addr_id,
                                   struct in6_addr *addr)
 {
-       u8 hmac[MPTCP_ADDR_HMAC_LEN];
+       u8 hmac[SHA256_DIGEST_SIZE];
        u8 msg[19];
 
        msg[0] = addr_id;
@@ -562,7 +563,7 @@ static u64 add_addr6_generate_hmac(u64 key1, u64 key2, u8 addr_id,
 
        mptcp_crypto_hmac_sha(key1, key2, msg, 19, hmac);
 
-       return get_unaligned_be64(&hmac[MPTCP_ADDR_HMAC_LEN - sizeof(u64)]);
+       return get_unaligned_be64(&hmac[SHA256_DIGEST_SIZE - sizeof(u64)]);
 }
 #endif
 
index e4ca6320ce7679c64f588290d65b10686ee3c728..d0803dfb81082352e71e61a50d5b9fd58af5d25d 100644 (file)
@@ -81,7 +81,6 @@
 
 /* MPTCP ADD_ADDR flags */
 #define MPTCP_ADDR_ECHO                BIT(0)
-#define MPTCP_ADDR_HMAC_LEN    20
 #define MPTCP_ADDR_IPVERSION_4 4
 #define MPTCP_ADDR_IPVERSION_6 6
 
index 4931a29a6f08bb55d786031bf4b87c279d19c8d1..8968b2c065e7cf7983fb9cb31497a39353e325b4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <crypto/algapi.h>
+#include <crypto/sha.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <net/inet_hashtables.h>
@@ -89,7 +90,7 @@ static bool subflow_token_join_request(struct request_sock *req,
                                       const struct sk_buff *skb)
 {
        struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
-       u8 hmac[MPTCPOPT_HMAC_LEN];
+       u8 hmac[SHA256_DIGEST_SIZE];
        struct mptcp_sock *msk;
        int local_id;
 
@@ -201,7 +202,7 @@ static void subflow_v6_init_req(struct request_sock *req,
 /* validate received truncated hmac and create hmac for third ACK */
 static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow)
 {
-       u8 hmac[MPTCPOPT_HMAC_LEN];
+       u8 hmac[SHA256_DIGEST_SIZE];
        u64 thmac;
 
        subflow_generate_hmac(subflow->remote_key, subflow->local_key,
@@ -267,6 +268,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
                        subflow->ssn_offset = TCP_SKB_CB(skb)->seq;
                }
        } else if (subflow->mp_join) {
+               u8 hmac[SHA256_DIGEST_SIZE];
+
                pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u",
                         subflow, subflow->thmac,
                         subflow->remote_nonce);
@@ -279,7 +282,9 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
                subflow_generate_hmac(subflow->local_key, subflow->remote_key,
                                      subflow->local_nonce,
                                      subflow->remote_nonce,
-                                     subflow->hmac);
+                                     hmac);
+
+               memcpy(subflow->hmac, hmac, MPTCPOPT_HMAC_LEN);
 
                if (skb)
                        subflow->ssn_offset = TCP_SKB_CB(skb)->seq;
@@ -347,7 +352,7 @@ static bool subflow_hmac_valid(const struct request_sock *req,
                               const struct mptcp_options_received *mp_opt)
 {
        const struct mptcp_subflow_request_sock *subflow_req;
-       u8 hmac[MPTCPOPT_HMAC_LEN];
+       u8 hmac[SHA256_DIGEST_SIZE];
        struct mptcp_sock *msk;
        bool ret;
 
@@ -361,7 +366,7 @@ static bool subflow_hmac_valid(const struct request_sock *req,
                              subflow_req->local_nonce, hmac);
 
        ret = true;
-       if (crypto_memneq(hmac, mp_opt->hmac, sizeof(hmac)))
+       if (crypto_memneq(hmac, mp_opt->hmac, MPTCPOPT_HMAC_LEN))
                ret = false;
 
        sock_put((struct sock *)msk);