aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMikael Kanstrup <mikael.kanstrup@sony.com>2018-11-09 11:46:39 +0100
committerAnders Broman <a.broman58@gmail.com>2018-11-14 05:03:08 +0000
commit61ccf52107c6762288e29f752e47623ff2f26166 (patch)
treeef3826a3cc2c797550e8feebd08878f6790a2cc6 /epan
parenta51b3d1d169ddf9111fdbe63ad9acc7e626d7ee6 (diff)
ieee80211: Decrypt and dissect EAPOL keydata
Decrypt EAPOL keydata information and have it dissected with the ieee80211 dissector. This is achieved by letting the Dot11Decrypt engine retrieve the EAPOL keydata decrypted while extracting the GTK during 4-way handshake. The ieee80211 dissector then stores the decrypted data in packet proto data so that the wlan_rsna_eapol subdissector can retrieve it for dissection. Change-Id: I2145f47396cf3261b40e623fddc9ed06b3d7e72b Reviewed-on: https://code.wireshark.org/review/30530 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/crypt/dot11decrypt.c86
-rw-r--r--epan/crypt/dot11decrypt_system.h4
-rw-r--r--epan/dissectors/packet-ieee80211.c99
3 files changed, 156 insertions, 33 deletions
diff --git a/epan/crypt/dot11decrypt.c b/epan/crypt/dot11decrypt.c
index 3ff5449025..6595ca05e8 100644
--- a/epan/crypt/dot11decrypt.c
+++ b/epan/crypt/dot11decrypt.c
@@ -160,8 +160,10 @@ static INT Dot11DecryptRsna4WHandshake(
const UCHAR *data,
DOT11DECRYPT_SEC_ASSOCIATION *sa,
INT offset,
- const guint tot_len)
- ;
+ const guint tot_len,
+ UCHAR *decrypt_data,
+ guint *decrypt_len,
+ PDOT11DECRYPT_KEY_ITEM key);
/**
* It checks whether the specified key is corrected or not.
* @note
@@ -330,7 +332,10 @@ Dot11DecryptRc4KeyData(const guint8 *decryption_key, guint decryption_key_len,
/* XXX - what if this doesn't get the key? */
static INT
-Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption_key, PDOT11DECRYPT_SEC_ASSOCIATION sa, guint eapol_len)
+Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption_key,
+ PDOT11DECRYPT_SEC_ASSOCIATION sa, guint eapol_len,
+ guint8 *decrypted_data,
+ guint *decrypted_len)
{
guint8 key_version;
const guint8 *key_data;
@@ -340,6 +345,8 @@ Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decrypt
static DOT11DECRYPT_KEY_ITEM dummy_key; /* needed in case Dot11DecryptRsnaMng() wants the key structure */
DOT11DECRYPT_SEC_ASSOCIATION *tmp_sa;
+ *decrypted_len = 0;
+
/* We skip verifying the MIC of the key. If we were implementing a WPA supplicant we'd want to verify, but for a sniffer it's not needed. */
/* Preparation for decrypting the group key - determine group key data length */
@@ -388,6 +395,7 @@ Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decrypt
/* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
/* group key is decrypted using RC4. Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
guint8 new_key[32];
+ guint8 *data;
/* The WPA group key just contains the GTK bytes so deducing the type is straightforward */
/* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
@@ -397,23 +405,29 @@ Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decrypt
memcpy(new_key, pEAPKey->key_iv, 16);
memcpy(new_key+16, decryption_key, 16);
DEBUG_DUMP("FullDecrKey:", new_key, 32);
- decrypted_key = Dot11DecryptRc4KeyData(new_key, 32, key_data, key_bytes_len);
- if (!decrypted_key) {
+ data = Dot11DecryptRc4KeyData(new_key, 32, key_data, key_bytes_len);
+ if (!data) {
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
}
+ memcpy(decrypted_data, data, key_bytes_len);
+ decrypted_key = decrypted_data;
+ g_free(data);
} else if (key_version == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP){
/* AES CCMP key */
guint8 key_found;
guint8 key_length;
guint16 key_index;
- guint8 *decrypted_data;
+ guint8 *data;
/* Unwrap the key; the result is key_bytes_len in length */
- decrypted_data = AES_unwrap(decryption_key, 16, key_data, key_bytes_len);
- if (!decrypted_data) {
+ data = AES_unwrap(decryption_key, 16, key_data, key_bytes_len);
+ if (!data) {
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
}
+ key_bytes_len -= 8; /* AES-WRAP adds 8 bytes */
+ memcpy(decrypted_data, data, key_bytes_len);
+ g_free(data);
/* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure.
The key itself is stored as a GTK KDE
@@ -445,22 +459,18 @@ Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decrypt
if (key_found){
if (decrypted_data[key_index+1] <= 6) {
- g_free(decrypted_data);
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
}
key_length = decrypted_data[key_index+1] - 6;
if (key_index+8 >= key_bytes_len ||
key_length > key_bytes_len - key_index - 8) {
- g_free(decrypted_data);
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
}
- /* Skip over the GTK header info, and don't copy past the end of the encrypted data */
- decrypted_key = (guint8 *)g_memdup(decrypted_data+key_index+8, key_length);
- g_free(decrypted_data);
+ /* Skip over the GTK header info */
+ decrypted_key = decrypted_data + key_index + 8;
} else {
- g_free(decrypted_data);
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
}
@@ -473,10 +483,11 @@ Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decrypt
key_len = (sa->wpa.key_ver==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP)?TKIP_GROUP_KEY_LEN:CCMP_GROUP_KEY_LEN;
if (key_len > key_bytes_len) {
/* the key required for this protocol is longer than the key that we just calculated */
- g_free(decrypted_key);
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
}
+ *decrypted_len = key_bytes_len;
+
/* Decrypted key is now in szEncryptedKey with len of key_len */
DEBUG_DUMP("Broadcast key:", decrypted_key, key_len);
@@ -488,7 +499,6 @@ Dot11DecryptDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decrypt
/* Dot11DecryptRsnaMng() function will extract the right piece of the GTK for decryption. (The first 16 bytes of the GTK are used for decryption.) */
memset(sa->wpa.ptk, 0, sizeof(sa->wpa.ptk));
memcpy(sa->wpa.ptk+32, decrypted_key, key_len);
- g_free(decrypted_key);
return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
}
@@ -517,7 +527,10 @@ static INT Dot11DecryptScanForKeys(
const guint8 *data,
const guint mac_header_len,
const guint tot_len,
- DOT11DECRYPT_SEC_ASSOCIATION_ID id
+ DOT11DECRYPT_SEC_ASSOCIATION_ID id,
+ UCHAR *decrypt_data,
+ guint *decrypt_len,
+ PDOT11DECRYPT_KEY_ITEM key
)
{
guint tot_len_left;
@@ -623,8 +636,11 @@ static INT Dot11DecryptScanForKeys(
}
/* It could be a Pairwise Key exchange, check */
- if (Dot11DecryptRsna4WHandshake(ctx, data, sa, offset, tot_len) == DOT11DECRYPT_RET_SUCCESS_HANDSHAKE)
+ if (Dot11DecryptRsna4WHandshake(ctx, data, sa, offset, tot_len,
+ decrypt_data, decrypt_len, key) == DOT11DECRYPT_RET_SUCCESS_HANDSHAKE)
+ {
return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
+ }
if (mac_header_len + GROUP_KEY_PAYLOAD_LEN_MIN > tot_len) {
DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptScanForKeys", "Message too short for Group Key", DOT11DECRYPT_DEBUG_LEVEL_3);
@@ -670,7 +686,9 @@ static INT Dot11DecryptScanForKeys(
}
/* Try to extract the group key and install it in the SA */
- return (Dot11DecryptDecryptWPABroadcastKey(pEAPKey, sta_sa->wpa.ptk+16, sa, tot_len-offset+1));
+ Dot11DecryptCopyKey(sta_sa, key); /* save key used for decrypting broadcast key */
+ return (Dot11DecryptDecryptWPABroadcastKey(pEAPKey, sta_sa->wpa.ptk+16, sa, tot_len-offset+1,
+ decrypt_data, decrypt_len));
} else if (tot_len_left >= 10 && memcmp(data+offset, tdls_header, 10) == 0) {
const guint8 *initiator, *responder;
@@ -817,6 +835,9 @@ INT Dot11DecryptPacketProcess(
DOT11DECRYPT_DEBUG_TRACE_START("Dot11DecryptPacketProcess");
+ if (decrypt_len) {
+ *decrypt_len = 0;
+ }
if (ctx==NULL) {
DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptPacketProcess", "NULL context", DOT11DECRYPT_DEBUG_LEVEL_5);
DOT11DECRYPT_DEBUG_TRACE_END("Dot11DecryptPacketProcess");
@@ -856,12 +877,19 @@ INT Dot11DecryptPacketProcess(
return DOT11DECRYPT_RET_REQ_DATA;
}
+ if (decrypt_data==NULL) {
+ DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptPacketProcess", "no decrypt buffer, use local", DOT11DECRYPT_DEBUG_LEVEL_3);
+ decrypt_data=tmp_data;
+ decrypt_len=&tmp_len;
+ }
+
/* check if data is encrypted (use the WEP bit in the Frame Control field) */
if (DOT11DECRYPT_WEP(data[1])==0) {
if (scanHandshake) {
/* data is sent in cleartext, check if is an authentication message or end the process */
DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptPacketProcess", "Unencrypted data", DOT11DECRYPT_DEBUG_LEVEL_3);
- return (Dot11DecryptScanForKeys(ctx, data, mac_header_len, tot_len, id));
+ return (Dot11DecryptScanForKeys(ctx, data, mac_header_len, tot_len, id,
+ decrypt_data, decrypt_len, key));
}
return DOT11DECRYPT_RET_NO_DATA_ENCRYPTED;
} else {
@@ -877,12 +905,6 @@ INT Dot11DecryptPacketProcess(
/* cache offset in the packet data (to scan encryption data) */
offset = mac_header_len;
- if (decrypt_data==NULL) {
- DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptPacketProcess", "no decrypt buffer, use local", DOT11DECRYPT_DEBUG_LEVEL_3);
- decrypt_data=tmp_data;
- decrypt_len=&tmp_len;
- }
-
/* create new header and data to modify */
*decrypt_len = tot_len;
memcpy(decrypt_data, data, *decrypt_len);
@@ -928,7 +950,8 @@ INT Dot11DecryptPacketProcess(
The group key handshake could be sent at any time the AP wants to change the key (such as when
it is using key rotation) and it also could be a rekey for the Pairwise key. So we must scan every packet. */
if (scanHandshake) {
- return (Dot11DecryptScanForKeys(ctx, decrypt_data, mac_header_len, *decrypt_len, id));
+ return (Dot11DecryptScanForKeys(ctx, decrypt_data, mac_header_len, *decrypt_len, id,
+ decrypt_data, decrypt_len, key));
} else {
return DOT11DECRYPT_RET_SUCCESS;
}
@@ -1365,7 +1388,10 @@ Dot11DecryptRsna4WHandshake(
const UCHAR *data,
DOT11DECRYPT_SEC_ASSOCIATION *sa,
INT offset,
- const guint tot_len)
+ const guint tot_len,
+ UCHAR *decrypt_data,
+ guint *decrypt_len,
+ PDOT11DECRYPT_KEY_ITEM key)
{
DOT11DECRYPT_KEY_ITEM *tmp_key, *tmp_pkt_key, pkt_key;
DOT11DECRYPT_SEC_ASSOCIATION *tmp_sa;
@@ -1592,7 +1618,9 @@ Dot11DecryptRsna4WHandshake(
if (broadcast_sa == NULL){
return DOT11DECRYPT_RET_REQ_DATA;
}
- return (Dot11DecryptDecryptWPABroadcastKey(pEAPKey, sa->wpa.ptk+16, broadcast_sa, tot_len-offset+1));
+ Dot11DecryptCopyKey(sa, key); /* save key used for decrypting broadcast key */
+ return (Dot11DecryptDecryptWPABroadcastKey(pEAPKey, sa->wpa.ptk+16, broadcast_sa, tot_len-offset+1,
+ decrypt_data, decrypt_len));
}
}
diff --git a/epan/crypt/dot11decrypt_system.h b/epan/crypt/dot11decrypt_system.h
index bca4e58565..969e993a7d 100644
--- a/epan/crypt/dot11decrypt_system.h
+++ b/epan/crypt/dot11decrypt_system.h
@@ -181,7 +181,9 @@ extern "C" {
* - DOT11DECRYPT_RET_UNSUCCESS: Generic unspecified error (decrypt_data
* and decrypt_length will be not modified).
* - DOT11DECRYPT_RET_SUCCESS_HANDSHAKE: An eapol handshake packet was successfuly parsed
- * and key information extracted
+ * and key information extracted. The decrypted eapol keydata is copied to
+ * decrypt_data with keydata len in decrypt_len. key param will contain ptk
+ * used to decrypt eapol keydata.
* - DOT11DECRYPT_RET_NO_VALID_HANDSHAKE: The handshake is invalid or was not used
* for some reason. For encrypted packets decryption was still successful.
* @note
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index cb005a9bc9..5d21443462 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -82,6 +82,15 @@ void proto_register_ieee80211(void);
void proto_reg_handoff_ieee80211(void);
void proto_register_wlan_rsna_eapol(void);
+typedef struct {
+ DOT11DECRYPT_KEY_ITEM used_key;
+ guint keydata_len;
+ guint8 keydata[0]; /* dynamic size */
+} proto_eapol_keydata_t;
+
+#define PROTO_EAPOL_KEYDATA_OFFSET (offsetof(proto_eapol_keydata_t, keydata))
+#define PROTO_EAPOL_MAX_SIZE (DOT11DECRYPT_MAX_CAPLEN + PROTO_EAPOL_KEYDATA_OFFSET)
+
extern value_string_ext eap_type_vals_ext; /* from packet-eap.c */
#ifndef roundup2
@@ -234,6 +243,7 @@ typedef struct mimo_control
#define IS_DMG_KEY 1
#define IS_AP_KEY 2
#define IS_CTRL_GRANT_OR_GRANT_ACK_KEY 2
+#define EAPOL_KEY 3
/* ************************************************************************* */
/* Define some very useful macros that are used to analyze frame types etc. */
/* ************************************************************************* */
@@ -3900,6 +3910,8 @@ static int hf_ieee80211_ccmp_extiv = -1;
static int hf_ieee80211_wep_key = -1;
static int hf_ieee80211_wep_icv = -1;
static int hf_ieee80211_fc_analysis_pmk = -1;
+static int hf_ieee80211_fc_analysis_kck = -1;
+static int hf_ieee80211_fc_analysis_kek = -1;
static int hf_ieee80211_fc_analysis_tk = -1;
static int hf_ieee80211_fc_analysis_gtk = -1;
@@ -24221,8 +24233,17 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
if (enable_decryption && !pinfo->fd->flags.visited) {
const guint8 *enc_data = tvb_get_ptr(tvb, 0, hdr_len+reported_len);
/* The processing will take care of 4-way handshake sessions for WPA and WPA2 decryption */
- Dot11DecryptPacketProcess(&dot11decrypt_ctx, enc_data, hdr_len, hdr_len+reported_len, NULL, 0, NULL, TRUE);
-
+ proto_eapol_keydata_t *eapol;
+ eapol = (proto_eapol_keydata_t *)wmem_alloc(wmem_file_scope(), PROTO_EAPOL_MAX_SIZE);
+ gint ret = Dot11DecryptPacketProcess(&dot11decrypt_ctx, enc_data, hdr_len, hdr_len+reported_len,
+ eapol->keydata, &eapol->keydata_len, &eapol->used_key, TRUE);
+ if (ret == DOT11DECRYPT_RET_SUCCESS_HANDSHAKE && eapol->keydata_len > 0) {
+ /* XXX realloc data for eapol to actual size used? */
+ /* Save decrypted eapol keydata for rsna dissector */
+ p_add_proto_data(wmem_file_scope(), pinfo, proto_wlan, EAPOL_KEY, eapol);
+ } else {
+ wmem_free(wmem_file_scope(), eapol);
+ }
}
/*
* No-data frames don't have a body.
@@ -25037,6 +25058,7 @@ static int hf_wlan_rsna_eapol_wpa_keydes_id = -1;
static int hf_wlan_rsna_eapol_wpa_keydes_mic = -1;
static int hf_wlan_rsna_eapol_wpa_keydes_data_len = -1;
static int hf_wlan_rsna_eapol_wpa_keydes_data = -1;
+static int hf_wlan_rsna_eapol_wpa_keydes_padding = -1;
static gint ett_keyinfo = -1;
static gint ett_wlan_rsna_eapol_keydes_data = -1;
@@ -25108,6 +25130,22 @@ static guint16 get_mic_len(guint32 akm_suite) {
}
static int
+keydata_padding_len(tvbuff_t *tvb)
+{
+ int keydata_len = tvb_reported_length(tvb);
+ int len_no_padding = keydata_len;
+ const guint8 *keydata = tvb_get_ptr(tvb, 0, keydata_len);
+ while (len_no_padding > 0 && (keydata[len_no_padding - 1] == 0x00)) {
+ len_no_padding--;
+ }
+ if (len_no_padding > 0 && keydata[len_no_padding - 1] == 0xdd) {
+ len_no_padding--;
+ return keydata_len - len_no_padding;
+ }
+ return 0;
+}
+
+static int
dissect_wlan_rsna_eapol_wpa_or_rsn_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
int offset = 0;
@@ -25226,6 +25264,7 @@ dissect_wlan_rsna_eapol_wpa_or_rsn_key(tvbuff_t *tvb, packet_info *pinfo, proto_
PROTO_ITEM_SET_GENERATED(ti);
+ guint16 keydes_version = tvb_get_ntohs(tvb, offset) & KEY_INFO_KEYDES_VERSION_MASK;
proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_wlan_rsna_eapol_wpa_keydes_keyinfo,
ett_keyinfo, wlan_rsna_eapol_wpa_keydes_keyinfo,
ENC_BIG_ENDIAN, BMT_NO_APPEND);
@@ -25266,9 +25305,48 @@ dissect_wlan_rsna_eapol_wpa_or_rsn_key(tvbuff_t *tvb, packet_info *pinfo, proto_
!(keyinfo & KEY_INFO_KEY_TYPE_MASK)) {
/* RSN: EAPOL-Key Key Data is encrypted.
* WPA: Group Keys use encrypted Key Data.
- * Cannot parse this without knowing the key.
+ * Decryption engine has already tried to decrypt this. If decrypted it's
+ * stored in EAPOL_KEY proto data.
* IEEE 802.11i-2004 8.5.2.
*/
+ proto_eapol_keydata_t *eapol;
+ eapol = (proto_eapol_keydata_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_wlan, EAPOL_KEY);
+
+ if (eapol) {
+ int keydata_len = eapol->keydata_len;
+ tvbuff_t *next_tvb = tvb_new_child_real_data(tvb, eapol->keydata,
+ keydata_len, keydata_len);
+
+ char out_buff[SHORT_STR];
+ keydes_tree = proto_item_add_subtree(ti, ett_wlan_rsna_eapol_keydes_data);
+
+ if (keydes_version == KEYDES_VER_TYPE1) {
+ add_new_data_source(pinfo, next_tvb, "Decrypted RC4 keydata");
+ } else if (keydes_version == KEYDES_VER_TYPE2) {
+ add_new_data_source(pinfo, next_tvb, "Decrypted AES keydata");
+ int padding_len = keydata_padding_len(next_tvb);
+ ieee_80211_add_tagged_parameters(next_tvb, 0, pinfo, keydes_tree,
+ keydata_len - padding_len,
+ -1, NULL);
+ if (padding_len) {
+ proto_tree_add_item(keydes_tree, hf_wlan_rsna_eapol_wpa_keydes_padding,
+ next_tvb, keydata_len - padding_len,
+ padding_len, ENC_NA);
+ }
+ } else {
+ /* TODO? */
+ }
+ /* Also add the PTK used to to decrypt and validate the keydata. */
+ bytes_to_hexstr(out_buff, eapol->used_key.KeyData.Wpa.Ptk, 16); /* KCK is stored in PTK at offset 0 */
+ out_buff[2*16] = '\0';
+ ti = proto_tree_add_string(keydes_tree, hf_ieee80211_fc_analysis_kck, tvb, 0, 0, out_buff);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ bytes_to_hexstr(out_buff, eapol->used_key.KeyData.Wpa.Ptk+16, 16); /* KEK is stored in PTK at offset 16 */
+ out_buff[2*16] = '\0';
+ ti = proto_tree_add_string(keydes_tree, hf_ieee80211_fc_analysis_kek, tvb, 0, 0, out_buff);
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
} else {
keydes_tree = proto_item_add_subtree(ti, ett_wlan_rsna_eapol_keydes_data);
ieee_80211_add_tagged_parameters(tvb, offset, pinfo, keydes_tree,
@@ -25870,6 +25948,16 @@ proto_register_ieee80211(void)
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
+ {&hf_ieee80211_fc_analysis_kck,
+ {"KCK", "wlan.analysis.kck",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ {&hf_ieee80211_fc_analysis_kek,
+ {"KEK", "wlan.analysis.kek",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
{&hf_ieee80211_fc_analysis_tk,
{"TK", "wlan.analysis.tk",
FT_STRING, BASE_NONE, NULL, 0x0,
@@ -36957,6 +37045,11 @@ proto_register_wlan_rsna_eapol(void)
{"WPA Key Data", "wlan_rsna_eapol.keydes.data",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
+
+ {&hf_wlan_rsna_eapol_wpa_keydes_padding,
+ {"WPA Key Data Padding", "wlan_rsna_eapol.keydes.padding",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
};
static gint *tree_array[] = {