From 870834a19bb1efd50cc4faf098a781f5c23c994b Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 29 Jun 2014 20:15:37 +0300 Subject: [PATCH] RSN authenticator: Use os_memcmp_const() for hash/password comparisons This makes the implementation less likely to provide useful timing information to potential attackers from comparisons of information received from a remote device and private material known only by the authorized devices. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth.c | 6 +++--- src/ap/wpa_auth_ft.c | 35 +++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index a9cd6f65e..2bb8aab8b 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -1490,7 +1490,7 @@ static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len) os_memset(key->key_mic, 0, 16); if (wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, data_len, key->key_mic) || - os_memcmp(mic, key->key_mic, 16) != 0) + os_memcmp_const(mic, key->key_mic, 16) != 0) ret = -1; os_memcpy(key->key_mic, mic, 16); return ret; @@ -1877,8 +1877,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) * Verify that PMKR1Name from EAPOL-Key message 2/4 matches * with the value we derived. */ - if (os_memcmp(sm->sup_pmk_r1_name, sm->pmk_r1_name, - WPA_PMK_NAME_LEN) != 0) { + if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name, + WPA_PMK_NAME_LEN) != 0) { wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, "PMKR1Name mismatch in FT 4-way " "handshake"); diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index a80bbb7f4..e356cea48 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -235,8 +235,8 @@ static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator *wpa_auth, r0 = cache->pmk_r0; while (r0) { if (os_memcmp(r0->spa, spa, ETH_ALEN) == 0 && - os_memcmp(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN) - == 0) { + os_memcmp_const(r0->pmk_r0_name, pmk_r0_name, + WPA_PMK_NAME_LEN) == 0) { os_memcpy(pmk_r0, r0->pmk_r0, PMK_LEN); if (pairwise) *pairwise = r0->pairwise; @@ -285,8 +285,8 @@ static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth, r1 = cache->pmk_r1; while (r1) { if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 && - os_memcmp(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN) - == 0) { + os_memcmp_const(r1->pmk_r1_name, pmk_r1_name, + WPA_PMK_NAME_LEN) == 0) { os_memcpy(pmk_r1, r1->pmk_r1, PMK_LEN); if (pairwise) *pairwise = r1->pairwise; @@ -310,7 +310,8 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm, r0kh = sm->wpa_auth->conf.r0kh_list; while (r0kh) { if (r0kh->id_len == sm->r0kh_id_len && - os_memcmp(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) == 0) + os_memcmp_const(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) == + 0) break; r0kh = r0kh->next; } @@ -1013,8 +1014,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, return WLAN_STATUS_INVALID_PMKID; } - if (os_memcmp(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) - { + if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) + != 0) { wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match " "with the PMKR1Name derived from auth request"); return WLAN_STATUS_INVALID_PMKID; @@ -1060,7 +1061,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, } if (parse.r0kh_id_len != sm->r0kh_id_len || - os_memcmp(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) { + os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) + { wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with " "the current R0KH-ID"); wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE", @@ -1075,8 +1077,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, return -1; } - if (os_memcmp(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder, - FT_R1KH_ID_LEN) != 0) { + if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder, + FT_R1KH_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in " "ReassocReq"); wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE", @@ -1087,7 +1089,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, } if (parse.rsn_pmkid == NULL || - os_memcmp(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)) { + os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)) + { wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in " "RSNIE (pmkid=%d)", !!parse.rsn_pmkid); return -1; @@ -1113,7 +1116,7 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, return WLAN_STATUS_UNSPECIFIED_FAILURE; } - if (os_memcmp(mic, ftie->mic, 16) != 0) { + if (os_memcmp_const(mic, ftie->mic, 16) != 0) { wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE"); wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR, MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr)); @@ -1468,8 +1471,8 @@ static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth, return -1; } - if (os_memcmp(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN) - != 0) { + if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder, + FT_R1KH_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull response did not use a " "matching R1KH-ID"); return -1; @@ -1544,8 +1547,8 @@ static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth, return -1; } - if (os_memcmp(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN) - != 0) { + if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder, + FT_R1KH_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not use a matching " "R1KH-ID (received " MACSTR " own " MACSTR ")", MAC2STR(f.r1kh_id),