forked from osmocom/wireshark
mptcp: add support for sha256 hashing.
MPTCP v1 switches the default/only hash function from sha1 to sha256. Hash consistently according to the MP_CAPABLE version. Additionally update MP_CAPABLE flag handling to show the correct hash function name when dissecting v1 options. Change-Id: I632c68541d8b1fba83864b4a478ad8b411dbf0fb Reviewed-on: https://code.wireshark.org/review/35026 Petri-Dish: Pascal Quantin <pascal@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Pascal Quantin <pascal@wireshark.org>
This commit is contained in:
parent
71996e8d93
commit
1b11115ca7
|
@ -246,7 +246,8 @@ static int hf_tcp_option_mptcp_flags = -1;
|
|||
static int hf_tcp_option_mptcp_backup_flag = -1;
|
||||
static int hf_tcp_option_mptcp_checksum_flag = -1;
|
||||
static int hf_tcp_option_mptcp_B_flag = -1;
|
||||
static int hf_tcp_option_mptcp_H_flag = -1;
|
||||
static int hf_tcp_option_mptcp_H_v0_flag = -1;
|
||||
static int hf_tcp_option_mptcp_H_v1_flag = -1;
|
||||
static int hf_tcp_option_mptcp_F_flag = -1;
|
||||
static int hf_tcp_option_mptcp_m_flag = -1;
|
||||
static int hf_tcp_option_mptcp_M_flag = -1;
|
||||
|
@ -593,10 +594,18 @@ static guint32 mptcp_stream_count;
|
|||
*/
|
||||
static wmem_tree_t *mptcp_tokens = NULL;
|
||||
|
||||
static const int *tcp_option_mptcp_capable_flags[] = {
|
||||
static const int *tcp_option_mptcp_capable_v0_flags[] = {
|
||||
&hf_tcp_option_mptcp_checksum_flag,
|
||||
&hf_tcp_option_mptcp_B_flag,
|
||||
&hf_tcp_option_mptcp_H_flag,
|
||||
&hf_tcp_option_mptcp_H_v0_flag,
|
||||
&hf_tcp_option_mptcp_reserved_flag,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const int *tcp_option_mptcp_capable_v1_flags[] = {
|
||||
&hf_tcp_option_mptcp_checksum_flag,
|
||||
&hf_tcp_option_mptcp_B_flag,
|
||||
&hf_tcp_option_mptcp_H_v1_flag,
|
||||
&hf_tcp_option_mptcp_reserved_flag,
|
||||
NULL
|
||||
};
|
||||
|
@ -2574,6 +2583,24 @@ mptcp_cryptodata_sha1(const guint64 key, guint32 *token, guint64 *idsn)
|
|||
*idsn = GUINT64_FROM_BE(_isdn);
|
||||
}
|
||||
|
||||
/* Generate the initial data sequence number and MPTCP connection token from the key. */
|
||||
static void
|
||||
mptcp_cryptodata_sha256(const guint64 key, guint32 *token, guint64 *idsn)
|
||||
{
|
||||
guint8 digest_buf[HASH_SHA2_256_LENGTH];
|
||||
guint64 pseudokey = GUINT64_TO_BE(key);
|
||||
guint32 _token;
|
||||
guint64 _isdn;
|
||||
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA256, digest_buf, (const guint8 *)&pseudokey, 8);
|
||||
|
||||
/* memcpy to prevent -Wstrict-aliasing errors with GCC 4 */
|
||||
memcpy(&_token, digest_buf, sizeof(_token));
|
||||
*token = GUINT32_FROM_BE(_token);
|
||||
memcpy(&_isdn, digest_buf + HASH_SHA2_256_LENGTH - sizeof(_isdn), sizeof(_isdn));
|
||||
*idsn = GUINT64_FROM_BE(_isdn);
|
||||
}
|
||||
|
||||
|
||||
/* Print formatted list of tcp stream ids that are part of the connection */
|
||||
static void
|
||||
|
@ -4338,7 +4365,7 @@ mptcp_get_meta_from_token(struct tcp_analysis* tcpd, tcp_flow_t *tcp_flow, guint
|
|||
/* setup from_key */
|
||||
static
|
||||
struct mptcp_analysis*
|
||||
get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint64 key, guint8 hmac_algo _U_) {
|
||||
get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint8 version, guint64 key, guint8 hmac_algo _U_) {
|
||||
|
||||
guint32 token = 0;
|
||||
guint64 expected_idsn= 0;
|
||||
|
@ -4348,8 +4375,11 @@ get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint6
|
|||
return mptcpd;
|
||||
}
|
||||
|
||||
/* MPTCP only standardizes SHA1 for now. */
|
||||
mptcp_cryptodata_sha1(key, &token, &expected_idsn);
|
||||
/* MPTCP v0 only standardizes SHA1, and v1 SHA256. */
|
||||
if (version == 0)
|
||||
mptcp_cryptodata_sha1(key, &token, &expected_idsn);
|
||||
else if (version == 1)
|
||||
mptcp_cryptodata_sha256(key, &token, &expected_idsn);
|
||||
|
||||
mptcpd = mptcp_get_meta_from_token(tcpd, fwd, token);
|
||||
|
||||
|
@ -4409,6 +4439,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
|
|||
proto_item *item,*main_item;
|
||||
proto_tree *mptcp_tree;
|
||||
|
||||
guint32 version;
|
||||
guint8 subtype;
|
||||
guint8 ipver;
|
||||
int offset = 0;
|
||||
|
@ -4462,18 +4493,19 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
|
|||
case TCPOPT_MPTCP_MP_CAPABLE:
|
||||
mph->mh_mpc = TRUE;
|
||||
|
||||
proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_version, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_version, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN, &version);
|
||||
offset += 1;
|
||||
|
||||
item = proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
|
||||
ett_tcp_option_mptcp, tcp_option_mptcp_capable_flags,
|
||||
ett_tcp_option_mptcp,
|
||||
version == 1 ? tcp_option_mptcp_capable_v1_flags : tcp_option_mptcp_capable_v0_flags,
|
||||
ENC_BIG_ENDIAN);
|
||||
mph->mh_capable_flags = tvb_get_guint8(tvb, offset);
|
||||
if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) == 0) {
|
||||
expert_add_info(pinfo, item, &ei_mptcp_analysis_missing_algorithm);
|
||||
}
|
||||
if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) != MPTCP_HMAC_SHA1) {
|
||||
if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) != MPTCP_HMAC_SHA) {
|
||||
expert_add_info(pinfo, item, &ei_mptcp_analysis_unsupported_algorithm);
|
||||
}
|
||||
offset += 1;
|
||||
|
@ -4488,7 +4520,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
|
|||
proto_tree_add_uint64(mptcp_tree, hf_tcp_option_mptcp_sender_key, tvb, offset, 8, mph->mh_key);
|
||||
offset += 8;
|
||||
|
||||
mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->fwd, mph->mh_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK);
|
||||
mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->fwd, version, mph->mh_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK);
|
||||
mptcpd->master = tcpd;
|
||||
|
||||
item = proto_tree_add_uint(mptcp_tree,
|
||||
|
@ -4514,7 +4546,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
|
|||
}
|
||||
}
|
||||
else {
|
||||
mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->rev, recv_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK);
|
||||
mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->rev, version, recv_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7147,10 +7179,14 @@ proto_register_tcp(void)
|
|||
{ "Extensibility", "tcp.options.mptcp.extensibility.flag", FT_UINT8,
|
||||
BASE_DEC, NULL, 0x40, NULL, HFILL}},
|
||||
|
||||
{ &hf_tcp_option_mptcp_H_flag,
|
||||
{ &hf_tcp_option_mptcp_H_v0_flag,
|
||||
{ "Use HMAC-SHA1", "tcp.options.mptcp.sha1.flag", FT_UINT8,
|
||||
BASE_DEC, NULL, 0x01, NULL, HFILL}},
|
||||
|
||||
{ &hf_tcp_option_mptcp_H_v1_flag,
|
||||
{ "Use HMAC-SHA256", "tcp.options.mptcp.sha256.flag", FT_UINT8,
|
||||
BASE_DEC, NULL, 0x01, NULL, HFILL}},
|
||||
|
||||
{ &hf_tcp_option_mptcp_F_flag,
|
||||
{ "DATA_FIN", "tcp.options.mptcp.datafin.flag", FT_UINT8,
|
||||
BASE_DEC, NULL, MPTCP_DSS_FLAG_DATA_FIN_PRESENT, NULL, HFILL}},
|
||||
|
|
|
@ -277,7 +277,8 @@ struct mptcp_subflow {
|
|||
|
||||
typedef enum {
|
||||
MPTCP_HMAC_NOT_SET = 0,
|
||||
MPTCP_HMAC_SHA1 = 1,
|
||||
/* this is either SHA1 for MPTCP v0 or sha256 for MPTCP v1 */
|
||||
MPTCP_HMAC_SHA = 1,
|
||||
MPTCP_HMAC_LAST
|
||||
} mptcp_hmac_algorithm_t;
|
||||
|
||||
|
|
Loading…
Reference in New Issue