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.
This commit is contained in:
Dr. Lars Völker 2021-11-21 20:18:55 +01:00
parent 730a4c0b85
commit 56d100d6ea
1 changed files with 107 additions and 5 deletions

View File

@ -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");