wlantest: Support TK list for Management frame decryption
Use the TKs from the PTK file (-T command line argument) to try to decrypt encrypted Management frames if no BSS/STA key can be found based on addresses. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
fce6fb0ec2
commit
56a04ae1a1
4 changed files with 80 additions and 24 deletions
|
@ -119,19 +119,6 @@ static void rx_data_process(struct wlantest *wt, const u8 *bssid,
|
|||
}
|
||||
|
||||
|
||||
static void write_decrypted_note(struct wlantest *wt, const u8 *decrypted,
|
||||
const u8 *tk, size_t tk_len, int keyid)
|
||||
{
|
||||
char tk_hex[65];
|
||||
|
||||
if (!decrypted)
|
||||
return;
|
||||
|
||||
wpa_snprintf_hex(tk_hex, sizeof(tk_hex), tk, tk_len);
|
||||
add_note(wt, MSG_EXCESSIVE, "TK[%d] %s", keyid, tk_hex);
|
||||
}
|
||||
|
||||
|
||||
static u8 * try_ptk(int pairwise_cipher, struct wpa_ptk *ptk,
|
||||
const struct ieee80211_hdr *hdr,
|
||||
const u8 *data, size_t data_len, size_t *decrypted_len)
|
||||
|
|
|
@ -2139,6 +2139,56 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
|
|||
}
|
||||
|
||||
|
||||
static u8 * try_tk(struct wpa_ptk *ptk, const u8 *data, size_t len,
|
||||
size_t *dlen)
|
||||
{
|
||||
const struct ieee80211_hdr *hdr;
|
||||
u8 *decrypted, *frame;
|
||||
|
||||
hdr = (const struct ieee80211_hdr *) data;
|
||||
decrypted = ccmp_decrypt(ptk->tk, hdr, data + 24, len - 24, dlen);
|
||||
if (!decrypted)
|
||||
return NULL;
|
||||
|
||||
frame = os_malloc(24 + *dlen);
|
||||
if (frame) {
|
||||
os_memcpy(frame, data, 24);
|
||||
os_memcpy(frame + 24, decrypted, *dlen);
|
||||
*dlen += 24;
|
||||
}
|
||||
os_free(decrypted);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
static u8 * mgmt_ccmp_decrypt_tk(struct wlantest *wt, const u8 *data,
|
||||
size_t len, size_t *dlen)
|
||||
{
|
||||
struct wlantest_ptk *ptk;
|
||||
u8 *decrypted;
|
||||
int prev_level = wpa_debug_level;
|
||||
int keyid;
|
||||
|
||||
keyid = data[24 + 3] >> 6;
|
||||
|
||||
wpa_debug_level = MSG_WARNING;
|
||||
dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
|
||||
decrypted = try_tk(&ptk->ptk, data, len, dlen);
|
||||
if (decrypted) {
|
||||
wpa_debug_level = prev_level;
|
||||
add_note(wt, MSG_DEBUG,
|
||||
"Found TK match from the list of all known TKs");
|
||||
write_decrypted_note(wt, decrypted, ptk->ptk.tk,
|
||||
ptk->ptk.tk_len, keyid);
|
||||
return decrypted;
|
||||
}
|
||||
}
|
||||
wpa_debug_level = prev_level;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len,
|
||||
size_t *dlen)
|
||||
{
|
||||
|
@ -2150,17 +2200,6 @@ static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len,
|
|||
u8 pn[6], *rsc;
|
||||
|
||||
hdr = (const struct ieee80211_hdr *) data;
|
||||
bss = bss_get(wt, hdr->addr3);
|
||||
if (bss == NULL)
|
||||
return NULL;
|
||||
if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
|
||||
sta = sta_get(bss, hdr->addr2);
|
||||
else
|
||||
sta = sta_get(bss, hdr->addr1);
|
||||
if (sta == NULL || !sta->ptk_set) {
|
||||
add_note(wt, MSG_MSGDUMP, "No PTK known to decrypt the frame");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < 24 + 4)
|
||||
return NULL;
|
||||
|
@ -2184,6 +2223,21 @@ static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len,
|
|||
MACSTR, keyid, MAC2STR(hdr->addr2));
|
||||
}
|
||||
|
||||
bss = bss_get(wt, hdr->addr3);
|
||||
if (bss == NULL)
|
||||
return mgmt_ccmp_decrypt_tk(wt, data, len, dlen);
|
||||
if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
|
||||
sta = sta_get(bss, hdr->addr2);
|
||||
else
|
||||
sta = sta_get(bss, hdr->addr1);
|
||||
if (sta == NULL || !sta->ptk_set) {
|
||||
decrypted = mgmt_ccmp_decrypt_tk(wt, data, len, dlen);
|
||||
if (!decrypted)
|
||||
add_note(wt, MSG_MSGDUMP,
|
||||
"No PTK known to decrypt the frame");
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
|
||||
rsc = sta->rsc_tods[16];
|
||||
else
|
||||
|
|
|
@ -323,6 +323,19 @@ size_t notes_len(struct wlantest *wt, size_t hdrlen)
|
|||
}
|
||||
|
||||
|
||||
void write_decrypted_note(struct wlantest *wt, const u8 *decrypted,
|
||||
const u8 *tk, size_t tk_len, int keyid)
|
||||
{
|
||||
char tk_hex[65];
|
||||
|
||||
if (!decrypted)
|
||||
return;
|
||||
|
||||
wpa_snprintf_hex(tk_hex, sizeof(tk_hex), tk, tk_len);
|
||||
add_note(wt, MSG_EXCESSIVE, "TK[%d] %s", keyid, tk_hex);
|
||||
}
|
||||
|
||||
|
||||
int wlantest_relog(struct wlantest *wt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
|
@ -232,6 +232,8 @@ void add_note(struct wlantest *wt, int level, const char *fmt, ...)
|
|||
PRINTF_FORMAT(3, 4);
|
||||
void clear_notes(struct wlantest *wt);
|
||||
size_t notes_len(struct wlantest *wt, size_t hdrlen);
|
||||
void write_decrypted_note(struct wlantest *wt, const u8 *decrypted,
|
||||
const u8 *tk, size_t tk_len, int keyid);
|
||||
|
||||
int add_wep(struct wlantest *wt, const char *key);
|
||||
int read_cap_file(struct wlantest *wt, const char *fname);
|
||||
|
|
Loading…
Reference in a new issue