RSN supplicant: 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 <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-06-29 20:15:07 +03:00
parent 72619ce61b
commit 0d15b69f0a
5 changed files with 24 additions and 19 deletions

View file

@ -674,7 +674,7 @@ static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
return; return;
} }
if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) { if (os_memcmp_const(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4", wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
ie.pmkid, PMKID_LEN); ie.pmkid, PMKID_LEN);
return; return;
@ -778,7 +778,7 @@ static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
return; return;
} }
if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) { if (os_memcmp_const(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4", wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
kde.pmkid, PMKID_LEN); kde.pmkid, PMKID_LEN);
return; return;
@ -929,7 +929,7 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
os_memset(key->key_mic, 0, 16); os_memset(key->key_mic, 0, 16);
wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
key->key_mic); key->key_mic);
if (os_memcmp(mic, key->key_mic, 16) != 0) { if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
"when using TSTK - ignoring TSTK"); "when using TSTK - ignoring TSTK");
} else { } else {
@ -945,7 +945,7 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
os_memset(key->key_mic, 0, 16); os_memset(key->key_mic, 0, 16);
wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
key->key_mic); key->key_mic);
if (os_memcmp(mic, key->key_mic, 16) != 0) { if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
"- dropping packet"); "- dropping packet");
return -1; return -1;

View file

@ -152,9 +152,9 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
while (pos) { while (pos) {
if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) { if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) {
if (pos->pmk_len == pmk_len && if (pos->pmk_len == pmk_len &&
os_memcmp(pos->pmk, pmk, pmk_len) == 0 && os_memcmp_const(pos->pmk, pmk, pmk_len) == 0 &&
os_memcmp(pos->pmkid, entry->pmkid, PMKID_LEN) == os_memcmp_const(pos->pmkid, entry->pmkid,
0) { PMKID_LEN) == 0) {
wpa_printf(MSG_DEBUG, "WPA: reusing previous " wpa_printf(MSG_DEBUG, "WPA: reusing previous "
"PMKSA entry"); "PMKSA entry");
os_free(entry); os_free(entry);

View file

@ -564,7 +564,7 @@ static int wpa_supplicant_verify_tdls_mic(u8 trans_seq,
wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid, wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid,
peer->rsnie_p, timeoutie, (u8 *) ftie, peer->rsnie_p, timeoutie, (u8 *) ftie,
mic); mic);
if (os_memcmp(mic, ftie->mic, 16) != 0) { if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - " wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - "
"dropping packet"); "dropping packet");
wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC", wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC",
@ -591,7 +591,7 @@ static int wpa_supplicant_verify_tdls_mic_teardown(
if (peer->tpk_set) { if (peer->tpk_set) {
wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode, wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode,
dtoken, lnkid, (u8 *) ftie, mic); dtoken, lnkid, (u8 *) ftie, mic);
if (os_memcmp(mic, ftie->mic, 16) != 0) { if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - " wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - "
"dropping packet"); "dropping packet");
return -1; return -1;

View file

@ -162,7 +162,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
} }
if (pmkid && sm->cur_pmksa && if (pmkid && sm->cur_pmksa &&
os_memcmp(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) { os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN); wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
wpa_sm_set_pmk_from_pmksa(sm); wpa_sm_set_pmk_from_pmksa(sm);
wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache", wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
@ -906,7 +906,8 @@ static int ft_validate_rsnie(struct wpa_sm *sm,
return -1; return -1;
} }
if (os_memcmp(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) { if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
{
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"FT: PMKR1Name mismatch in " "FT: PMKR1Name mismatch in "
"FT 4-way handshake message 3/4"); "FT 4-way handshake message 3/4");
@ -1418,7 +1419,7 @@ static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
os_memset(key->key_mic, 0, 16); os_memset(key->key_mic, 0, 16);
wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len, wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,
key->key_mic); key->key_mic);
if (os_memcmp(mic, key->key_mic, 16) != 0) { if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Invalid EAPOL-Key MIC " "WPA: Invalid EAPOL-Key MIC "
"when using TPTK - ignoring TPTK"); "when using TPTK - ignoring TPTK");
@ -1435,7 +1436,7 @@ static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
os_memset(key->key_mic, 0, 16); os_memset(key->key_mic, 0, 16);
wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len, wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,
key->key_mic); key->key_mic);
if (os_memcmp(mic, key->key_mic, 16) != 0) { if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Invalid EAPOL-Key MIC - " "WPA: Invalid EAPOL-Key MIC - "
"dropping packet"); "dropping packet");

View file

@ -442,7 +442,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
} }
if (parse.r0kh_id_len != sm->r0kh_id_len || 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 " wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
"the current R0KH-ID"); "the current R0KH-ID");
wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE", wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
@ -458,7 +459,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
} }
if (parse.rsn_pmkid == NULL || if (parse.rsn_pmkid == NULL ||
os_memcmp(parse.rsn_pmkid, sm->pmk_r0_name, WPA_PMK_NAME_LEN)) { os_memcmp_const(parse.rsn_pmkid, sm->pmk_r0_name, WPA_PMK_NAME_LEN))
{
wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name (PMKID) in " wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name (PMKID) in "
"RSNIE"); "RSNIE");
return -1; return -1;
@ -727,7 +729,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
} }
if (parse.r0kh_id_len != sm->r0kh_id_len || 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 " wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
"the current R0KH-ID"); "the current R0KH-ID");
wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE", wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
@ -742,14 +745,15 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
return -1; return -1;
} }
if (os_memcmp(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) { if (os_memcmp_const(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) {
wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in " wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
"ReassocResp"); "ReassocResp");
return -1; return -1;
} }
if (parse.rsn_pmkid == NULL || 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 " wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
"RSNIE (pmkid=%d)", !!parse.rsn_pmkid); "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
return -1; return -1;
@ -775,7 +779,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
return -1; return -1;
} }
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: Invalid MIC in FTIE");
wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16); wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16);
wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16); wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);