From 56d100d6eaafc54262710d13a9361b6de67532ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dr=2E=20Lars=20V=C3=B6lker?= Date: Sun, 21 Nov 2021 20:18:55 +0100 Subject: [PATCH] MKA: Adding Announcement TLV parsing and Cipher Suite This patch adds support to parse the Announcement TLV in MKA and the Cipher Suite announcement within it. --- epan/dissectors/packet-mka.c | 112 +++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/epan/dissectors/packet-mka.c b/epan/dissectors/packet-mka.c index cfa49ea308..a8f3002551 100644 --- a/epan/dissectors/packet-mka.c +++ b/epan/dissectors/packet-mka.c @@ -94,6 +94,12 @@ static int hf_mka_unknown_param_set = -1; static int hf_mka_icv = -1; +static int hf_mka_tlv_entry = -1; +static int hf_mka_tlv_type = -1; +static int hf_mka_tlv_info_string_length = -1; +static int hf_mka_tlv_data = -1; +static int hf_mka_tlv_cipher_suite_impl_cap = -1; + static expert_field ei_mka_undecoded = EI_INIT; static expert_field ei_unexpected_data = EI_INIT; static expert_field ei_mka_unimplemented = EI_INIT; @@ -109,6 +115,8 @@ static gint ett_mka_announcement_set = -1; static gint ett_mka_xpn_set = -1; static gint ett_mka_unknown_set = -1; static gint ett_mka_icv_set = -1; +static gint ett_mka_tlv = -1; +static gint ett_mka_cipher_suite_entry = -1; static const value_string param_set_type_vals[] = { { LIVE_PEER_LIST_TYPE, "Live Peer List" }, @@ -153,6 +161,19 @@ static const val64_string macsec_cipher_suite_vals[] = { { 0, NULL } }; + +static const value_string macsec_tlvs[] = { + // 0 - 110 reserved + { 111, "Access Information" }, + { 112, "MACsec Cipher Suites" }, + { 113, "Key Management Domain" }, + { 114, "NID (Network Identifier)" }, + // 115 - 125 reserved + { 126, "Organizationally Specific Set TLV" }, + { 127, "Organizationally Specific TLVs" }, + { 0, NULL } +}; + static void dissect_basic_paramset(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, int *offset_ptr) { @@ -522,6 +543,7 @@ dissect_announcement(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, in guint16 announcement_len; proto_tree *announcement_set_tree; proto_tree *ti; + int offset2; announcement_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff; ti = proto_tree_add_item(mka_tree, hf_mka_announcement_set, tvb, offset, announcement_len + 4, ENC_NA); @@ -536,8 +558,61 @@ dissect_announcement(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, in tvb, offset, 2, announcement_len); offset += 2; - // See IEEE 802.1X-2010, Section 11.11.1, Figure 11-15 and Section 11.12 - proto_tree_add_expert(announcement_set_tree, pinfo, &ei_mka_unimplemented, tvb, offset, announcement_len); + offset2 = 0; + while (offset2 + 2 <= announcement_len) { + proto_tree *tlv_tree; + guint8 tlv_type = ((tvb_get_guint8(tvb, offset + offset2)) & 0xfe ) >> 1; + guint16 tlv_length = (tvb_get_ntohs(tvb, offset + offset2)) & 0x01ff; + guint16 tlv_item_offset; + + if (offset2 + 2 + tlv_length > announcement_len) { + offset2 = announcement_len; + break; + } + + ti = proto_tree_add_none_format(announcement_set_tree, hf_mka_tlv_entry, tvb, offset + offset2, tlv_length + 2, "TLV entry: %s", + val_to_str(tlv_type, macsec_tlvs, "unknown TLV type: %d")); + tlv_tree = proto_item_add_subtree(ti, ett_mka_tlv); + + proto_tree_add_item(tlv_tree, hf_mka_tlv_type, tvb, offset + offset2, 1, ENC_NA); + proto_tree_add_item(tlv_tree, hf_mka_tlv_info_string_length, tvb, offset + offset2, 2, ENC_NA); + offset2 += 2; + + if (tlv_length > 0) { + switch (tlv_type) { + case 112: // MACsec Cipher Suites + tlv_item_offset = 0; + while (tlv_item_offset + 10 <= tlv_length) { + proto_tree *cipher_suite_entry; + guint64 cipher_suite_id = tvb_get_guint64(tvb, offset + offset2 + tlv_item_offset + 2, ENC_BIG_ENDIAN); + guint16 cipher_suite_cap = tvb_get_guint16(tvb, offset + offset2 + tlv_item_offset, ENC_BIG_ENDIAN) & 0x0003; + + ti = proto_tree_add_none_format(tlv_tree, hf_mka_tlv_entry, tvb, offset + offset2, tlv_length + 2, "Cipher Suite: %s, %s", + val64_to_str(cipher_suite_id, macsec_cipher_suite_vals, "Unknown Cipher Suite (0x%" G_GINT64_MODIFIER "x)"), + val_to_str(cipher_suite_cap, macsec_capability_type_vals, "Unknown Capability (%d)")); + cipher_suite_entry = proto_item_add_subtree(ti, ett_mka_cipher_suite_entry); + + proto_tree_add_item(cipher_suite_entry, hf_mka_tlv_cipher_suite_impl_cap, tvb, offset + offset2 + tlv_item_offset, 2, ENC_NA); + tlv_item_offset += 2; + proto_tree_add_item(cipher_suite_entry, hf_mka_macsec_cipher_suite, tvb, offset + offset2 + tlv_item_offset, 8, ENC_NA); + tlv_item_offset += 8; + } + break; + + case 111: // Access Information + case 113: // Key Management Domain + case 114: // NID (Network Identifier) + // See IEEE 802.1X-2010, Section 11.11.1, Figure 11-15 and Section 11.12 + proto_tree_add_expert(tlv_tree, pinfo, &ei_mka_unimplemented, tvb, offset + offset2, tlv_length); + proto_tree_add_item(tlv_tree, hf_mka_tlv_data, tvb, offset + offset2, tlv_length, ENC_NA); + break; + + default: + proto_tree_add_item(tlv_tree, hf_mka_tlv_data, tvb, offset + offset2, tlv_length, ENC_NA); + } + offset2 += tlv_length; + } + } offset += announcement_len; @@ -737,7 +812,7 @@ proto_register_mka(void) { &ei_unexpected_data, { "mka.expert.unexpected_data", PI_PROTOCOL, PI_WARN, "Unexpected data", EXPFILL }}, { &ei_mka_unimplemented, { - "mka.expert.unimplemented", PI_UNDECODED, PI_WARN, "Announcement TLVs not handled, if you want this implemented please contact the wireshark developers", EXPFILL }} + "mka.expert.unimplemented", PI_UNDECODED, PI_WARN, "Announcement TLV not handled, if you want this implemented please contact the wireshark developers", EXPFILL }} }; static hf_register_info hf[] = { @@ -999,7 +1074,32 @@ proto_register_mka(void) { &hf_mka_icv, { "Integrity Check Value", "mka.icv", FT_BYTES, BASE_NONE, NULL, 0x0, - NULL, HFILL }} + NULL, HFILL }}, + + { &hf_mka_tlv_entry, { + "TLV Entry", "mka.tlv_entry", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_mka_tlv_type, { + "TLV Type", "mka.tlv_type", + FT_UINT8, BASE_DEC, VALS(macsec_tlvs), 0xfe, + NULL, HFILL }}, + + { &hf_mka_tlv_info_string_length, { + "TLV Info String Length", "mka.tlv_info_string_len", + FT_UINT16, BASE_DEC, NULL, 0x01ff, + NULL, HFILL }}, + + { &hf_mka_tlv_data, { + "TLV Data", "mka.tlv_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_mka_tlv_cipher_suite_impl_cap, { + "Cipher Suite Implementation Cababilities", "mka.tlv.cipher_suite_impl_cap", + FT_UINT16, BASE_DEC, VALS(macsec_capability_type_vals), 0x0003, + NULL, HFILL }}, }; static gint *ett[] = { @@ -1013,7 +1113,9 @@ proto_register_mka(void) &ett_mka_announcement_set, &ett_mka_xpn_set, &ett_mka_unknown_set, - &ett_mka_icv_set + &ett_mka_icv_set, + &ett_mka_tlv, + &ett_mka_cipher_suite_entry }; proto_mka = proto_register_protocol("MACsec Key Agreement", "EAPOL-MKA", "mka");