diff options
author | Jouni Malinen <j@w1.fi> | 2015-01-25 14:49:18 (GMT) |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2015-01-26 23:26:49 (GMT) |
commit | 98cd3d1c3b2f2081539a95be26b37aae88b2b0f5 (patch) | |
tree | 7ebb32f2312e9feff800426599b6e27e08b0106a /wlantest | |
parent | 287eb3f9d723cbba9493a89049b98c76d75e129a (diff) | |
download | hostap-98cd3d1c3b2f2081539a95be26b37aae88b2b0f5.zip hostap-98cd3d1c3b2f2081539a95be26b37aae88b2b0f5.tar.gz hostap-98cd3d1c3b2f2081539a95be26b37aae88b2b0f5.tar.bz2 |
Preparations for variable length KCK and KEK
This modifies struct wpa_ptk to allow the length of KCK and KEK to be
stored. This is needed to allow longer keys to be used, e.g., with
Suite B 192-bit level.
Signed-off-by: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wlantest')
-rw-r--r-- | wlantest/inject.c | 6 | ||||
-rw-r--r-- | wlantest/rx_data.c | 18 | ||||
-rw-r--r-- | wlantest/rx_eapol.c | 108 | ||||
-rw-r--r-- | wlantest/rx_mgmt.c | 4 | ||||
-rw-r--r-- | wlantest/wlantest.c | 12 |
5 files changed, 82 insertions, 66 deletions
diff --git a/wlantest/inject.c b/wlantest/inject.c index 04cd961..ed25033 100644 --- a/wlantest/inject.c +++ b/wlantest/inject.c @@ -1,6 +1,6 @@ /* * wlantest frame injection - * Copyright (c) 2010, Jouni Malinen <j@w1.fi> + * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -248,11 +248,11 @@ static int wlantest_inject_prot(struct wlantest *wt, struct wlantest_bss *bss, frame, len, hdrlen, qos, pn, 0, &crypt_len); else if (sta->pairwise_cipher == WPA_CIPHER_TKIP) - crypt = tkip_encrypt(incorrect_key ? dummy : sta->ptk.tk1, + crypt = tkip_encrypt(incorrect_key ? dummy : sta->ptk.tk, frame, len, hdrlen, qos, pn, 0, &crypt_len); else - crypt = ccmp_encrypt(incorrect_key ? dummy : sta->ptk.tk1, + crypt = ccmp_encrypt(incorrect_key ? dummy : sta->ptk.tk, frame, len, hdrlen, qos, pn, 0, &crypt_len); diff --git a/wlantest/rx_data.c b/wlantest/rx_data.c index 3c500d6..4c55e7d 100644 --- a/wlantest/rx_data.c +++ b/wlantest/rx_data.c @@ -1,6 +1,6 @@ /* * Received Data frame processing - * Copyright (c) 2010, Jouni Malinen <j@w1.fi> + * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -107,21 +107,21 @@ static u8 * try_all_ptk(struct wlantest *wt, int pairwise_cipher, decrypted = NULL; if ((pairwise_cipher == WPA_CIPHER_CCMP || pairwise_cipher == 0) && tk_len == 16) { - decrypted = ccmp_decrypt(ptk->ptk.tk1, hdr, data, + decrypted = ccmp_decrypt(ptk->ptk.tk, hdr, data, data_len, decrypted_len); } else if ((pairwise_cipher == WPA_CIPHER_CCMP_256 || pairwise_cipher == 0) && tk_len == 32) { - decrypted = ccmp_256_decrypt(ptk->ptk.tk1, hdr, data, + decrypted = ccmp_256_decrypt(ptk->ptk.tk, hdr, data, data_len, decrypted_len); } else if ((pairwise_cipher == WPA_CIPHER_GCMP || pairwise_cipher == WPA_CIPHER_GCMP_256 || pairwise_cipher == 0) && (tk_len == 16 || tk_len == 32)) { - decrypted = gcmp_decrypt(ptk->ptk.tk1, tk_len, hdr, + decrypted = gcmp_decrypt(ptk->ptk.tk, tk_len, hdr, data, data_len, decrypted_len); } else if ((pairwise_cipher == WPA_CIPHER_TKIP || pairwise_cipher == 0) && tk_len == 32) { - decrypted = tkip_decrypt(ptk->ptk.tk1, hdr, data, + decrypted = tkip_decrypt(ptk->ptk.tk, hdr, data, data_len, decrypted_len); } if (decrypted) { @@ -411,19 +411,19 @@ skip_replay_det: else decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen); } else if (sta->pairwise_cipher == WPA_CIPHER_TKIP) { - decrypted = tkip_decrypt(sta->ptk.tk1, hdr, data, len, &dlen); + decrypted = tkip_decrypt(sta->ptk.tk, hdr, data, len, &dlen); } else if (sta->pairwise_cipher == WPA_CIPHER_WEP40) { decrypted = wep_decrypt(wt, hdr, data, len, &dlen); } else if (sta->ptk_set) { if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256) - decrypted = ccmp_256_decrypt(sta->ptk.tk1, hdr, data, + decrypted = ccmp_256_decrypt(sta->ptk.tk, hdr, data, len, &dlen); else if (sta->pairwise_cipher == WPA_CIPHER_GCMP || sta->pairwise_cipher == WPA_CIPHER_GCMP_256) - decrypted = gcmp_decrypt(sta->ptk.tk1, sta->tk_len, + decrypted = gcmp_decrypt(sta->ptk.tk, sta->tk_len, hdr, data, len, &dlen); else - decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, + decrypted = ccmp_decrypt(sta->ptk.tk, hdr, data, len, &dlen); } else { decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data, diff --git a/wlantest/rx_eapol.c b/wlantest/rx_eapol.c index 704c0eb..04ea6ac 100644 --- a/wlantest/rx_eapol.c +++ b/wlantest/rx_eapol.c @@ -1,6 +1,6 @@ /* * Received Data frame processing for EAPOL messages - * Copyright (c) 2010, Jouni Malinen <j@w1.fi> + * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -31,14 +31,15 @@ static int is_zero(const u8 *buf, size_t len) } -static int check_mic(const u8 *kck, int akmp, int ver, const u8 *data, - size_t len) +static int check_mic(const u8 *kck, size_t kck_len, int akmp, int ver, + const u8 *data, size_t len) { u8 *buf; int ret = -1; struct ieee802_1x_hdr *hdr; struct wpa_eapol_key *key; - u8 rx_mic[16]; + u8 rx_mic[WPA_EAPOL_KEY_MIC_MAX_LEN]; + size_t mic_len = 16; buf = os_malloc(len); if (buf == NULL) @@ -47,11 +48,12 @@ static int check_mic(const u8 *kck, int akmp, int ver, const u8 *data, hdr = (struct ieee802_1x_hdr *) buf; key = (struct wpa_eapol_key *) (hdr + 1); - os_memcpy(rx_mic, key->key_mic, 16); - os_memset(key->key_mic, 0, 16); + os_memcpy(rx_mic, key->key_mic, mic_len); + os_memset(key->key_mic, 0, mic_len); - if (wpa_eapol_key_mic(kck, akmp, ver, buf, len, key->key_mic) == 0 && - os_memcmp(rx_mic, key->key_mic, 16) == 0) + if (wpa_eapol_key_mic(kck, kck_len, akmp, ver, buf, len, + key->key_mic) == 0 && + os_memcmp(rx_mic, key->key_mic, mic_len) == 0) ret = 0; os_free(buf); @@ -97,16 +99,12 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss, struct wlantest_pmk *pmk) { struct wpa_ptk ptk; - size_t ptk_len; - ptk_len = wpa_cipher_key_len(sta->pairwise_cipher) + 32; - - wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk), - "Pairwise key expansion", - bss->bssid, sta->addr, sta->anonce, sta->snonce, - (u8 *) &ptk, ptk_len, - wpa_key_mgmt_sha256(sta->key_mgmt)); - if (check_mic(ptk.kck, sta->key_mgmt, ver, data, len) < 0) + if (wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk), + "Pairwise key expansion", + bss->bssid, sta->addr, sta->anonce, sta->snonce, + &ptk, sta->key_mgmt, sta->pairwise_cipher) < 0 || + check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data, len) < 0) return -1; sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher); @@ -120,22 +118,20 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss, */ add_note(wt, MSG_DEBUG, "Derived PTK during rekeying"); os_memcpy(&sta->tptk, &ptk, sizeof(ptk)); - wpa_hexdump(MSG_DEBUG, "TPTK:KCK", sta->tptk.kck, 16); - wpa_hexdump(MSG_DEBUG, "TPTK:KEK", sta->tptk.kek, 16); - wpa_hexdump(MSG_DEBUG, "TPTK:TK1", sta->tptk.tk1, 16); - if (ptk_len > 48) - wpa_hexdump(MSG_DEBUG, "TPTK:TK2", sta->tptk.u.tk2, - 16); + wpa_hexdump(MSG_DEBUG, "TPTK:KCK", + sta->tptk.kck, sta->tptk.kck_len); + wpa_hexdump(MSG_DEBUG, "TPTK:KEK", + sta->tptk.kek, sta->tptk.kek_len); + wpa_hexdump(MSG_DEBUG, "TPTK:TK", + sta->tptk.tk, sta->tptk.tk_len); sta->tptk_set = 1; return 0; } add_note(wt, MSG_DEBUG, "Derived new PTK"); os_memcpy(&sta->ptk, &ptk, sizeof(ptk)); - wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16); - wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16); - wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16); - if (ptk_len > 48) - wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16); + wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, sta->ptk.kck_len); + wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, sta->ptk.kek_len); + wpa_hexdump(MSG_DEBUG, "PTK:TK", sta->ptk.tk, sta->ptk.tk_len); sta->ptk_set = 1; os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods)); os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds)); @@ -169,8 +165,8 @@ static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss, wpa_debug_level = MSG_WARNING; dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) { - if (check_mic(ptk->ptk.kck, sta->key_mgmt, ver, data, - len) < 0) + if (check_mic(ptk->ptk.kck, ptk->ptk.kck_len, + sta->key_mgmt, ver, data, len) < 0) continue; wpa_printf(MSG_INFO, "Pre-set PTK matches for STA " MACSTR " BSSID " MACSTR, @@ -179,12 +175,12 @@ static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss, ptk->ptk_len = 32 + wpa_cipher_key_len(sta->pairwise_cipher); os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk)); - wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16); - wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16); - wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16); - if (ptk->ptk_len > 48) - wpa_hexdump(MSG_DEBUG, "PTK:TK2", - sta->ptk.u.tk2, 16); + wpa_hexdump(MSG_DEBUG, "PTK:KCK", + sta->ptk.kck, sta->ptk.kck_len); + wpa_hexdump(MSG_DEBUG, "PTK:KEK", + sta->ptk.kek, sta->ptk.kek_len); + wpa_hexdump(MSG_DEBUG, "PTK:TK", + sta->ptk.tk, sta->ptk.tk_len); sta->ptk_set = 1; os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods)); os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds)); @@ -204,6 +200,7 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst, const struct ieee802_1x_hdr *eapol; const struct wpa_eapol_key *hdr; const u8 *key_data, *kck; + size_t kck_len; u16 key_info, key_data_len; struct wpa_eapol_ie_parse ie; @@ -238,13 +235,15 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst, } kck = sta->ptk.kck; + kck_len = sta->ptk.kck_len; if (sta->tptk_set) { add_note(wt, MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC"); kck = sta->tptk.kck; + kck_len = sta->tptk.kck_len; } - if (check_mic(kck, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK, - data, len) < 0) { + if (check_mic(kck, kck_len, sta->key_mgmt, + key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) { add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC"); return; } @@ -371,10 +370,13 @@ static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek, } -static u8 * decrypt_eapol_key_data(struct wlantest *wt, const u8 *kek, u16 ver, +static u8 * decrypt_eapol_key_data(struct wlantest *wt, const u8 *kek, + size_t kek_len, u16 ver, const struct wpa_eapol_key *hdr, size_t *len) { + if (kek_len != 16) + return NULL; switch (ver) { case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4: return decrypt_eapol_key_data_rc4(wt, kek, hdr, len); @@ -513,6 +515,7 @@ static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst, const struct ieee802_1x_hdr *eapol; const struct wpa_eapol_key *hdr; const u8 *key_data, *kck, *kek; + size_t kck_len, kek_len; int recalc = 0; u16 key_info, ver; u8 *decrypted_buf = NULL; @@ -551,15 +554,19 @@ static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst, } kek = sta->ptk.kek; + kek_len = sta->ptk.kek_len; kck = sta->ptk.kck; + kck_len = sta->ptk.kck_len; if (sta->tptk_set) { add_note(wt, MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC"); kck = sta->tptk.kck; + kck_len = sta->tptk.kck_len; kek = sta->tptk.kek; + kek_len = sta->tptk.kek_len; } - if (check_mic(kck, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK, - data, len) < 0) { + if (check_mic(kck, kck_len, sta->key_mgmt, + key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) { add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC"); return; } @@ -574,8 +581,8 @@ static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst, decrypted_len = WPA_GET_BE16(hdr->key_data_length); } else { ver = key_info & WPA_KEY_INFO_TYPE_MASK; - decrypted_buf = decrypt_eapol_key_data(wt, kek, ver, hdr, - &decrypted_len); + decrypted_buf = decrypt_eapol_key_data(wt, kek, kek_len, ver, + hdr, &decrypted_len); if (decrypted_buf == NULL) { add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data"); @@ -674,6 +681,7 @@ static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst, const struct wpa_eapol_key *hdr; u16 key_info; const u8 *kck; + size_t kck_len; wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR, MAC2STR(src), MAC2STR(dst)); @@ -699,13 +707,15 @@ static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst, } kck = sta->ptk.kck; + kck_len = sta->ptk.kck_len; if (sta->tptk_set) { add_note(wt, MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC"); kck = sta->tptk.kck; + kck_len = sta->tptk.kck_len; } - if (check_mic(kck, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK, - data, len) < 0) { + if (check_mic(kck, kck_len, sta->key_mgmt, + key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) { add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC"); return; } @@ -752,7 +762,7 @@ static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst, } if (sta->ptk_set && - check_mic(sta->ptk.kck, sta->key_mgmt, + check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) { add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC"); @@ -766,8 +776,8 @@ static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst, return; } ver = key_info & WPA_KEY_INFO_TYPE_MASK; - decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, ver, hdr, - &decrypted_len); + decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, sta->ptk.kek_len, + ver, hdr, &decrypted_len); if (decrypted == NULL) { add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data"); return; @@ -877,7 +887,7 @@ static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst, } if (sta->ptk_set && - check_mic(sta->ptk.kck, sta->key_mgmt, + check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) { add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC"); diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c index 2d7ef1d..5f60abe 100644 --- a/wlantest/rx_mgmt.c +++ b/wlantest/rx_mgmt.c @@ -1,6 +1,6 @@ /* * Received Management frame processing - * Copyright (c) 2010, Jouni Malinen <j@w1.fi> + * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -983,7 +983,7 @@ static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len, wpa_hexdump(MSG_INFO, "RSC", rsc, 6); } - decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data + 24, len - 24, dlen); + decrypted = ccmp_decrypt(sta->ptk.tk, hdr, data + 24, len - 24, dlen); if (decrypted) { os_memcpy(rsc, pn, 6); frame = os_malloc(24 + *dlen); diff --git a/wlantest/wlantest.c b/wlantest/wlantest.c index a214141..ab3b2fc 100644 --- a/wlantest/wlantest.c +++ b/wlantest/wlantest.c @@ -1,6 +1,6 @@ /* * wlantest - IEEE 802.11 protocol monitoring and testing tool - * Copyright (c) 2010-2013, Jouni Malinen <j@w1.fi> + * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -210,10 +210,16 @@ static int add_ptk_file(struct wlantest *wt, const char *ptk_file) if (p == NULL) break; if (ptk_len < 48) { - os_memcpy(p->ptk.tk1, ptk, ptk_len); + os_memcpy(p->ptk.tk, ptk, ptk_len); + p->ptk.tk_len = ptk_len; p->ptk_len = 32 + ptk_len; } else { - os_memcpy(&p->ptk, ptk, ptk_len); + os_memcpy(p->ptk.kck, ptk, 16); + p->ptk.kck_len = 16; + os_memcpy(p->ptk.kek, ptk + 16, 16); + p->ptk.kek_len = 16; + os_memcpy(p->ptk.tk, ptk + 32, ptk_len - 32); + p->ptk.tk_len = ptk_len - 32; p->ptk_len = ptk_len; } dl_list_add(&wt->ptk, &p->list); |