diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2014-07-02 10:32:10 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2014-07-02 10:32:10 -0700 |
| commit | c28170251eb54dbf64a9074a07fee377587425b2 (patch) | |
| tree | ebbb5127648c86a789a927e5ef3e47acde4bddad /src | |
| parent | d30ac604c9f6da71a0dd7f46d25be05a2a62cfbb (diff) | |
| download | android_external_wpa_supplicant_8-c28170251eb54dbf64a9074a07fee377587425b2.tar.gz android_external_wpa_supplicant_8-c28170251eb54dbf64a9074a07fee377587425b2.tar.bz2 android_external_wpa_supplicant_8-c28170251eb54dbf64a9074a07fee377587425b2.zip | |
Cumulative patch from commit e376290c667e970d751acc916e0efe2ed16292ed
e376290 HS 2.0R2: Add update_identifier field to network
5bc2857 Fix some sparse warnings about u16 vs. le16
42619d6 Fix CTRL-EVENT-REGDOM-CHANGE event init= value
a520bf4 Mark function static
0cb79d3 dbus: Fix indentation level to match code logic
8f03ac9 Mark functions static
6891f0e Allow SCAN command to specify scan_ssid=1 SSIDs
18389ab WPS: Clear keys/PINs explicitly
b7175b4 Clear hostapd configuration keys explicitly
d1ecca6 HS 2.0 R2: Clear hs20-osu-client configuration keys explicitly
0a13e06 EAP server: Clear keying material on deinit
f534ee0 EAP peer: Clear keying material on deinit
19c48da Clear wpa_supplicant configuration keys explicitly
28bfa29 EAP-AKA: Remove unnecessary dead increment
62493df EAP-GPSK: Avoid dead increment by checking pos pointer
164a453 FT: Debug print extra response data
70bfc77 PCSC: Debug print extra response data
5dbbf36 Interworking: Remove unnecessary dead increment
a1e46f3 Check for no key_mgmt/proto/auth_alg entries in config writer
290ea6a Remove unnecessary tracking of first entry
d3fa2bb WFD: Explicit limit for subelement length (CID 68127)
745ef18 HS 2.0: Verify assoc_req_ie buffer size for indication elements
0233dca SAE: Use os_memcmp_const() for hash/password comparisons
34ef46c WEP shared key: Use os_memcmp_const() for hash/password comparisons
3e4b77c EAP-GTC: Use os_memcmp_const() for hash/password comparisons
a6eae3f EAP-MSCHAPv2: Use os_memcmp_const() for hash/password comparisons
30411b3 EAP-TTLS: Use os_memcmp_const() for hash/password comparisons
a564d9c EAP-MD5: Use os_memcmp_const() for hash/password comparisons
4685482 EAP-PSK: Use os_memcmp_const() for hash/password comparisons
cba0f86 EAP-PEAP: Use os_memcmp_const() for hash/password comparisons
7b1e745 EAP-LEAP: Use os_memcmp_const() for hash/password comparisons
8f92826 EAP-GPSK: Use os_memcmp_const() for hash/password comparisons
e1550d4 EAP-PAX: Use os_memcmp_const() for hash/password comparisons
c434503 EAP-FAST: Use os_memcmp_const() for hash/password comparisons
dddf7bb EAP-EKE: Use os_memcmp_const() for hash/password comparisons
dfb5608 EAP-SAKE: Use os_memcmp_const() for hash/password comparisons
05c79d6 EAP-SIM/AKA: Use os_memcmp_const() for hash/password comparisons
675ddad EAP-IKEv2: Use os_memcmp_const() for hash/password comparisons
2049a3c TLS: Use os_memcmp_const() for hash/password comparisons
a79aea5 Milenage: Use os_memcmp_const() for hash/password comparisons
05f916e AES-GCM: Use os_memcmp_const() for hash/password comparisons
87a5c93 AES-CCM: Use os_memcmp_const() for hash/password comparisons
7c24f53 EAPOL supplicant: Use os_memcmp_const() for hash/password comparisons
870834a RSN authenticator: Use os_memcmp_const() for hash/password comparisons
0d15b69 RSN supplicant: Use os_memcmp_const() for hash/password comparisons
72619ce MACsec: Use os_memcmp_const() for hash/password comparisons
c237195 RADIUS: Use os_memcmp_const() for hash/password comparisons
ce9c9bc WPS: Use os_memcmp_const() for hash/password comparisons
afc3c8b Add constant time memory comparison function os_memcmp_const
ee352f1 EAP-pwd: Add explicit total length limit
b2b8a4c EAP-SIM/AKA: Pass EAP type as argument to eap_sim_msg_finish()
f107d00 PeerKey: Clean up EAPOL-Key Key Data processing
010fc5f dbus: Clean up array-array-type property getter
Change-Id: I1dbe483be2678a7468e6955d70ea261f8e53b26d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src')
82 files changed, 466 insertions, 267 deletions
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 7535b1b7..bc9f6cf4 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -379,7 +379,7 @@ void hostapd_config_free_eap_user(struct hostapd_eap_user *user) { hostapd_config_free_radius_attr(user->accept_attr); os_free(user->identity); - os_free(user->password); + bin_clear_free(user->password, user->password_len); os_free(user); } @@ -388,7 +388,7 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys) { int i; for (i = 0; i < NUM_WEP_KEYS; i++) { - os_free(keys->key[i]); + bin_clear_free(keys->key[i], keys->len[i]); keys->key[i] = NULL; } } @@ -406,10 +406,10 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) while (psk) { prev = psk; psk = psk->next; - os_free(prev); + bin_clear_free(prev, sizeof(*prev)); } - os_free(conf->ssid.wpa_passphrase); + str_clear_free(conf->ssid.wpa_passphrase); os_free(conf->ssid.wpa_psk_file); hostapd_config_free_wep(&conf->ssid.wep); #ifdef CONFIG_FULL_DYNAMIC_VLAN diff --git a/src/ap/eap_user_db.c b/src/ap/eap_user_db.c index 371a73f2..559d77f9 100644 --- a/src/ap/eap_user_db.c +++ b/src/ap/eap_user_db.c @@ -83,7 +83,7 @@ static int get_user_cb(void *ctx, int argc, char *argv[], char *col[]) for (i = 0; i < argc; i++) { if (os_strcmp(col[i], "password") == 0 && argv[i]) { - os_free(user->password); + bin_clear_free(user->password, user->password_len); user->password_len = os_strlen(argv[i]); user->password = (u8 *) os_strdup(argv[i]); user->next = (void *) 1; @@ -118,7 +118,7 @@ static int get_wildcard_cb(void *ctx, int argc, char *argv[], char *col[]) if (len <= user->identity_len && os_memcmp(argv[id], user->identity, len) == 0 && (user->password == NULL || len > user->password_len)) { - os_free(user->password); + bin_clear_free(user->password, user->password_len); user->password_len = os_strlen(argv[id]); user->password = (u8 *) os_strdup(argv[id]); user->next = (void *) 1; @@ -158,8 +158,10 @@ eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity, return NULL; } - os_free(hapd->tmp_eap_user.identity); - os_free(hapd->tmp_eap_user.password); + bin_clear_free(hapd->tmp_eap_user.identity, + hapd->tmp_eap_user.identity_len); + bin_clear_free(hapd->tmp_eap_user.password, + hapd->tmp_eap_user.password_len); os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user)); hapd->tmp_eap_user.phase2 = phase2; hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 55b7ced8..26aca2b0 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -311,8 +311,10 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) #endif /* CONFIG_INTERWORKING */ #ifdef CONFIG_SQLITE - os_free(hapd->tmp_eap_user.identity); - os_free(hapd->tmp_eap_user.password); + bin_clear_free(hapd->tmp_eap_user.identity, + hapd->tmp_eap_user.identity_len); + bin_clear_free(hapd->tmp_eap_user.password, + hapd->tmp_eap_user.password_len); #endif /* CONFIG_SQLITE */ } diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index ca8db8fb..de1ee5ed 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -236,7 +236,8 @@ static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta, /* Transaction 3 */ if (!iswep || !sta->challenge || !challenge || - os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) { + os_memcmp_const(sta->challenge, challenge, + WLAN_AUTH_CHALLENGE_LEN)) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "shared key authentication - invalid " @@ -402,7 +403,7 @@ static int check_sae_token(struct hostapd_data *hapd, const u8 *addr, return -1; if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key), addr, ETH_ALEN, mac) < 0 || - os_memcmp(token, mac, SHA256_MAC_LEN) != 0) + os_memcmp_const(token, mac, SHA256_MAC_LEN) != 0) return -1; return 0; diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index a9cd6f65..2bb8aab8 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 a80bbb7f..8a6ca71c 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), @@ -1686,6 +1689,11 @@ int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr, return -1; } + if (end > pos) { + wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end", + pos, end - pos); + } + return 0; } diff --git a/src/common/sae.c b/src/common/sae.c index c1b488e9..b67623f8 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -1051,7 +1051,7 @@ int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len) sae->tmp->own_commit_element_ffc, verifier); - if (os_memcmp(verifier, data + 2, SHA256_MAC_LEN) != 0) { + if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) { wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch"); wpa_hexdump(MSG_DEBUG, "SAE: Received confirm", data + 2, SHA256_MAC_LEN); diff --git a/src/crypto/aes-ccm.c b/src/crypto/aes-ccm.c index d14670db..cf227785 100644 --- a/src/crypto/aes-ccm.c +++ b/src/crypto/aes-ccm.c @@ -203,7 +203,7 @@ int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, aes_encrypt_deinit(aes); - if (os_memcmp(x, t, M) != 0) { + if (os_memcmp_const(x, t, M) != 0) { wpa_printf(MSG_EXCESSIVE, "CCM: Auth mismatch"); return -1; } diff --git a/src/crypto/aes-gcm.c b/src/crypto/aes-gcm.c index 3d91c71d..84294d2d 100644 --- a/src/crypto/aes-gcm.c +++ b/src/crypto/aes-gcm.c @@ -310,7 +310,7 @@ int aes_gcm_ad(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, aes_encrypt_deinit(aes); - if (os_memcmp(tag, T, 16) != 0) { + if (os_memcmp_const(tag, T, 16) != 0) { wpa_printf(MSG_EXCESSIVE, "GCM: Tag mismatch"); return -1; } diff --git a/src/crypto/milenage.c b/src/crypto/milenage.c index a7f9c6a2..6edea57e 100644 --- a/src/crypto/milenage.c +++ b/src/crypto/milenage.c @@ -217,7 +217,7 @@ int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts, for (i = 0; i < 6; i++) sqn[i] = auts[i] ^ ak[i]; if (milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) || - memcmp(mac_s, auts + 6, 8) != 0) + os_memcmp_const(mac_s, auts + 6, 8) != 0) return -1; return 0; } @@ -312,7 +312,7 @@ int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand, wpa_hexdump(MSG_DEBUG, "Milenage: MAC_A", mac_a, 8); - if (os_memcmp(mac_a, autn + 8, 8) != 0) { + if (os_memcmp_const(mac_a, autn + 8, 8) != 0) { wpa_printf(MSG_DEBUG, "Milenage: MAC mismatch"); wpa_hexdump(MSG_DEBUG, "Milenage: Received MAC_A", autn + 8, 8); diff --git a/src/eap_common/eap_eke_common.c b/src/eap_common/eap_eke_common.c index a62ac8e0..4dfdb3f9 100644 --- a/src/eap_common/eap_eke_common.c +++ b/src/eap_common/eap_eke_common.c @@ -692,7 +692,7 @@ int eap_eke_decrypt_prot(struct eap_eke_session *sess, if (eap_eke_mac(sess->mac, sess->ki, prot + block_size, prot_len - block_size - icv_len, icv) < 0) return -1; - if (os_memcmp(icv, prot + prot_len - icv_len, icv_len) != 0) { + if (os_memcmp_const(icv, prot + prot_len - icv_len, icv_len) != 0) { wpa_printf(MSG_INFO, "EAP-EKE: ICV mismatch in Prot() data"); return -1; } diff --git a/src/eap_common/eap_gpsk_common.c b/src/eap_common/eap_gpsk_common.c index 7a33215f..8c7ae27b 100644 --- a/src/eap_common/eap_gpsk_common.c +++ b/src/eap_common/eap_gpsk_common.c @@ -284,7 +284,6 @@ int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor, u8 *pk, size_t *pk_len) { u8 *seed, *pos; - size_t seed_len; int ret; wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving keys (%d:%d)", @@ -296,8 +295,7 @@ int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor, wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len); /* Seed = RAND_Peer || ID_Peer || RAND_Server || ID_Server */ - seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len; - seed = os_malloc(seed_len); + seed = os_malloc(2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len); if (seed == NULL) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory " "for key derivation"); @@ -313,17 +311,18 @@ int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor, pos += EAP_GPSK_RAND_LEN; os_memcpy(pos, id_server, id_server_len); pos += id_server_len; - wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, seed_len); + wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, pos - seed); switch (specifier) { case EAP_GPSK_CIPHER_AES: - ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, seed_len, + ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, pos - seed, msk, emsk, sk, sk_len, pk, pk_len); break; #ifdef EAP_GPSK_SHA256 case EAP_GPSK_CIPHER_SHA256: - ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed, seed_len, + ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed, + pos - seed, msk, emsk, sk, sk_len); break; #endif /* EAP_GPSK_SHA256 */ @@ -423,7 +422,6 @@ int eap_gpsk_derive_session_id(const u8 *psk, size_t psk_len, int vendor, { u8 *seed, *pos; u8 kdf_out[16]; - size_t seed_len; int ret; wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving Session ID(%d:%d)", @@ -441,8 +439,7 @@ int eap_gpsk_derive_session_id(const u8 *psk, size_t psk_len, int vendor, * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type || * CSuite_Sel || inputString) */ - seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len; - seed = os_malloc(seed_len); + seed = os_malloc(2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len); if (seed == NULL) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory " "for Session-Id derivation"); @@ -458,11 +455,11 @@ int eap_gpsk_derive_session_id(const u8 *psk, size_t psk_len, int vendor, pos += EAP_GPSK_RAND_LEN; os_memcpy(pos, id_server, id_server_len); pos += id_server_len; - wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, seed_len); + wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, pos - seed); ret = eap_gpsk_derive_mid_helper(specifier, kdf_out, sizeof(kdf_out), - psk, seed, seed_len, + psk, seed, pos - seed, method_type); sid[0] = method_type; diff --git a/src/eap_common/eap_ikev2_common.c b/src/eap_common/eap_ikev2_common.c index da9f3cc5..585c79c4 100644 --- a/src/eap_common/eap_ikev2_common.c +++ b/src/eap_common/eap_ikev2_common.c @@ -100,7 +100,7 @@ int eap_ikev2_validate_icv(int integ_alg, struct ikev2_keys *keys, return -1; } - if (os_memcmp(icv, end - icv_len, icv_len) != 0) { + if (os_memcmp_const(icv, end - icv_len, icv_len) != 0) { wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid ICV"); wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Calculated ICV", icv, icv_len); diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c index ae021858..2adc3b37 100644 --- a/src/eap_common/eap_sim_common.c +++ b/src/eap_common/eap_sim_common.c @@ -198,7 +198,7 @@ int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req, hmac, EAP_SIM_MAC_LEN); os_free(tmp); - return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1; + return (os_memcmp_const(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1; } @@ -393,7 +393,7 @@ int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req, hmac, EAP_SIM_MAC_LEN); os_free(tmp); - return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1; + return (os_memcmp_const(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1; } @@ -972,7 +972,6 @@ u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data, struct eap_sim_msg { struct wpabuf *buf; size_t mac, iv, encr; /* index from buf */ - int type; }; @@ -986,7 +985,6 @@ struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype) if (msg == NULL) return NULL; - msg->type = type; msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN); if (msg->buf == NULL) { os_free(msg); @@ -1006,7 +1004,8 @@ struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype) } -struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut, +struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, int type, + const u8 *k_aut, const u8 *extra, size_t extra_len) { struct eap_hdr *eap; @@ -1019,7 +1018,7 @@ struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut, eap->length = host_to_be16(wpabuf_len(msg->buf)); #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME) - if (k_aut && msg->mac && msg->type == EAP_TYPE_AKA_PRIME) { + if (k_aut && msg->mac && type == EAP_TYPE_AKA_PRIME) { eap_sim_add_mac_sha256(k_aut, (u8 *) wpabuf_head(msg->buf), wpabuf_len(msg->buf), (u8 *) wpabuf_mhead(msg->buf) + diff --git a/src/eap_common/eap_sim_common.h b/src/eap_common/eap_sim_common.h index 6021bd2e..daeb0e2d 100644 --- a/src/eap_common/eap_sim_common.h +++ b/src/eap_common/eap_sim_common.h @@ -211,7 +211,8 @@ u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data, struct eap_sim_msg; struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype); -struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut, +struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, int type, + const u8 *k_aut, const u8 *extra, size_t extra_len); void eap_sim_msg_free(struct eap_sim_msg *msg); u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr, diff --git a/src/eap_common/ikev2_common.c b/src/eap_common/ikev2_common.c index b98a3e8e..3d4fb6f9 100644 --- a/src/eap_common/ikev2_common.c +++ b/src/eap_common/ikev2_common.c @@ -477,7 +477,7 @@ u8 * ikev2_decrypt_payload(int encr_id, int integ_id, "hash"); return NULL; } - if (os_memcmp(integ, hash, integ_alg->hash_len) != 0) { + if (os_memcmp_const(integ, hash, integ_alg->hash_len) != 0) { wpa_printf(MSG_INFO, "IKEV2: Incorrect Integrity Checksum " "Data"); return NULL; diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 47cbbeed..a2faeb2d 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -92,6 +92,15 @@ static void eap_notify_status(struct eap_sm *sm, const char *status, } +static void eap_sm_free_key(struct eap_sm *sm) +{ + if (sm->eapKeyData) { + bin_clear_free(sm->eapKeyData, sm->eapKeyDataLen); + sm->eapKeyData = NULL; + } +} + + static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt) { ext_password_free(sm->ext_pw_buf); @@ -159,8 +168,7 @@ SM_STATE(EAP, INITIALIZE) eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); eapol_set_bool(sm, EAPOL_eapFail, FALSE); - os_free(sm->eapKeyData); - sm->eapKeyData = NULL; + eap_sm_free_key(sm); os_free(sm->eapSessionId); sm->eapSessionId = NULL; sm->eapKeyAvailable = FALSE; @@ -404,7 +412,7 @@ SM_STATE(EAP, METHOD) if (sm->m->isKeyAvailable && sm->m->getKey && sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { - os_free(sm->eapKeyData); + eap_sm_free_key(sm); sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, &sm->eapKeyDataLen); os_free(sm->eapSessionId); @@ -1488,8 +1496,7 @@ void eap_sm_abort(struct eap_sm *sm) sm->lastRespData = NULL; wpabuf_free(sm->eapRespData); sm->eapRespData = NULL; - os_free(sm->eapKeyData); - sm->eapKeyData = NULL; + eap_sm_free_key(sm); os_free(sm->eapSessionId); sm->eapSessionId = NULL; diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c index 3f31866b..0662ae73 100644 --- a/src/eap_peer/eap_aka.c +++ b/src/eap_peer/eap_aka.c @@ -126,6 +126,21 @@ static void * eap_aka_prime_init(struct eap_sm *sm) #endif /* EAP_AKA_PRIME */ +static void eap_aka_clear_keys(struct eap_aka_data *data, int reauth) +{ + if (!reauth) { + os_memset(data->mk, 0, EAP_SIM_MK_LEN); + os_memset(data->k_aut, 0, EAP_AKA_PRIME_K_AUT_LEN); + os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN); + os_memset(data->k_re, 0, EAP_AKA_PRIME_K_RE_LEN); + } + os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN); + os_memset(data->emsk, 0, EAP_EMSK_LEN); + os_memset(data->autn, 0, EAP_AKA_AUTN_LEN); + os_memset(data->auts, 0, EAP_AKA_AUTS_LEN); +} + + static void eap_aka_deinit(struct eap_sm *sm, void *priv) { struct eap_aka_data *data = priv; @@ -135,6 +150,7 @@ static void eap_aka_deinit(struct eap_sm *sm, void *priv) os_free(data->last_eap_identity); wpabuf_free(data->id_msgs); os_free(data->network_name); + eap_aka_clear_keys(data, 0); os_free(data); } } @@ -151,7 +167,7 @@ static int eap_aka_ext_sim_req(struct eap_sm *sm, struct eap_aka_data *data) pos += os_snprintf(pos, end - pos, ":"); pos += wpa_snprintf_hex(pos, end - pos, data->rand, EAP_AKA_RAND_LEN); pos += os_snprintf(pos, end - pos, ":"); - pos += wpa_snprintf_hex(pos, end - pos, data->autn, EAP_AKA_AUTN_LEN); + wpa_snprintf_hex(pos, end - pos, data->autn, EAP_AKA_AUTN_LEN); eap_sm_request_sim(sm, req); return 1; @@ -294,7 +310,7 @@ static int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data) { u8 autn[EAP_AKA_AUTN_LEN]; os_memset(autn, '1', EAP_AKA_AUTN_LEN); - if (os_memcmp(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) { + if (os_memcmp_const(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) { wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match " "with expected value"); return -1; @@ -509,7 +525,7 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data, #endif /* EAP_AKA_PRIME */ sha1_vector(1, &addr, &len, hash); - if (os_memcmp(hash, checkcode, hash_len) != 0) { + if (os_memcmp_const(hash, checkcode, hash_len) != 0) { wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE"); return -1; } @@ -532,7 +548,7 @@ static struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id, msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, EAP_AKA_SUBTYPE_CLIENT_ERROR); eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); } @@ -549,7 +565,7 @@ static struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data, "(id=%d)", id); msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT); - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); } @@ -568,7 +584,7 @@ static struct wpabuf * eap_aka_synchronization_failure( wpa_printf(MSG_DEBUG, " AT_AUTS"); eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts, EAP_AKA_AUTS_LEN); - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); } @@ -612,7 +628,7 @@ static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm, identity, identity_len); } - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); } @@ -634,7 +650,8 @@ static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data, } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, (u8 *) "", 0); + return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, (u8 *) "", + 0); } @@ -676,7 +693,7 @@ static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data, } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, nonce_s, + return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, nonce_s, EAP_SIM_NONCE_S_LEN); } @@ -710,7 +727,7 @@ static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); } - return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0); + return eap_sim_msg_finish(msg, data->eap_method, k_aut, (u8 *) "", 0); } @@ -790,7 +807,7 @@ static struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data, EAP_AKA_SUBTYPE_CHALLENGE); wpa_printf(MSG_DEBUG, " AT_KDF"); eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0); - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); } @@ -1372,6 +1389,7 @@ static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv) data->id_msgs = NULL; data->use_result_ind = 0; data->kdf_negotiation = 0; + eap_aka_clear_keys(data, 1); } diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h index daa1d328..2591e113 100644 --- a/src/eap_peer/eap_config.h +++ b/src/eap_peer/eap_config.h @@ -157,7 +157,7 @@ struct eap_peer_config { * * If left out, this will be asked through control interface. */ - u8 *private_key_passwd; + char *private_key_passwd; /** * dh_file - File path to DH/DSA parameters file (in PEM format) @@ -289,7 +289,7 @@ struct eap_peer_config { * This field is like private_key_passwd, but used for phase 2 (inside * EAP-TTLS/PEAP/FAST tunnel) authentication. */ - u8 *private_key2_passwd; + char *private_key2_passwd; /** * dh_file2 - File path to DH/DSA parameters file (in PEM format) diff --git a/src/eap_peer/eap_eke.c b/src/eap_peer/eap_eke.c index 6818b08f..9fec66c0 100644 --- a/src/eap_peer/eap_eke.c +++ b/src/eap_peer/eap_eke.c @@ -138,7 +138,7 @@ static void eap_eke_deinit(struct eap_sm *sm, void *priv) os_free(data->serverid); os_free(data->peerid); wpabuf_free(data->msgs); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -566,8 +566,8 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_S", auth_s, data->sess.prf_len); - if (os_memcmp(auth_s, pos + data->sess.pnonce_ps_len, - data->sess.prf_len) != 0) { + if (os_memcmp_const(auth_s, pos + data->sess.pnonce_ps_len, + data->sess.prf_len) != 0) { wpa_printf(MSG_INFO, "EAP-EKE: Auth_S does not match"); return eap_eke_build_fail(data, ret, reqData, EAP_EKE_FAIL_AUTHENTICATION_FAIL); diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c index b3f6a524..0739187c 100644 --- a/src/eap_peer/eap_fast.c +++ b/src/eap_peer/eap_fast.c @@ -250,6 +250,8 @@ static void eap_fast_deinit(struct eap_sm *sm, void *priv) pac = pac->next; eap_fast_free_pac(prev); } + os_memset(data->key_data, 0, EAP_FAST_KEY_LEN); + os_memset(data->emsk, 0, EAP_EMSK_LEN); os_free(data->session_id); wpabuf_free(data->pending_phase2_req); os_free(data); @@ -767,7 +769,7 @@ static struct wpabuf * eap_fast_process_crypto_binding( "MAC calculation", (u8 *) _bind, bind_len); hmac_sha1(cmk, EAP_FAST_CMK_LEN, (u8 *) _bind, bind_len, _bind->compound_mac); - res = os_memcmp(cmac, _bind->compound_mac, sizeof(cmac)); + res = os_memcmp_const(cmac, _bind->compound_mac, sizeof(cmac)); wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Received Compound MAC", cmac, sizeof(cmac)); wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Calculated Compound MAC", @@ -1636,6 +1638,8 @@ static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv) os_free(data); return NULL; } + os_memset(data->key_data, 0, EAP_FAST_KEY_LEN); + os_memset(data->emsk, 0, EAP_EMSK_LEN); os_free(data->session_id); data->session_id = NULL; if (data->phase2_priv && data->phase2_method && diff --git a/src/eap_peer/eap_gpsk.c b/src/eap_peer/eap_gpsk.c index 3c9cbf4a..c54bf116 100644 --- a/src/eap_peer/eap_gpsk.c +++ b/src/eap_peer/eap_gpsk.c @@ -134,8 +134,11 @@ static void eap_gpsk_deinit(struct eap_sm *sm, void *priv) struct eap_gpsk_data *data = priv; os_free(data->id_server); os_free(data->id_peer); - os_free(data->psk); - os_free(data); + if (data->psk) { + os_memset(data->psk, 0, data->psk_len); + os_free(data->psk); + } + bin_clear_free(data, sizeof(*data)); } @@ -565,7 +568,7 @@ static const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data, wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC"); return NULL; } - if (os_memcmp(mic, pos, miclen) != 0) { + if (os_memcmp_const(mic, pos, miclen) != 0) { wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-3"); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen); diff --git a/src/eap_peer/eap_ikev2.c b/src/eap_peer/eap_ikev2.c index 568a4480..c12b5193 100644 --- a/src/eap_peer/eap_ikev2.c +++ b/src/eap_peer/eap_ikev2.c @@ -113,7 +113,7 @@ static void eap_ikev2_deinit(struct eap_sm *sm, void *priv) wpabuf_free(data->in_buf); wpabuf_free(data->out_buf); ikev2_responder_deinit(&data->ikev2); - os_free(data); + bin_clear_free(data, sizeof(*data)); } diff --git a/src/eap_peer/eap_leap.c b/src/eap_peer/eap_leap.c index df340138..e0f8bcf6 100644 --- a/src/eap_peer/eap_leap.c +++ b/src/eap_peer/eap_leap.c @@ -244,7 +244,7 @@ static struct wpabuf * eap_leap_process_response(struct eap_sm *sm, void *priv, ret->methodState = METHOD_DONE; ret->allowNotifications = FALSE; - if (os_memcmp(pos, expected, LEAP_RESPONSE_LEN) != 0) { + if (os_memcmp_const(pos, expected, LEAP_RESPONSE_LEN) != 0) { wpa_printf(MSG_WARNING, "EAP-LEAP: AP sent an invalid " "response - authentication failed"); wpa_hexdump(MSG_DEBUG, "EAP-LEAP: Expected response from AP", @@ -383,6 +383,9 @@ static u8 * eap_leap_getKey(struct eap_sm *sm, void *priv, size_t *len) wpa_hexdump_key(MSG_DEBUG, "EAP-LEAP: master key", key, LEAP_KEY_LEN); *len = LEAP_KEY_LEN; + os_memset(pw_hash, 0, sizeof(pw_hash)); + os_memset(pw_hash_hash, 0, sizeof(pw_hash_hash)); + return key; } diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c index f2fcc371..430c501b 100644 --- a/src/eap_peer/eap_mschapv2.c +++ b/src/eap_peer/eap_mschapv2.c @@ -140,7 +140,7 @@ static void eap_mschapv2_deinit(struct eap_sm *sm, void *priv) os_free(data->peer_challenge); os_free(data->auth_challenge); wpabuf_free(data->prev_challenge); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -303,7 +303,7 @@ static void eap_mschapv2_password_changed(struct eap_sm *sm, WPA_EVENT_PASSWORD_CHANGED "EAP-MSCHAPV2: Password changed successfully"); data->prev_error = 0; - os_free(config->password); + bin_clear_free(config->password, config->password_len); if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { /* TODO: update external storage */ } else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) { @@ -313,11 +313,13 @@ static void eap_mschapv2_password_changed(struct eap_sm *sm, nt_password_hash(config->new_password, config->new_password_len, config->password)) { - os_free(config->password); + bin_clear_free(config->password, + config->password_len); config->password = NULL; config->password_len = 0; } - os_free(config->new_password); + bin_clear_free(config->new_password, + config->new_password_len); } else { config->password = config->new_password; config->password_len = config->new_password_len; diff --git a/src/eap_peer/eap_pax.c b/src/eap_peer/eap_pax.c index 7f870520..1c111c28 100644 --- a/src/eap_peer/eap_pax.c +++ b/src/eap_peer/eap_pax.c @@ -86,7 +86,7 @@ static void eap_pax_deinit(struct eap_sm *sm, void *priv) { struct eap_pax_data *data = priv; os_free(data->cid); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -278,7 +278,7 @@ static struct wpabuf * eap_pax_process_std_3(struct eap_pax_data *data, eap_pax_mac(data->mac_id, data->ck, EAP_PAX_CK_LEN, data->rand.r.y, EAP_PAX_RAND_LEN, (u8 *) data->cid, data->cid_len, NULL, 0, mac); - if (os_memcmp(pos, mac, EAP_PAX_MAC_LEN) != 0) { + if (os_memcmp_const(pos, mac, EAP_PAX_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-PAX: Invalid MAC_CK(B, CID) " "received"); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: expected MAC_CK(B, CID)", @@ -415,7 +415,7 @@ static struct wpabuf * eap_pax_process(struct eap_sm *sm, void *priv, wpabuf_head(reqData), mlen, NULL, 0, NULL, 0, icvbuf); } - if (os_memcmp(icv, icvbuf, EAP_PAX_ICV_LEN) != 0) { + if (os_memcmp_const(icv, icvbuf, EAP_PAX_ICV_LEN) != 0) { wpa_printf(MSG_DEBUG, "EAP-PAX: invalid ICV - ignoring the " "message"); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: expected ICV", diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c index 8634f754..472e861b 100644 --- a/src/eap_peer/eap_peap.c +++ b/src/eap_peer/eap_peap.c @@ -170,6 +170,15 @@ static void * eap_peap_init(struct eap_sm *sm) } +static void eap_peap_free_key(struct eap_peap_data *data) +{ + if (data->key_data) { + bin_clear_free(data->key_data, EAP_TLS_KEY_LEN); + data->key_data = NULL; + } +} + + static void eap_peap_deinit(struct eap_sm *sm, void *priv) { struct eap_peap_data *data = priv; @@ -179,7 +188,7 @@ static void eap_peap_deinit(struct eap_sm *sm, void *priv) data->phase2_method->deinit(sm, data->phase2_priv); os_free(data->phase2_types); eap_peer_tls_ssl_deinit(sm, &data->ssl); - os_free(data->key_data); + eap_peap_free_key(data); os_free(data->session_id); wpabuf_free(data->pending_phase2_req); os_free(data); @@ -423,7 +432,7 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm, buf, sizeof(buf)); hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac); - if (os_memcmp(mac, pos, SHA1_MAC_LEN) != 0) { + if (os_memcmp_const(mac, pos, SHA1_MAC_LEN) != 0) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in " "cryptobinding TLV"); wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received MAC", @@ -1005,7 +1014,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, char *label; wpa_printf(MSG_DEBUG, "EAP-PEAP: TLS done, proceed to Phase 2"); - os_free(data->key_data); + eap_peap_free_key(data); /* draft-josefsson-ppext-eap-tls-eap-05.txt * specifies that PEAPv1 would use "client PEAP * encryption" as the label. However, most existing @@ -1115,8 +1124,7 @@ static void eap_peap_deinit_for_reauth(struct eap_sm *sm, void *priv) static void * eap_peap_init_for_reauth(struct eap_sm *sm, void *priv) { struct eap_peap_data *data = priv; - os_free(data->key_data); - data->key_data = NULL; + eap_peap_free_key(data); os_free(data->session_id); data->session_id = NULL; if (eap_peer_tls_reauth_init(sm, &data->ssl)) { diff --git a/src/eap_peer/eap_psk.c b/src/eap_peer/eap_psk.c index cd0e3f96..f0126635 100644 --- a/src/eap_peer/eap_psk.c +++ b/src/eap_peer/eap_psk.c @@ -76,7 +76,7 @@ static void eap_psk_deinit(struct eap_sm *sm, void *priv) struct eap_psk_data *data = priv; os_free(data->id_s); os_free(data->id_p); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -237,7 +237,7 @@ static struct wpabuf * eap_psk_process_3(struct eap_psk_data *data, return NULL; } os_free(buf); - if (os_memcmp(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) { + if (os_memcmp_const(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) { wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third " "message"); ret->methodState = METHOD_DONE; diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c index 2aa7ba55..bdcca0b8 100644 --- a/src/eap_peer/eap_pwd.c +++ b/src/eap_peer/eap_pwd.c @@ -157,7 +157,7 @@ static void eap_pwd_deinit(struct eap_sm *sm, void *priv) EC_POINT_free(data->server_element); os_free(data->id_peer); os_free(data->id_server); - os_free(data->password); + bin_clear_free(data->password, data->password_len); if (data->grp) { EC_GROUP_free(data->grp->group); EC_POINT_free(data->grp->pwe); @@ -167,7 +167,7 @@ static void eap_pwd_deinit(struct eap_sm *sm, void *priv) } wpabuf_free(data->inbuf); wpabuf_free(data->outbuf); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -782,6 +782,8 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, tot_len = WPA_GET_BE16(pos); wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments whose " "total length = %d", tot_len); + if (tot_len > 15000) + return NULL; data->inbuf = wpabuf_alloc(tot_len); if (data->inbuf == NULL) { wpa_printf(MSG_INFO, "Out of memory to buffer " diff --git a/src/eap_peer/eap_sake.c b/src/eap_peer/eap_sake.c index 431519ca..7d149074 100644 --- a/src/eap_peer/eap_sake.c +++ b/src/eap_peer/eap_sake.c @@ -108,7 +108,7 @@ static void eap_sake_deinit(struct eap_sm *sm, void *priv) struct eap_sake_data *data = priv; os_free(data->serverid); os_free(data->peerid); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -315,7 +315,7 @@ static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm, data->peerid, data->peerid_len, 0, wpabuf_head(reqData), wpabuf_len(reqData), attr.mic_s, mic_s); - if (os_memcmp(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) { + if (os_memcmp_const(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_S"); eap_sake_state(data, FAILURE); ret->methodState = METHOD_DONE; diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c index 63c89396..bd06df78 100644 --- a/src/eap_peer/eap_sim.c +++ b/src/eap_peer/eap_sim.c @@ -130,6 +130,20 @@ static void * eap_sim_init(struct eap_sm *sm) } +static void eap_sim_clear_keys(struct eap_sim_data *data, int reauth) +{ + if (!reauth) { + os_memset(data->mk, 0, EAP_SIM_MK_LEN); + os_memset(data->k_aut, 0, EAP_SIM_K_AUT_LEN); + os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN); + } + os_memset(data->kc, 0, 3 * EAP_SIM_KC_LEN); + os_memset(data->sres, 0, 3 * EAP_SIM_SRES_LEN); + os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN); + os_memset(data->emsk, 0, EAP_EMSK_LEN); +} + + static void eap_sim_deinit(struct eap_sm *sm, void *priv) { struct eap_sim_data *data = priv; @@ -138,6 +152,7 @@ static void eap_sim_deinit(struct eap_sm *sm, void *priv) os_free(data->pseudonym); os_free(data->reauth_id); os_free(data->last_eap_identity); + eap_sim_clear_keys(data, 0); os_free(data); } } @@ -449,7 +464,7 @@ static struct wpabuf * eap_sim_client_error(struct eap_sim_data *data, u8 id, msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR); eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0); } @@ -502,7 +517,7 @@ static struct wpabuf * eap_sim_response_start(struct eap_sm *sm, identity, identity_len); } - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0); } @@ -520,7 +535,8 @@ static struct wpabuf * eap_sim_response_challenge(struct eap_sim_data *data, } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, (u8 *) data->sres, + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, + (u8 *) data->sres, data->num_chal * EAP_SIM_SRES_LEN); } @@ -562,7 +578,7 @@ static struct wpabuf * eap_sim_response_reauth(struct eap_sim_data *data, } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, nonce_s, + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, nonce_s, EAP_SIM_NONCE_S_LEN); } @@ -596,7 +612,7 @@ static struct wpabuf * eap_sim_response_notification(struct eap_sim_data *data, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); } - return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, k_aut, (u8 *) "", 0); } @@ -1109,6 +1125,7 @@ static void eap_sim_deinit_for_reauth(struct eap_sm *sm, void *priv) struct eap_sim_data *data = priv; eap_sim_clear_identities(sm, data, CLEAR_EAP_ID); data->use_result_ind = 0; + eap_sim_clear_keys(data, 1); } diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c index bb9f3f26..5aa3fd59 100644 --- a/src/eap_peer/eap_tls.c +++ b/src/eap_peer/eap_tls.c @@ -125,13 +125,22 @@ static void * eap_wfa_unauth_tls_init(struct eap_sm *sm) #endif /* CONFIG_HS20 */ +static void eap_tls_free_key(struct eap_tls_data *data) +{ + if (data->key_data) { + bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); + data->key_data = NULL; + } +} + + static void eap_tls_deinit(struct eap_sm *sm, void *priv) { struct eap_tls_data *data = priv; if (data == NULL) return; eap_peer_tls_ssl_deinit(sm, &data->ssl); - os_free(data->key_data); + eap_tls_free_key(data); os_free(data->session_id); os_free(data); } @@ -181,7 +190,7 @@ static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data, ret->methodState = METHOD_DONE; ret->decision = DECISION_UNCOND_SUCC; - os_free(data->key_data); + eap_tls_free_key(data); data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, "client EAP encryption", EAP_TLS_KEY_LEN + @@ -267,8 +276,7 @@ static void eap_tls_deinit_for_reauth(struct eap_sm *sm, void *priv) static void * eap_tls_init_for_reauth(struct eap_sm *sm, void *priv) { struct eap_tls_data *data = priv; - os_free(data->key_data); - data->key_data = NULL; + eap_tls_free_key(data); os_free(data->session_id); data->session_id = NULL; if (eap_peer_tls_reauth_init(sm, &data->ssl)) { diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c index 5091bf08..e110236a 100644 --- a/src/eap_peer/eap_ttls.c +++ b/src/eap_peer/eap_ttls.c @@ -133,6 +133,15 @@ static void eap_ttls_phase2_eap_deinit(struct eap_sm *sm, } +static void eap_ttls_free_key(struct eap_ttls_data *data) +{ + if (data->key_data) { + bin_clear_free(data->key_data, EAP_TLS_KEY_LEN); + data->key_data = NULL; + } +} + + static void eap_ttls_deinit(struct eap_sm *sm, void *priv) { struct eap_ttls_data *data = priv; @@ -141,7 +150,7 @@ static void eap_ttls_deinit(struct eap_sm *sm, void *priv) eap_ttls_phase2_eap_deinit(sm, data); os_free(data->phase2_eap_types); eap_peer_tls_ssl_deinit(sm, &data->ssl); - os_free(data->key_data); + eap_ttls_free_key(data); os_free(data->session_id); wpabuf_free(data->pending_phase2_req); os_free(data); @@ -213,7 +222,7 @@ static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code, static int eap_ttls_v0_derive_key(struct eap_sm *sm, struct eap_ttls_data *data) { - os_free(data->key_data); + eap_ttls_free_key(data); data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, "ttls keying material", EAP_TLS_KEY_LEN); @@ -1540,8 +1549,7 @@ static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv) static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv) { struct eap_ttls_data *data = priv; - os_free(data->key_data); - data->key_data = NULL; + eap_ttls_free_key(data); os_free(data->session_id); data->session_id = NULL; if (eap_peer_tls_reauth_init(sm, &data->ssl)) { diff --git a/src/eap_peer/ikev2.c b/src/eap_peer/ikev2.c index fb2f6199..8186afb5 100644 --- a/src/eap_peer/ikev2.c +++ b/src/eap_peer/ikev2.c @@ -565,7 +565,7 @@ static int ikev2_process_auth_secret(struct ikev2_responder_data *data, return -1; if (auth_len != prf->hash_len || - os_memcmp(auth, auth_data, auth_len) != 0) { + os_memcmp_const(auth, auth_data, auth_len) != 0) { wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data"); wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data", auth, auth_len); diff --git a/src/eap_peer/mschapv2.c b/src/eap_peer/mschapv2.c index 37e6735e..9bc73707 100644 --- a/src/eap_peer/mschapv2.c +++ b/src/eap_peer/mschapv2.c @@ -117,8 +117,8 @@ int mschapv2_verify_auth_response(const u8 *auth_response, buf[0] != 'S' || buf[1] != '=' || hexstr2bin((char *) (buf + 2), recv_response, MSCHAPV2_AUTH_RESPONSE_LEN) || - os_memcmp(auth_response, recv_response, - MSCHAPV2_AUTH_RESPONSE_LEN) != 0) + os_memcmp_const(auth_response, recv_response, + MSCHAPV2_AUTH_RESPONSE_LEN) != 0) return -1; return 0; } diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c index 65d00dda..c1bb6b83 100644 --- a/src/eap_server/eap_server.c +++ b/src/eap_server/eap_server.c @@ -168,7 +168,7 @@ SM_STATE(EAP, INITIALIZE) sm->eap_if.eapSuccess = FALSE; sm->eap_if.eapFail = FALSE; sm->eap_if.eapTimeout = FALSE; - os_free(sm->eap_if.eapKeyData); + bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); sm->eap_if.eapKeyData = NULL; sm->eap_if.eapKeyDataLen = 0; sm->eap_if.eapKeyAvailable = FALSE; @@ -346,7 +346,7 @@ SM_STATE(EAP, METHOD_RESPONSE) sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData); if (sm->m->isDone(sm, sm->eap_method_priv)) { eap_sm_Policy_update(sm, NULL, 0); - os_free(sm->eap_if.eapKeyData); + bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); if (sm->m->getKey) { sm->eap_if.eapKeyData = sm->m->getKey( sm, sm->eap_method_priv, @@ -632,7 +632,7 @@ SM_STATE(EAP, SUCCESS2) if (sm->eap_if.aaaEapKeyAvailable) { EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData); } else { - os_free(sm->eap_if.eapKeyData); + bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); sm->eap_if.eapKeyData = NULL; sm->eap_if.eapKeyDataLen = 0; } @@ -1260,7 +1260,7 @@ static void eap_user_free(struct eap_user *user) { if (user == NULL) return; - os_free(user->password); + bin_clear_free(user->password, user->password_len); user->password = NULL; os_free(user); } @@ -1352,7 +1352,7 @@ void eap_server_sm_deinit(struct eap_sm *sm) if (sm->m && sm->eap_method_priv) sm->m->reset(sm, sm->eap_method_priv); wpabuf_free(sm->eap_if.eapReqData); - os_free(sm->eap_if.eapKeyData); + bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); wpabuf_free(sm->lastReqData); wpabuf_free(sm->eap_if.eapRespData); os_free(sm->identity); @@ -1361,7 +1361,7 @@ void eap_server_sm_deinit(struct eap_sm *sm) os_free(sm->eap_fast_a_id_info); wpabuf_free(sm->eap_if.aaaEapReqData); wpabuf_free(sm->eap_if.aaaEapRespData); - os_free(sm->eap_if.aaaEapKeyData); + bin_clear_free(sm->eap_if.aaaEapKeyData, sm->eap_if.aaaEapKeyDataLen); eap_user_free(sm->user); wpabuf_free(sm->assoc_wps_ie); wpabuf_free(sm->assoc_p2p_ie); diff --git a/src/eap_server/eap_server_aka.c b/src/eap_server/eap_server_aka.c index 46fc4584..09b976e6 100644 --- a/src/eap_server/eap_server_aka.c +++ b/src/eap_server/eap_server_aka.c @@ -241,7 +241,7 @@ static void eap_aka_reset(struct eap_sm *sm, void *priv) os_free(data->next_reauth_id); wpabuf_free(data->id_msgs); os_free(data->network_name); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -336,7 +336,7 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data, else sha1_vector(1, &addr, &len, hash); - if (os_memcmp(hash, checkcode, hash_len) != 0) { + if (os_memcmp_const(hash, checkcode, hash_len) != 0) { wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE"); return -1; } @@ -377,7 +377,7 @@ static struct wpabuf * eap_aka_build_identity(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ"); eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0); } - buf = eap_sim_msg_finish(msg, NULL, NULL, 0); + buf = eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); if (eap_aka_add_id_msg(data, buf) < 0) { wpabuf_free(buf); return NULL; @@ -534,7 +534,7 @@ static struct wpabuf * eap_aka_build_challenge(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0); } @@ -581,7 +581,7 @@ static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0); } @@ -620,7 +620,7 @@ static struct wpabuf * eap_aka_build_notification(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); } - return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); + return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0); } @@ -963,7 +963,7 @@ static void eap_aka_process_challenge(struct eap_sm *sm, */ if (attr->res == NULL || attr->res_len < data->res_len || attr->res_len_bits != data->res_len * 8 || - os_memcmp(attr->res, data->res, data->res_len) != 0) { + os_memcmp_const(attr->res, data->res, data->res_len) != 0) { wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not " "include valid AT_RES (attr len=%lu, res len=%lu " "bits, expected %lu bits)", diff --git a/src/eap_server/eap_server_eke.c b/src/eap_server/eap_server_eke.c index b19a321a..966f511d 100644 --- a/src/eap_server/eap_server_eke.c +++ b/src/eap_server/eap_server_eke.c @@ -104,7 +104,7 @@ static void eap_eke_reset(struct eap_sm *sm, void *priv) eap_eke_session_clean(&data->sess); os_free(data->peerid); wpabuf_free(data->msgs); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -635,8 +635,8 @@ static void eap_eke_process_confirm(struct eap_sm *sm, return; } wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_P", auth_p, data->sess.prf_len); - if (os_memcmp(auth_p, payload + data->sess.pnonce_len, - data->sess.prf_len) != 0) { + if (os_memcmp_const(auth_p, payload + data->sess.pnonce_len, + data->sess.prf_len) != 0) { wpa_printf(MSG_INFO, "EAP-EKE: Auth_P does not match"); eap_eke_fail(data, EAP_EKE_FAIL_AUTHENTICATION_FAIL); return; diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c index 44a443af..10245101 100644 --- a/src/eap_server/eap_server_fast.c +++ b/src/eap_server/eap_server_fast.c @@ -511,7 +511,7 @@ static void eap_fast_reset(struct eap_sm *sm, void *priv) os_free(data->key_block_p); wpabuf_free(data->pending_phase2_resp); os_free(data->identity); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -1198,7 +1198,7 @@ static int eap_fast_validate_crypto_binding( return -1; } - if (os_memcmp(data->crypto_binding_nonce, b->nonce, 31) != 0 || + if (os_memcmp_const(data->crypto_binding_nonce, b->nonce, 31) != 0 || (data->crypto_binding_nonce[31] | 1) != b->nonce[31]) { wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid nonce in " "Crypto-Binding"); @@ -1212,7 +1212,7 @@ static int eap_fast_validate_crypto_binding( (u8 *) b, bind_len); hmac_sha1(data->cmk, EAP_FAST_CMK_LEN, (u8 *) b, bind_len, b->compound_mac); - if (os_memcmp(cmac, b->compound_mac, sizeof(cmac)) != 0) { + if (os_memcmp_const(cmac, b->compound_mac, sizeof(cmac)) != 0) { wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Calculated Compound MAC", b->compound_mac, sizeof(cmac)); diff --git a/src/eap_server/eap_server_gpsk.c b/src/eap_server/eap_server_gpsk.c index 66f42715..cb369e44 100644 --- a/src/eap_server/eap_server_gpsk.c +++ b/src/eap_server/eap_server_gpsk.c @@ -95,7 +95,7 @@ static void eap_gpsk_reset(struct eap_sm *sm, void *priv) { struct eap_gpsk_data *data = priv; os_free(data->id_peer); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -433,7 +433,7 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm, eap_gpsk_state(data, FAILURE); return; } - if (os_memcmp(mic, pos, miclen) != 0) { + if (os_memcmp_const(mic, pos, miclen) != 0) { wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-2"); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen); @@ -502,7 +502,7 @@ static void eap_gpsk_process_gpsk_4(struct eap_sm *sm, eap_gpsk_state(data, FAILURE); return; } - if (os_memcmp(mic, pos, miclen) != 0) { + if (os_memcmp_const(mic, pos, miclen) != 0) { wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-4"); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen); diff --git a/src/eap_server/eap_server_gtc.c b/src/eap_server/eap_server_gtc.c index f423106b..98ac3c6e 100644 --- a/src/eap_server/eap_server_gtc.c +++ b/src/eap_server/eap_server_gtc.c @@ -175,7 +175,7 @@ static void eap_gtc_process(struct eap_sm *sm, void *priv, } if (rlen != sm->user->password_len || - os_memcmp(pos, sm->user->password, rlen) != 0) { + os_memcmp_const(pos, sm->user->password, rlen) != 0) { wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure"); data->state = FAILURE; } else { diff --git a/src/eap_server/eap_server_ikev2.c b/src/eap_server/eap_server_ikev2.c index 3e32cc90..65b2ef69 100644 --- a/src/eap_server/eap_server_ikev2.c +++ b/src/eap_server/eap_server_ikev2.c @@ -127,7 +127,7 @@ static void eap_ikev2_reset(struct eap_sm *sm, void *priv) wpabuf_free(data->in_buf); wpabuf_free(data->out_buf); ikev2_initiator_deinit(&data->ikev2); - os_free(data); + bin_clear_free(data, sizeof(*data)); } diff --git a/src/eap_server/eap_server_md5.c b/src/eap_server/eap_server_md5.c index 5a5e2907..71e8d59e 100644 --- a/src/eap_server/eap_server_md5.c +++ b/src/eap_server/eap_server_md5.c @@ -126,7 +126,7 @@ static void eap_md5_process(struct eap_sm *sm, void *priv, return; } - if (os_memcmp(hash, pos, CHAP_MD5_LEN) == 0) { + if (os_memcmp_const(hash, pos, CHAP_MD5_LEN) == 0) { wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success"); data->state = SUCCESS; } else { diff --git a/src/eap_server/eap_server_mschapv2.c b/src/eap_server/eap_server_mschapv2.c index 0eb7908f..f7a753de 100644 --- a/src/eap_server/eap_server_mschapv2.c +++ b/src/eap_server/eap_server_mschapv2.c @@ -91,7 +91,7 @@ static void eap_mschapv2_reset(struct eap_sm *sm, void *priv) return; os_free(data->peer_challenge); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -393,7 +393,7 @@ static void eap_mschapv2_process_response(struct eap_sm *sm, return; } - if (os_memcmp(nt_response, expected, 24) == 0) { + if (os_memcmp_const(nt_response, expected, 24) == 0) { const u8 *pw_hash; u8 pw_hash_buf[16], pw_hash_hash[16]; diff --git a/src/eap_server/eap_server_pax.c b/src/eap_server/eap_server_pax.c index 35a42ad1..c87848c4 100644 --- a/src/eap_server/eap_server_pax.c +++ b/src/eap_server/eap_server_pax.c @@ -64,7 +64,7 @@ static void eap_pax_reset(struct eap_sm *sm, void *priv) { struct eap_pax_data *data = priv; os_free(data->cid); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -268,7 +268,7 @@ static Boolean eap_pax_check(struct eap_sm *sm, void *priv, wpabuf_mhead(respData), wpabuf_len(respData) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, icvbuf); - if (os_memcmp(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) { + if (os_memcmp_const(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV"); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV", icvbuf, EAP_PAX_ICV_LEN); @@ -395,7 +395,7 @@ static void eap_pax_process_std_2(struct eap_sm *sm, data->rand.r.x, EAP_PAX_RAND_LEN, data->rand.r.y, EAP_PAX_RAND_LEN, (u8 *) data->cid, data->cid_len, mac); - if (os_memcmp(mac, pos, EAP_PAX_MAC_LEN) != 0) { + if (os_memcmp_const(mac, pos, EAP_PAX_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-PAX: Invalid MAC_CK(A, B, CID) in " "PAX_STD-2"); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected MAC_CK(A, B, CID)", @@ -417,7 +417,7 @@ static void eap_pax_process_std_2(struct eap_sm *sm, wpabuf_head(respData), wpabuf_len(respData) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, icvbuf); - if (os_memcmp(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) { + if (os_memcmp_const(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV in PAX_STD-2"); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV", icvbuf, EAP_PAX_ICV_LEN); diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c index defcb3c0..594e02dd 100644 --- a/src/eap_server/eap_server_peap.c +++ b/src/eap_server/eap_server_peap.c @@ -172,7 +172,7 @@ static void eap_peap_reset(struct eap_sm *sm, void *priv) wpabuf_free(data->pending_phase2_resp); os_free(data->phase2_key); wpabuf_free(data->soh_response); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -593,7 +593,7 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm, buf[60] = EAP_TYPE_PEAP; hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac); - if (os_memcmp(mac, pos, SHA1_MAC_LEN) != 0) { + if (os_memcmp_const(mac, pos, SHA1_MAC_LEN) != 0) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in " "cryptobinding TLV"); wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK", data->cmk, 20); diff --git a/src/eap_server/eap_server_psk.c b/src/eap_server/eap_server_psk.c index 46bedd94..db394e98 100644 --- a/src/eap_server/eap_server_psk.c +++ b/src/eap_server/eap_server_psk.c @@ -47,7 +47,7 @@ static void eap_psk_reset(struct eap_sm *sm, void *priv) { struct eap_psk_data *data = priv; os_free(data->id_p); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -314,7 +314,7 @@ static void eap_psk_process_2(struct eap_sm *sm, } os_free(buf); wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN); - if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) { + if (os_memcmp_const(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P"); wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P", mac, EAP_PSK_MAC_LEN); diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c index ec53481f..9154ab17 100644 --- a/src/eap_server/eap_server_pwd.c +++ b/src/eap_server/eap_server_pwd.c @@ -116,7 +116,7 @@ static void * eap_pwd_init(struct eap_sm *sm) data->bnctx = BN_CTX_new(); if (data->bnctx == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: bn context allocation fail"); - os_free(data->password); + bin_clear_free(data->password, data->password_len); os_free(data->id_server); os_free(data); return NULL; @@ -144,7 +144,7 @@ static void eap_pwd_reset(struct eap_sm *sm, void *priv) EC_POINT_free(data->peer_element); os_free(data->id_peer); os_free(data->id_server); - os_free(data->password); + bin_clear_free(data->password, data->password_len); if (data->grp) { EC_GROUP_free(data->grp->group); EC_POINT_free(data->grp->pwe); @@ -154,7 +154,7 @@ static void eap_pwd_reset(struct eap_sm *sm, void *priv) } wpabuf_free(data->inbuf); wpabuf_free(data->outbuf); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -900,6 +900,8 @@ static void eap_pwd_process(struct eap_sm *sm, void *priv, tot_len = WPA_GET_BE16(pos); wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments, total " "length = %d", tot_len); + if (tot_len > 15000) + return; data->inbuf = wpabuf_alloc(tot_len); if (data->inbuf == NULL) { wpa_printf(MSG_INFO, "EAP-pwd: Out of memory to " diff --git a/src/eap_server/eap_server_sake.c b/src/eap_server/eap_server_sake.c index 68dd76b1..1937621c 100644 --- a/src/eap_server/eap_server_sake.c +++ b/src/eap_server/eap_server_sake.c @@ -83,7 +83,7 @@ static void eap_sake_reset(struct eap_sm *sm, void *priv) { struct eap_sake_data *data = priv; os_free(data->peerid); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -351,7 +351,7 @@ static void eap_sake_process_challenge(struct eap_sm *sm, data->peerid, data->peerid_len, 1, wpabuf_head(respData), wpabuf_len(respData), attr.mic_p, mic_p); - if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) { + if (os_memcmp_const(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P"); eap_sake_state(data, FAILURE); return; @@ -388,7 +388,7 @@ static void eap_sake_process_confirm(struct eap_sm *sm, data->peerid, data->peerid_len, 1, wpabuf_head(respData), wpabuf_len(respData), attr.mic_p, mic_p); - if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) { + if (os_memcmp_const(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P"); eap_sake_state(data, FAILURE); } else diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c index b531241e..23ee2b60 100644 --- a/src/eap_server/eap_server_sim.c +++ b/src/eap_server/eap_server_sim.c @@ -94,7 +94,7 @@ static void eap_sim_reset(struct eap_sm *sm, void *priv) struct eap_sim_data *data = priv; os_free(data->next_pseudonym); os_free(data->next_reauth_id); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -140,7 +140,7 @@ static struct wpabuf * eap_sim_build_start(struct eap_sm *sm, ver[1] = EAP_SIM_VERSION; eap_sim_msg_add(msg, EAP_SIM_AT_VERSION_LIST, sizeof(ver), ver, sizeof(ver)); - return eap_sim_msg_finish(msg, NULL, NULL, 0); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0); } @@ -240,8 +240,8 @@ static struct wpabuf * eap_sim_build_challenge(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, data->nonce_mt, - EAP_SIM_NONCE_MT_LEN); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, + data->nonce_mt, EAP_SIM_NONCE_MT_LEN); } @@ -278,7 +278,7 @@ static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, NULL, 0); } @@ -317,7 +317,7 @@ static struct wpabuf * eap_sim_build_notification(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); } - return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); + return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, NULL, 0); } diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c index d09a7693..31e3871d 100644 --- a/src/eap_server/eap_server_ttls.c +++ b/src/eap_server/eap_server_ttls.c @@ -336,7 +336,7 @@ static void eap_ttls_reset(struct eap_sm *sm, void *priv) data->phase2_method->reset(sm, data->phase2_priv); eap_server_tls_ssl_deinit(sm, &data->ssl); wpabuf_free(data->pending_phase2_eap_resp); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -509,8 +509,8 @@ static void eap_ttls_process_phase2_pap(struct eap_sm *sm, } if (sm->user->password_len != user_password_len || - os_memcmp(sm->user->password, user_password, user_password_len) != - 0) { + os_memcmp_const(sm->user->password, user_password, + user_password_len) != 0) { wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password"); eap_ttls_state(data, FAILURE); return; @@ -558,7 +558,8 @@ static void eap_ttls_process_phase2_chap(struct eap_sm *sm, return; } - if (os_memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 || + if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) + != 0 || password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) { wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch"); os_free(chal); @@ -571,7 +572,8 @@ static void eap_ttls_process_phase2_chap(struct eap_sm *sm, chap_md5(password[0], sm->user->password, sm->user->password_len, challenge, challenge_len, hash); - if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) { + if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == + 0) { wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password"); eap_ttls_state(data, SUCCESS); } else { @@ -616,7 +618,8 @@ static void eap_ttls_process_phase2_mschap(struct eap_sm *sm, return; } - if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 || + if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) + != 0 || response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) { wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch"); os_free(chal); @@ -631,7 +634,7 @@ static void eap_ttls_process_phase2_mschap(struct eap_sm *sm, nt_challenge_response(challenge, sm->user->password, sm->user->password_len, nt_response); - if (os_memcmp(nt_response, response + 2 + 24, 24) == 0) { + if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) { wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response"); eap_ttls_state(data, SUCCESS); } else { @@ -703,7 +706,8 @@ static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm, return; } - if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 || + if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) + != 0 || response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) { wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch"); os_free(chal); @@ -736,7 +740,7 @@ static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm, } rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8; - if (os_memcmp(nt_response, rx_resp, 24) == 0) { + if (os_memcmp_const(nt_response, rx_resp, 24) == 0) { wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct " "NT-Response"); data->mschapv2_resp_ok = 1; diff --git a/src/eap_server/ikev2.c b/src/eap_server/ikev2.c index 512ba307..632598fa 100644 --- a/src/eap_server/ikev2.c +++ b/src/eap_server/ikev2.c @@ -633,7 +633,7 @@ static int ikev2_process_auth_secret(struct ikev2_initiator_data *data, return -1; if (auth_len != prf->hash_len || - os_memcmp(auth, auth_data, auth_len) != 0) { + os_memcmp_const(auth, auth_data, auth_len) != 0) { wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data"); wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data", auth, auth_len); diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index e00dea34..cf3506d9 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -719,8 +719,8 @@ static void eapol_sm_processKey(struct eapol_sm *sm) hmac_md5(keydata.sign_key, sign_key_len, sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length), key->key_signature); - if (os_memcmp(orig_key_sign, key->key_signature, - IEEE8021X_KEY_SIGN_LEN) != 0) { + if (os_memcmp_const(orig_key_sign, key->key_signature, + IEEE8021X_KEY_SIGN_LEN) != 0) { wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in " "EAPOL-Key packet"); os_memcpy(key->key_signature, orig_key_sign, diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c index fb8a8ca9..56c195ab 100644 --- a/src/pae/ieee802_1x_kay.c +++ b/src/pae/ieee802_1x_kay.c @@ -2942,8 +2942,9 @@ static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay, mka_msg_len); if (msg_icv) { - if (os_memcmp(msg_icv, icv, - mka_alg_tbl[kay->mka_algindex].icv_len) != 0) { + if (os_memcmp_const(msg_icv, icv, + mka_alg_tbl[kay->mka_algindex].icv_len) != + 0) { wpa_printf(MSG_ERROR, "KaY: Computed ICV is not equal to Received ICV"); return -1; diff --git a/src/radius/radius.c b/src/radius/radius.c index e34d08b3..f2d8e96f 100644 --- a/src/radius/radius.c +++ b/src/radius/radius.c @@ -508,7 +508,7 @@ int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret, addr[3] = secret; len[3] = secret_len; md5_vector(4, addr, len, hash); - return os_memcmp(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0; + return os_memcmp_const(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0; } @@ -535,7 +535,7 @@ int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret, addr[3] = secret; len[3] = secret_len; md5_vector(4, addr, len, hash); - if (os_memcmp(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0) + if (os_memcmp_const(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0) return 1; for (i = 0; i < msg->attr_used; i++) { @@ -568,7 +568,7 @@ int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret, os_memcpy(msg->hdr->authenticator, orig_authenticator, sizeof(orig_authenticator)); - return os_memcmp(orig, auth, MD5_MAC_LEN) != 0; + return os_memcmp_const(orig, auth, MD5_MAC_LEN) != 0; } @@ -801,7 +801,7 @@ int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret, sizeof(orig_authenticator)); } - if (os_memcmp(orig, auth, MD5_MAC_LEN) != 0) { + if (os_memcmp_const(orig, auth, MD5_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "Invalid Message-Authenticator!"); return 1; } @@ -838,7 +838,7 @@ int radius_msg_verify(struct radius_msg *msg, const u8 *secret, addr[3] = secret; len[3] = secret_len; md5_vector(4, addr, len, hash); - if (os_memcmp(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) { + if (os_memcmp_const(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "Response Authenticator invalid!"); return 1; } diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c index c35ba557..24348a39 100644 --- a/src/radius/radius_server.c +++ b/src/radius/radius_server.c @@ -623,7 +623,7 @@ radius_server_get_new_session(struct radius_server_data *data, os_memset(&tmp, 0, sizeof(tmp)); res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp); - os_free(tmp.password); + bin_clear_free(tmp.password, tmp.password_len); if (res != 0) { RADIUS_DEBUG("User-Name not found from user database"); @@ -852,7 +852,7 @@ radius_server_macacl(struct radius_server_data *data, os_strlen(sess->username), 0, &tmp); if (res || !tmp.macacl || tmp.password == NULL) { RADIUS_DEBUG("No MAC ACL user entry"); - os_free(tmp.password); + bin_clear_free(tmp.password, tmp.password_len); code = RADIUS_CODE_ACCESS_REJECT; } else { u8 buf[128]; @@ -861,10 +861,10 @@ radius_server_macacl(struct radius_server_data *data, (u8 *) client->shared_secret, client->shared_secret_len, buf, sizeof(buf)); - os_free(tmp.password); + bin_clear_free(tmp.password, tmp.password_len); if (res < 0 || pw_len != (size_t) res || - os_memcmp(pw, buf, res) != 0) { + os_memcmp_const(pw, buf, res) != 0) { RADIUS_DEBUG("Incorrect User-Password"); code = RADIUS_CODE_ACCESS_REJECT; } diff --git a/src/rsn_supp/peerkey.c b/src/rsn_supp/peerkey.c index 88550e4b..aab8b7e6 100644 --- a/src/rsn_supp/peerkey.c +++ b/src/rsn_supp/peerkey.c @@ -653,11 +653,11 @@ static int wpa_supplicant_process_smk_error( static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, struct wpa_peerkey *peerkey, const struct wpa_eapol_key *key, - u16 ver) + u16 ver, const u8 *key_data, + size_t key_data_len) { struct wpa_eapol_ie_parse ie; - const u8 *kde; - size_t len, kde_buf_len; + size_t kde_buf_len; struct wpa_ptk *stk; u8 buf[8], *kde_buf, *pos; be32 lifetime; @@ -668,14 +668,13 @@ static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, os_memset(&ie, 0, sizeof(ie)); /* RSN: msg 1/4 should contain SMKID for the selected SMK */ - kde = (const u8 *) (key + 1); - len = WPA_GET_BE16(key->key_data_length); - wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len); - if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) { + wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", key_data, key_data_len); + if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0 || + ie.pmkid == NULL) { wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); 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", ie.pmkid, PMKID_LEN); return; @@ -760,11 +759,10 @@ static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm, static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, struct wpa_peerkey *peerkey, const struct wpa_eapol_key *key, - u16 ver) + u16 ver, const u8 *key_data, + size_t key_data_len) { struct wpa_eapol_ie_parse kde; - const u8 *keydata; - size_t len; wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from " MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); @@ -773,16 +771,14 @@ static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE * from the peer. It may also include Lifetime KDE. */ - keydata = (const u8 *) (key + 1); - len = WPA_GET_BE16(key->key_data_length); - wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len); - if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 || + wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", key_data, key_data_len); + if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0 || kde.pmkid == NULL || kde.rsn_ie == NULL) { wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4"); 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", kde.pmkid, PMKID_LEN); return; @@ -809,11 +805,11 @@ static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm, struct wpa_peerkey *peerkey, const struct wpa_eapol_key *key, - u16 ver) + u16 ver, const u8 *key_data, + size_t key_data_len) { struct wpa_eapol_ie_parse kde; - const u8 *keydata; - size_t len, key_len; + size_t key_len; const u8 *_key; u8 key_buf[32], rsc[6]; @@ -824,10 +820,8 @@ static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm, /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include * Lifetime KDE. */ - keydata = (const u8 *) (key + 1); - len = WPA_GET_BE16(key->key_data_length); - wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len); - if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) { + wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", key_data, key_data_len); + if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0) { wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in " "STK 3/4"); return; @@ -935,7 +929,7 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, os_memset(key->key_mic, 0, 16); wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, 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 " "when using TSTK - ignoring TSTK"); } else { @@ -951,7 +945,7 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, os_memset(key->key_mic, 0, 16); wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, 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 " "- dropping packet"); return -1; @@ -1117,21 +1111,25 @@ void peerkey_deinit(struct wpa_sm *sm) void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, - struct wpa_eapol_key *key, u16 key_info, u16 ver) + struct wpa_eapol_key *key, u16 key_info, u16 ver, + const u8 *key_data, size_t key_data_len) { if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) == (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) { /* 3/4 STK 4-Way Handshake */ - wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver); + wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver, + key_data, key_data_len); } else if (key_info & WPA_KEY_INFO_ACK) { /* 1/4 STK 4-Way Handshake */ - wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver); + wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver, + key_data, key_data_len); } else if (key_info & WPA_KEY_INFO_SECURE) { /* 4/4 STK 4-Way Handshake */ wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver); } else { /* 2/4 STK 4-Way Handshake */ - wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver); + wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver, + key_data, key_data_len); } } diff --git a/src/rsn_supp/peerkey.h b/src/rsn_supp/peerkey.h index f420691a..4c17eae0 100644 --- a/src/rsn_supp/peerkey.h +++ b/src/rsn_supp/peerkey.h @@ -41,7 +41,8 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, struct wpa_eapol_key *key, u16 ver, const u8 *buf, size_t len); void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, - struct wpa_eapol_key *key, u16 key_info, u16 ver); + struct wpa_eapol_key *key, u16 key_info, u16 ver, + const u8 *key_data, size_t key_data_len); void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr, struct wpa_eapol_key *key, size_t extra_len, u16 key_info, u16 ver); @@ -60,7 +61,8 @@ peerkey_verify_eapol_key_mic(struct wpa_sm *sm, static inline void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, - struct wpa_eapol_key *key, u16 key_info, u16 ver) + struct wpa_eapol_key *key, u16 key_info, u16 ver, + const u8 *key_data, size_t key_data_len) { } diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c index 09608153..b5a87fc5 100644 --- a/src/rsn_supp/pmksa_cache.c +++ b/src/rsn_supp/pmksa_cache.c @@ -152,9 +152,9 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, while (pos) { if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) { if (pos->pmk_len == pmk_len && - os_memcmp(pos->pmk, pmk, pmk_len) == 0 && - os_memcmp(pos->pmkid, entry->pmkid, PMKID_LEN) == - 0) { + os_memcmp_const(pos->pmk, pmk, pmk_len) == 0 && + os_memcmp_const(pos->pmkid, entry->pmkid, + PMKID_LEN) == 0) { wpa_printf(MSG_DEBUG, "WPA: reusing previous " "PMKSA entry"); os_free(entry); diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index cda69574..cd34223f 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -564,7 +564,7 @@ static int wpa_supplicant_verify_tdls_mic(u8 trans_seq, wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid, peer->rsnie_p, timeoutie, (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 FTIE - " "dropping packet"); wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC", @@ -591,7 +591,7 @@ static int wpa_supplicant_verify_tdls_mic_teardown( if (peer->tpk_set) { wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode, 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 - " "dropping packet"); return -1; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 40fb92a2..94710717 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -162,7 +162,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, } 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_sm_set_pmk_from_pmksa(sm); 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; } - 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, "FT: PMKR1Name mismatch in " "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); wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len, 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: Invalid EAPOL-Key MIC " "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); wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len, 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: Invalid EAPOL-Key MIC - " "dropping packet"); @@ -1833,7 +1834,8 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr, } if (peerkey) { /* PeerKey 4-Way Handshake */ - peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver); + peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver, + key_data, key_data_len); } else if (key_info & WPA_KEY_INFO_MIC) { /* 3/4 4-Way Handshake */ wpa_supplicant_process_3_of_4(sm, key, ver, key_data, diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index c8d8cfc8..4a75b926 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -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 || - 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", @@ -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 || - 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 " "RSNIE"); 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 || - 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", @@ -742,14 +745,15 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, 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 " "ReassocResp"); return -1; } 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; @@ -775,7 +779,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, 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_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16); wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16); diff --git a/src/tls/pkcs1.c b/src/tls/pkcs1.c index 381b7a03..141ac50d 100644 --- a/src/tls/pkcs1.c +++ b/src/tls/pkcs1.c @@ -298,7 +298,7 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk, hdr.payload, hdr.length); if (hdr.length != hash_len || - os_memcmp(hdr.payload, hash, hdr.length) != 0) { + os_memcmp_const(hdr.payload, hash, hdr.length) != 0) { wpa_printf(MSG_INFO, "PKCS #1: Digest value does not match calculated hash"); os_free(decrypted); return -1; diff --git a/src/tls/tlsv1_client_read.c b/src/tls/tlsv1_client_read.c index f78921d9..4f08e0f9 100644 --- a/src/tls/tlsv1_client_read.c +++ b/src/tls/tlsv1_client_read.c @@ -962,7 +962,7 @@ static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct, wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", verify_data, TLS_VERIFY_DATA_LEN); - if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { + if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data"); tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECRYPT_ERROR); diff --git a/src/tls/tlsv1_common.c b/src/tls/tlsv1_common.c index 8a4645bf..ced28cff 100644 --- a/src/tls/tlsv1_common.c +++ b/src/tls/tlsv1_common.c @@ -481,7 +481,8 @@ int tls_verify_signature(u16 tls_version, struct crypto_public_key *pk, } #endif /* CONFIG_TLSV12 */ - if (buflen != data_len || os_memcmp(decrypted, data, data_len) != 0) { + if (buflen != data_len || + os_memcmp_const(decrypted, data, data_len) != 0) { wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in CertificateVerify - did not match calculated hash"); os_free(buf); *alert = TLS_ALERT_DECRYPT_ERROR; diff --git a/src/tls/tlsv1_record.c b/src/tls/tlsv1_record.c index 3bec3be3..0c6897a8 100644 --- a/src/tls/tlsv1_record.c +++ b/src/tls/tlsv1_record.c @@ -456,7 +456,7 @@ int tlsv1_record_receive(struct tlsv1_record_layer *rl, return -1; } if (hlen != rl->hash_size || - os_memcmp(hash, out_data + plen, hlen) != 0 || + os_memcmp_const(hash, out_data + plen, hlen) != 0 || force_mac_error) { wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in " "received message (force_mac_error=%d)", diff --git a/src/tls/tlsv1_server_read.c b/src/tls/tlsv1_server_read.c index c34545ed..728e1372 100644 --- a/src/tls/tlsv1_server_read.c +++ b/src/tls/tlsv1_server_read.c @@ -1135,7 +1135,7 @@ static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct, wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)", verify_data, TLS_VERIFY_DATA_LEN); - if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { + if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { tlsv1_server_log(conn, "Mismatch in verify_data"); return -1; } diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index 751a268e..e1e4df8d 100644 --- a/src/tls/x509v3.c +++ b/src/tls/x509v3.c @@ -1776,7 +1776,7 @@ skip_digest_oid: } if (hdr.length != hash_len || - os_memcmp(hdr.payload, hash, hdr.length) != 0) { + os_memcmp_const(hdr.payload, hash, hdr.length) != 0) { wpa_printf(MSG_INFO, "X509: Certificate Digest does not match " "with calculated tbsCertificate hash"); os_free(data); diff --git a/src/utils/common.c b/src/utils/common.c index 7dc4797d..5b017e57 100644 --- a/src/utils/common.c +++ b/src/utils/common.c @@ -827,3 +827,22 @@ void int_array_add_unique(int **res, int a) *res = n; } + + +void str_clear_free(char *str) +{ + if (str) { + size_t len = os_strlen(str); + os_memset(str, 0, len); + os_free(str); + } +} + + +void bin_clear_free(void *bin, size_t len) +{ + if (bin) { + os_memset(bin, 0, len); + os_free(bin); + } +} diff --git a/src/utils/common.h b/src/utils/common.h index a85cc159..2bc8fe14 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -535,6 +535,10 @@ void int_array_add_unique(int **res, int a); #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +void str_clear_free(char *str); +void bin_clear_free(void *bin, size_t len); + + /* * gcc 4.4 ends up generating strict-aliasing warnings about some very common * networking socket uses that do not really result in a real problem and diff --git a/src/utils/ext_password_test.c b/src/utils/ext_password_test.c index 3801bb85..b3a4552d 100644 --- a/src/utils/ext_password_test.c +++ b/src/utils/ext_password_test.c @@ -36,7 +36,7 @@ static void ext_password_test_deinit(void *ctx) { struct ext_password_test_data *data = ctx; - os_free(data->params); + str_clear_free(data->params); os_free(data); } diff --git a/src/utils/http_curl.c b/src/utils/http_curl.c index 07d9af08..eb79b862 100644 --- a/src/utils/http_curl.c +++ b/src/utils/http_curl.c @@ -1368,8 +1368,8 @@ int soap_reinit_client(struct http_ctx *ctx) client_cert, client_key); os_free(address); os_free(ca_fname); - os_free(username); - os_free(password); + str_clear_free(username); + str_clear_free(password); os_free(client_cert); os_free(client_key); return ret; @@ -1487,8 +1487,8 @@ void http_deinit_ctx(struct http_ctx *ctx) os_free(ctx->svc_address); os_free(ctx->svc_ca_fname); - os_free(ctx->svc_username); - os_free(ctx->svc_password); + str_clear_free(ctx->svc_username); + str_clear_free(ctx->svc_password); os_free(ctx->svc_client_cert); os_free(ctx->svc_client_key); diff --git a/src/utils/os.h b/src/utils/os.h index f019e26b..f196209b 100644 --- a/src/utils/os.h +++ b/src/utils/os.h @@ -584,6 +584,23 @@ static inline void os_remove_in_array(void *ptr, size_t nmemb, size_t size, */ size_t os_strlcpy(char *dest, const char *src, size_t siz); +/** + * os_memcmp_const - Constant time memory comparison + * @a: First buffer to compare + * @b: Second buffer to compare + * @len: Number of octets to compare + * Returns: 0 if buffers are equal, non-zero if not + * + * This function is meant for comparing passwords or hash values where + * difference in execution time could provide external observer information + * about the location of the difference in the memory buffers. The return value + * does not behave like os_memcmp(), i.e., os_memcmp_const() cannot be used to + * sort items into a defined order. Unlike os_memcmp(), execution time of + * os_memcmp_const() does not depend on the contents of the compared memory + * buffers, but only on the total compared length. + */ +int os_memcmp_const(const void *a, const void *b, size_t len); + #ifdef OS_REJECT_C_LIB_FUNCTIONS #define malloc OS_DO_NOT_USE_malloc diff --git a/src/utils/os_internal.c b/src/utils/os_internal.c index 2cb0d126..90b6688a 100644 --- a/src/utils/os_internal.c +++ b/src/utils/os_internal.c @@ -463,6 +463,20 @@ size_t os_strlcpy(char *dest, const char *src, size_t siz) } +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + + char * os_strstr(const char *haystack, const char *needle) { size_t len = os_strlen(needle); diff --git a/src/utils/os_none.c b/src/utils/os_none.c index 228c4724..26491115 100644 --- a/src/utils/os_none.c +++ b/src/utils/os_none.c @@ -218,6 +218,11 @@ size_t os_strlcpy(char *dest, const char *src, size_t size) } +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + return 0; +} + char * os_strstr(const char *haystack, const char *needle) { return NULL; diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c index 008ec6b0..d3860aec 100644 --- a/src/utils/os_unix.c +++ b/src/utils/os_unix.c @@ -450,6 +450,20 @@ size_t os_strlcpy(char *dest, const char *src, size_t siz) } +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + + #ifdef WPA_TRACE void * os_malloc(size_t size) diff --git a/src/utils/os_win32.c b/src/utils/os_win32.c index 1cfa7a5f..55937dec 100644 --- a/src/utils/os_win32.c +++ b/src/utils/os_win32.c @@ -244,3 +244,17 @@ size_t os_strlcpy(char *dest, const char *src, size_t siz) return s - src - 1; } + + +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} diff --git a/src/utils/pcsc_funcs.c b/src/utils/pcsc_funcs.c index ec065563..d955dc4e 100644 --- a/src/utils/pcsc_funcs.c +++ b/src/utils/pcsc_funcs.c @@ -1406,6 +1406,12 @@ int scard_umts_auth(struct scard_data *scard, const unsigned char *_rand, pos += IK_LEN; wpa_hexdump(MSG_DEBUG, "SCARD: IK", ik, IK_LEN); + if (end > pos) { + wpa_hexdump(MSG_DEBUG, + "SCARD: Ignore extra data in end", + pos, end - pos); + } + return 0; } diff --git a/src/wps/wps.c b/src/wps/wps.c index 648cfd10..b0f6887c 100644 --- a/src/wps/wps.c +++ b/src/wps/wps.c @@ -89,7 +89,7 @@ struct wps_data * wps_init(const struct wps_config *cfg) if (cfg->pbc) { /* Use special PIN '00000000' for PBC */ data->dev_pw_id = DEV_PW_PUSHBUTTON; - os_free(data->dev_password); + bin_clear_free(data->dev_password, data->dev_password_len); data->dev_password = (u8 *) os_strdup("00000000"); if (data->dev_password == NULL) { os_free(data); @@ -122,7 +122,8 @@ struct wps_data * wps_init(const struct wps_config *cfg) data->new_ap_settings = os_malloc(sizeof(*data->new_ap_settings)); if (data->new_ap_settings == NULL) { - os_free(data->dev_password); + bin_clear_free(data->dev_password, + data->dev_password_len); os_free(data); return NULL; } @@ -173,11 +174,11 @@ void wps_deinit(struct wps_data *data) wpabuf_free(data->dh_pubkey_e); wpabuf_free(data->dh_pubkey_r); wpabuf_free(data->last_msg); - os_free(data->dev_password); - os_free(data->alt_dev_password); - os_free(data->new_psk); + bin_clear_free(data->dev_password, data->dev_password_len); + bin_clear_free(data->alt_dev_password, data->alt_dev_password_len); + bin_clear_free(data->new_psk, data->new_psk_len); wps_device_data_free(&data->peer_dev); - os_free(data->new_ap_settings); + bin_clear_free(data->new_ap_settings, sizeof(*data->new_ap_settings)); dh5_free(data->dh_ctx); os_free(data); } diff --git a/src/wps/wps_attr_process.c b/src/wps/wps_attr_process.c index 52666206..eadb22fe 100644 --- a/src/wps/wps_attr_process.c +++ b/src/wps/wps_attr_process.c @@ -41,7 +41,7 @@ int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator, len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN; hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash); - if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) { + if (os_memcmp_const(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator"); return -1; } @@ -71,7 +71,7 @@ int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg, } hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash); - if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) { + if (os_memcmp_const(hash, key_wrap_auth, WPS_KWA_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: Invalid KWA"); return -1; } diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index d072582f..f7d41b4d 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -525,8 +525,8 @@ static int wps_process_pubkey(struct wps_data *wps, const u8 *pk, if (wps->peer_pubkey_hash_set) { u8 hash[WPS_HASH_LEN]; sha256_vector(1, &pk, &pk_len, hash); - if (os_memcmp(hash, wps->peer_pubkey_hash, - WPS_OOB_PUBKEY_HASH_LEN) != 0) { + if (os_memcmp_const(hash, wps->peer_pubkey_hash, + WPS_OOB_PUBKEY_HASH_LEN) != 0) { wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch"); wpa_hexdump(MSG_DEBUG, "WPS: Received public key", pk, pk_len); @@ -605,7 +605,7 @@ static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1) len[3] = wpabuf_len(wps->dh_pubkey_r); hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); - if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { + if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does " "not match with the pre-committed value"); wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; @@ -645,7 +645,7 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2) len[3] = wpabuf_len(wps->dh_pubkey_r); hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); - if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { + if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does " "not match with the pre-committed value"); wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; @@ -892,7 +892,7 @@ static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id) if (wps->alt_dev_password && wps->alt_dev_pw_id == id) { wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password"); - os_free(wps->dev_password); + bin_clear_free(wps->dev_password, wps->dev_password_len); wps->dev_pw_id = wps->alt_dev_pw_id; wps->dev_password = wps->alt_dev_password; wps->dev_password_len = wps->alt_dev_password_len; diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index b917e6b0..00c8299a 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -42,7 +42,7 @@ struct wps_nfc_pw_token { static void wps_remove_nfc_pw_token(struct wps_nfc_pw_token *token) { dl_list_del(&token->list); - os_free(token); + bin_clear_free(token, sizeof(*token)); } @@ -91,7 +91,7 @@ struct wps_uuid_pin { static void wps_free_pin(struct wps_uuid_pin *pin) { - os_free(pin->pin); + bin_clear_free(pin->pin, pin->pin_len); os_free(pin); } @@ -826,7 +826,7 @@ static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg, { if (dev_pw && pin->pin && (dev_pw_len != pin->pin_len || - os_memcmp(dev_pw, pin->pin, dev_pw_len) != 0)) + os_memcmp_const(dev_pw, pin->pin, dev_pw_len) != 0)) continue; /* different PIN */ if (pin->wildcard_uuid) { wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID", @@ -1343,7 +1343,7 @@ static int wps_get_dev_password(struct wps_data *wps) const u8 *pin; size_t pin_len = 0; - os_free(wps->dev_password); + bin_clear_free(wps->dev_password, wps->dev_password_len); wps->dev_password = NULL; if (wps->pbc) { @@ -2211,7 +2211,7 @@ static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1) len[3] = wpabuf_len(wps->dh_pubkey_r); hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); - if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { + if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does " "not match with the pre-committed value"); wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; @@ -2251,7 +2251,7 @@ static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2) len[3] = wpabuf_len(wps->dh_pubkey_r); hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); - if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { + if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does " "not match with the pre-committed value"); wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e); @@ -2591,8 +2591,9 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps, addr[0] = attr->public_key; sha256_vector(1, addr, &attr->public_key_len, hash); - if (os_memcmp(hash, wps->nfc_pw_token->pubkey_hash, - WPS_OOB_PUBKEY_HASH_LEN) != 0) { + if (os_memcmp_const(hash, + wps->nfc_pw_token->pubkey_hash, + WPS_OOB_PUBKEY_HASH_LEN) != 0) { wpa_printf(MSG_ERROR, "WPS: Public Key hash " "mismatch"); wps->state = SEND_M2D; |
