diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index f5e5779ab..e5a777bbb 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -934,6 +934,7 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data, os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN); os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); + forced_memzero(&PTK, sizeof(PTK)); sm->PTK_valid = TRUE; return 0; @@ -1407,6 +1408,8 @@ static int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr, #endif /* CONFIG_SHA256 */ #endif /* CONFIG_SHA384 */ + forced_memzero(data, sizeof(data)); + return ret; } @@ -2046,7 +2049,7 @@ SM_STATE(WPA_PTK, INITPMK) sm->Disconnect = TRUE; return; } - os_memset(msk, 0, sizeof(msk)); + forced_memzero(msk, sizeof(msk)); sm->req_replay_counter_used = 0; /* IEEE 802.11i does not set keyRun to FALSE, but not doing this @@ -2285,12 +2288,12 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, wpa_hexdump(MSG_DEBUG, "FILS+FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN); wpa_ft_store_pmk_fils(sm, pmk_r0, pmk_r0_name); - os_memset(fils_ft, 0, sizeof(fils_ft)); + forced_memzero(fils_ft, sizeof(fils_ft)); res = wpa_derive_pmk_r1_name(pmk_r0_name, conf->r1_key_holder, sm->addr, sm->pmk_r1_name, use_sha384); - os_memset(pmk_r0, 0, PMK_LEN_MAX); + forced_memzero(pmk_r0, PMK_LEN_MAX); if (res < 0) return -1; wpa_hexdump(MSG_DEBUG, "FILS+FT: PMKR1Name", sm->pmk_r1_name, @@ -2308,7 +2311,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, sm->wpa_key_mgmt, sm->fils_key_auth_sta, sm->fils_key_auth_ap, &sm->fils_key_auth_len); - os_memset(ick, 0, sizeof(ick)); + forced_memzero(ick, sizeof(ick)); /* Store nonces for (Re)Association Request/Response frame processing */ os_memcpy(sm->SNonce, snonce, FILS_NONCE_LEN); @@ -3030,6 +3033,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) sm->MICVerified = TRUE; os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); + forced_memzero(&PTK, sizeof(PTK)); sm->PTK_valid = TRUE; } diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index d1a983e0b..696f8d5fa 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2226,6 +2226,7 @@ static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len) return NULL; } + forced_memzero(keybuf, sizeof(keybuf)); *len = subelem_len; return subelem; } @@ -3567,7 +3568,7 @@ static int wpa_ft_rrb_build_r0(const u8 *key, const size_t key_len, pmk_r0->vlan, src_addr, type, packet, packet_len); - os_memset(pmk_r1, 0, sizeof(pmk_r1)); + forced_memzero(pmk_r1, sizeof(pmk_r1)); return ret; } @@ -3893,10 +3894,7 @@ static int wpa_ft_rrb_rx_r1(struct wpa_authenticator *wpa_auth, ret = 0; out: - if (plain) { - os_memset(plain, 0, plain_len); - os_free(plain); - } + bin_clear_free(plain, plain_len); return ret; diff --git a/src/crypto/sha1-internal.c b/src/crypto/sha1-internal.c index a4917070f..ffa04df01 100644 --- a/src/crypto/sha1-internal.c +++ b/src/crypto/sha1-internal.c @@ -224,7 +224,7 @@ void SHA1Transform(u32 state[5], const unsigned char buffer[64]) /* Wipe variables */ a = b = c = d = e = 0; #ifdef SHA1HANDSOFF - os_memset(block, 0, 64); + forced_memzero(block, 64); #endif } @@ -300,7 +300,7 @@ void SHA1Final(unsigned char digest[20], SHA1_CTX* context) os_memset(context->buffer, 0, 64); os_memset(context->state, 0, 20); os_memset(context->count, 0, 8); - os_memset(finalcount, 0, 8); + forced_memzero(finalcount, sizeof(finalcount)); } /* ===== end - public domain SHA1 implementation ===== */ diff --git a/src/crypto/sha1-prf.c b/src/crypto/sha1-prf.c index 4b2d13730..13851494f 100644 --- a/src/crypto/sha1-prf.c +++ b/src/crypto/sha1-prf.c @@ -61,7 +61,7 @@ int sha1_prf(const u8 *key, size_t key_len, const char *label, } counter++; } - os_memset(hash, 0, sizeof(hash)); + forced_memzero(hash, sizeof(hash)); return 0; } diff --git a/src/crypto/sha1-tlsprf.c b/src/crypto/sha1-tlsprf.c index a11649a93..5e8d15920 100644 --- a/src/crypto/sha1-tlsprf.c +++ b/src/crypto/sha1-tlsprf.c @@ -92,10 +92,10 @@ int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, SHA1_pos++; } - os_memset(A_MD5, 0, MD5_MAC_LEN); - os_memset(P_MD5, 0, MD5_MAC_LEN); - os_memset(A_SHA1, 0, SHA1_MAC_LEN); - os_memset(P_SHA1, 0, SHA1_MAC_LEN); + forced_memzero(A_MD5, MD5_MAC_LEN); + forced_memzero(P_MD5, MD5_MAC_LEN); + forced_memzero(A_SHA1, SHA1_MAC_LEN); + forced_memzero(P_SHA1, SHA1_MAC_LEN); return 0; } diff --git a/src/crypto/sha1-tprf.c b/src/crypto/sha1-tprf.c index 562510f89..c3acf1975 100644 --- a/src/crypto/sha1-tprf.c +++ b/src/crypto/sha1-tprf.c @@ -66,7 +66,7 @@ int sha1_t_prf(const u8 *key, size_t key_len, const char *label, len[0] = SHA1_MAC_LEN; } - os_memset(hash, 0, SHA1_MAC_LEN); + forced_memzero(hash, SHA1_MAC_LEN); return 0; } diff --git a/src/crypto/sha1.c b/src/crypto/sha1.c index 8fce13940..76d7a68f2 100644 --- a/src/crypto/sha1.c +++ b/src/crypto/sha1.c @@ -86,7 +86,8 @@ int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, _addr[1] = mac; _len[1] = SHA1_MAC_LEN; ret = sha1_vector(2, _addr, _len, mac); - os_memset(k_pad, 0, sizeof(k_pad)); + forced_memzero(k_pad, sizeof(k_pad)); + forced_memzero(tk, sizeof(tk)); return ret; } diff --git a/src/crypto/sha256-kdf.c b/src/crypto/sha256-kdf.c index af7d954d8..5a6b74455 100644 --- a/src/crypto/sha256-kdf.c +++ b/src/crypto/sha256-kdf.c @@ -69,7 +69,7 @@ int hmac_sha256_kdf(const u8 *secret, size_t secret_len, if (iter == 255) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA256_MAC_LEN); + forced_memzero(T, SHA256_MAC_LEN); return -1; } iter++; @@ -77,11 +77,11 @@ int hmac_sha256_kdf(const u8 *secret, size_t secret_len, if (hmac_sha256_vector(secret, secret_len, 4, addr, len, T) < 0) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA256_MAC_LEN); + forced_memzero(T, SHA256_MAC_LEN); return -1; } } - os_memset(T, 0, SHA256_MAC_LEN); + forced_memzero(T, SHA256_MAC_LEN); return 0; } diff --git a/src/crypto/sha256-prf.c b/src/crypto/sha256-prf.c index 722cad6bd..d665a9983 100644 --- a/src/crypto/sha256-prf.c +++ b/src/crypto/sha256-prf.c @@ -102,7 +102,7 @@ int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, buf[pos - 1] &= mask; } - os_memset(hash, 0, sizeof(hash)); + forced_memzero(hash, sizeof(hash)); return 0; } diff --git a/src/crypto/sha384-kdf.c b/src/crypto/sha384-kdf.c index 1d1962790..babcb9ed0 100644 --- a/src/crypto/sha384-kdf.c +++ b/src/crypto/sha384-kdf.c @@ -69,7 +69,7 @@ int hmac_sha384_kdf(const u8 *secret, size_t secret_len, if (iter == 255) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA384_MAC_LEN); + forced_memzero(T, SHA384_MAC_LEN); return -1; } iter++; @@ -77,11 +77,11 @@ int hmac_sha384_kdf(const u8 *secret, size_t secret_len, if (hmac_sha384_vector(secret, secret_len, 4, addr, len, T) < 0) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA384_MAC_LEN); + forced_memzero(T, SHA384_MAC_LEN); return -1; } } - os_memset(T, 0, SHA384_MAC_LEN); + forced_memzero(T, SHA384_MAC_LEN); return 0; } diff --git a/src/crypto/sha384-prf.c b/src/crypto/sha384-prf.c index 03e3cb353..420e78c38 100644 --- a/src/crypto/sha384-prf.c +++ b/src/crypto/sha384-prf.c @@ -102,7 +102,7 @@ int sha384_prf_bits(const u8 *key, size_t key_len, const char *label, buf[pos - 1] &= mask; } - os_memset(hash, 0, sizeof(hash)); + forced_memzero(hash, sizeof(hash)); return 0; } diff --git a/src/crypto/sha512-kdf.c b/src/crypto/sha512-kdf.c index 8b71f9b0e..5bde66485 100644 --- a/src/crypto/sha512-kdf.c +++ b/src/crypto/sha512-kdf.c @@ -69,7 +69,7 @@ int hmac_sha512_kdf(const u8 *secret, size_t secret_len, if (iter == 255) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA512_MAC_LEN); + forced_memzero(T, SHA512_MAC_LEN); return -1; } iter++; @@ -77,11 +77,11 @@ int hmac_sha512_kdf(const u8 *secret, size_t secret_len, if (hmac_sha512_vector(secret, secret_len, 4, addr, len, T) < 0) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA512_MAC_LEN); + forced_memzero(T, SHA512_MAC_LEN); return -1; } } - os_memset(T, 0, SHA512_MAC_LEN); + forced_memzero(T, SHA512_MAC_LEN); return 0; } diff --git a/src/crypto/sha512-prf.c b/src/crypto/sha512-prf.c index 3b2ad889d..e48cf5f05 100644 --- a/src/crypto/sha512-prf.c +++ b/src/crypto/sha512-prf.c @@ -102,7 +102,7 @@ int sha512_prf_bits(const u8 *key, size_t key_len, const char *label, buf[pos - 1] &= mask; } - os_memset(hash, 0, sizeof(hash)); + forced_memzero(hash, sizeof(hash)); return 0; } diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index bf2407421..c71979f8b 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -3999,7 +3999,7 @@ int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, _out, skip + out_len) == 0) { ret = 0; } - os_memset(master_key, 0, sizeof(master_key)); + forced_memzero(master_key, sizeof(master_key)); os_free(rnd); if (ret == 0) os_memcpy(out, _out + skip, out_len); diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c index e9cb425c1..83704fffa 100644 --- a/src/crypto/tls_wolfssl.c +++ b/src/crypto/tls_wolfssl.c @@ -2044,7 +2044,7 @@ int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, _out, skip + out_len); } - os_memset(master_key, 0, master_key_len); + forced_memzero(master_key, master_key_len); if (ret == 0) os_memcpy(out, _out + skip, out_len); bin_clear_free(tmp_out, skip + out_len); diff --git a/src/eap_peer/eap_eke.c b/src/eap_peer/eap_eke.c index 0de7d6cbf..534af262e 100644 --- a/src/eap_peer/eap_eke.c +++ b/src/eap_peer/eap_eke.c @@ -414,7 +414,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, */ if (eap_eke_dh_init(data->sess.dhgroup, data->dh_priv, pub) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to initialize DH"); - os_memset(key, 0, sizeof(key)); + forced_memzero(key, sizeof(key)); return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -422,7 +422,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (eap_eke_shared_secret(&data->sess, key, data->dh_priv, dhcomp) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive shared secret"); - os_memset(key, 0, sizeof(key)); + forced_memzero(key, sizeof(key)); return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -431,7 +431,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, data->serverid, data->serverid_len, data->peerid, data->peerid_len) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive Ke/Ki"); - os_memset(key, 0, sizeof(key)); + forced_memzero(key, sizeof(key)); return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -442,7 +442,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, data->sess.dhcomp_len + data->sess.pnonce_len, EAP_EKE_COMMIT); if (resp == NULL) { - os_memset(key, 0, sizeof(key)); + forced_memzero(key, sizeof(key)); return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -452,11 +452,11 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (eap_eke_dhcomp(&data->sess, key, pub, rpos) < 0) { wpabuf_free(resp); wpa_printf(MSG_INFO, "EAP-EKE: Failed to build DHComponent_P"); - os_memset(key, 0, sizeof(key)); + forced_memzero(key, sizeof(key)); return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } - os_memset(key, 0, sizeof(key)); + forced_memzero(key, sizeof(key)); wpa_hexdump(MSG_DEBUG, "EAP-EKE: DHComponent_P", rpos, data->sess.dhcomp_len); diff --git a/src/eap_peer/eap_leap.c b/src/eap_peer/eap_leap.c index 233b9eeb1..34758e021 100644 --- a/src/eap_peer/eap_leap.c +++ b/src/eap_peer/eap_leap.c @@ -390,8 +390,8 @@ 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)); + forced_memzero(pw_hash, sizeof(pw_hash)); + forced_memzero(pw_hash_hash, sizeof(pw_hash_hash)); return key; } diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c index 8dcf7cc29..6453afe2f 100644 --- a/src/eap_peer/eap_peap.c +++ b/src/eap_peer/eap_peap.c @@ -295,7 +295,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data) res = peap_prfplus(data->peap_version, tk, 40, "Inner Methods Compound Keys", isk, sizeof(isk), imck, sizeof(imck)); - os_memset(isk, 0, sizeof(isk)); + forced_memzero(isk, sizeof(isk)); if (res < 0) return -1; wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)", @@ -305,7 +305,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data) wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40); os_memcpy(data->cmk, imck + 40, 20); wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK (CMKj)", data->cmk, 20); - os_memset(imck, 0, sizeof(imck)); + forced_memzero(imck, sizeof(imck)); return 0; } @@ -1267,7 +1267,7 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len) os_memcpy(key, csk, EAP_TLS_KEY_LEN); wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key", key, EAP_TLS_KEY_LEN); - os_memset(csk, 0, sizeof(csk)); + forced_memzero(csk, sizeof(csk)); } else os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN); diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c index 76fcad4a5..6cd72e0c1 100644 --- a/src/eap_peer/eap_pwd.c +++ b/src/eap_peer/eap_pwd.c @@ -362,7 +362,7 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, data->password_len, pwhash); if (res == 0) res = hash_nt_password_hash(pwhash, pwhashhash); - os_memset(pwhash, 0, sizeof(pwhash)); + forced_memzero(pwhash, sizeof(pwhash)); } if (res) { @@ -514,8 +514,8 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, data->id_server, data->id_server_len, data->id_peer, data->id_peer_len, data->token); - os_memset(pwhashhash, 0, sizeof(pwhashhash)); - os_memset(salthashpwd, 0, sizeof(salthashpwd)); + forced_memzero(pwhashhash, sizeof(pwhashhash)); + forced_memzero(salthashpwd, sizeof(salthashpwd)); if (res) { wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE"); eap_pwd_state(data, FAILURE); diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c index 92c0e5ec9..5e125acf7 100644 --- a/src/eap_server/eap_server_peap.c +++ b/src/eap_server/eap_server_peap.c @@ -362,7 +362,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data) res = peap_prfplus(data->peap_version, tk, 40, "Inner Methods Compound Keys", isk, sizeof(isk), imck, sizeof(imck)); - os_memset(isk, 0, sizeof(isk)); + forced_memzero(isk, sizeof(isk)); if (res < 0) { os_free(tk); return -1; @@ -376,7 +376,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data) wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40); os_memcpy(data->cmk, imck + 40, 20); wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK (CMKj)", data->cmk, 20); - os_memset(imck, 0, sizeof(imck)); + forced_memzero(imck, sizeof(imck)); return 0; } @@ -1326,7 +1326,7 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len) "key"); } - os_memset(csk, 0, sizeof(csk)); + forced_memzero(csk, sizeof(csk)); return eapKeyData; } diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c index e720a28c8..a8087c1d8 100644 --- a/src/eap_server/eap_server_pwd.c +++ b/src/eap_server/eap_server_pwd.c @@ -632,7 +632,7 @@ static void eap_pwd_process_id_resp(struct eap_sm *sm, data->id_server, data->id_server_len, data->id_peer, data->id_peer_len, (u8 *) &data->token); - os_memset(pwhashhash, 0, sizeof(pwhashhash)); + forced_memzero(pwhashhash, sizeof(pwhashhash)); if (res) { wpa_printf(MSG_INFO, "EAP-PWD (server): unable to compute " "PWE"); diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 8accb9c80..c929e8194 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -334,7 +334,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN); sm->xxkey_len = PMK_LEN; } - os_memset(buf, 0, sizeof(buf)); + forced_memzero(buf, sizeof(buf)); if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_ft(sm->key_mgmt)) { struct rsn_pmksa_cache_entry *sa = NULL; @@ -649,7 +649,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, os_memcpy(buf, &ptk->tk[16], 8); os_memcpy(&ptk->tk[16], &ptk->tk[24], 8); os_memcpy(&ptk->tk[24], buf, 8); - os_memset(buf, 0, sizeof(buf)); + forced_memzero(buf, sizeof(buf)); } sm->tptk_set = 1; @@ -923,7 +923,7 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: Failed to set GTK to the driver " "(Group only)"); - os_memset(gtk_buf, 0, sizeof(gtk_buf)); + forced_memzero(gtk_buf, sizeof(gtk_buf)); return -1; } } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr, @@ -933,10 +933,10 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, "WPA: Failed to set GTK to " "the driver (alg=%d keylen=%d keyidx=%d)", gd->alg, gd->gtk_len, gd->keyidx); - os_memset(gtk_buf, 0, sizeof(gtk_buf)); + forced_memzero(gtk_buf, sizeof(gtk_buf)); return -1; } - os_memset(gtk_buf, 0, sizeof(gtk_buf)); + forced_memzero(gtk_buf, sizeof(gtk_buf)); if (wnm_sleep) { sm->gtk_wnm_sleep.gtk_len = gd->gtk_len; @@ -1042,10 +1042,10 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Failed to install GTK"); - os_memset(&gd, 0, sizeof(gd)); + forced_memzero(&gd, sizeof(gd)); return -1; } - os_memset(&gd, 0, sizeof(gd)); + forced_memzero(&gd, sizeof(gd)); return 0; } @@ -1714,12 +1714,12 @@ static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm, os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len); os_memcpy(gd->gtk, key_data, key_data_len); if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) { - os_memset(ek, 0, sizeof(ek)); + forced_memzero(ek, sizeof(ek)); wpa_msg(sm->ctx->msg_ctx, MSG_ERROR, "WPA: RC4 failed"); return -1; } - os_memset(ek, 0, sizeof(ek)); + forced_memzero(ek, sizeof(ek)); #endif /* CONFIG_NO_RC4 */ } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { if (maxkeylen % 8) { @@ -1868,7 +1868,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm, if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) || wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0) goto failed; - os_memset(&gd, 0, sizeof(gd)); + forced_memzero(&gd, sizeof(gd)); if (rekey) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying " @@ -1887,7 +1887,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm, return; failed: - os_memset(&gd, 0, sizeof(gd)); + forced_memzero(&gd, sizeof(gd)); wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED); } @@ -2001,12 +2001,12 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm, os_memcpy(ek, key->key_iv, 16); os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len); if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) { - os_memset(ek, 0, sizeof(ek)); + forced_memzero(ek, sizeof(ek)); wpa_msg(sm->ctx->msg_ctx, MSG_ERROR, "WPA: RC4 failed"); return -1; } - os_memset(ek, 0, sizeof(ek)); + forced_memzero(ek, sizeof(ek)); #endif /* CONFIG_NO_RC4 */ } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || ver == WPA_KEY_INFO_TYPE_AES_128_CMAC || @@ -3446,12 +3446,12 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)", gd.gtk, gd.gtk_len); if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) { - os_memset(&gd, 0, sizeof(gd)); + forced_memzero(&gd, sizeof(gd)); wpa_printf(MSG_DEBUG, "Failed to install the GTK in " "WNM mode"); return -1; } - os_memset(&gd, 0, sizeof(gd)); + forced_memzero(&gd, sizeof(gd)); #ifdef CONFIG_IEEE80211W } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) { const struct wpa_igtk_kde *igtk; @@ -3881,7 +3881,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, dh_ss ? wpabuf_head(dh_ss) : NULL, dh_ss ? wpabuf_len(dh_ss) : 0, sm->pmk, &sm->pmk_len); - os_memset(rmsk, 0, sizeof(rmsk)); + forced_memzero(rmsk, sizeof(rmsk)); /* Don't use DHss in PTK derivation if PMKSA caching is not * used. */ @@ -3956,7 +3956,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, sm->fils_key_auth_ap, &sm->fils_key_auth_len); wpabuf_free(pub); - os_memset(ick, 0, sizeof(ick)); + forced_memzero(ick, sizeof(ick)); return res; fail: wpabuf_free(pub); @@ -4480,9 +4480,11 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len) wpa_printf(MSG_DEBUG, "FILS: Auth+Assoc completed successfully"); sm->fils_completed = 1; + forced_memzero(&gd, sizeof(gd)); return 0; fail: + forced_memzero(&gd, sizeof(gd)); return -1; } @@ -4694,7 +4696,7 @@ int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid, else if (group == 21) res = hmac_sha512_kdf(prk, hash_len, NULL, (const u8 *) info, os_strlen(info), sm->pmk, hash_len); - os_memset(prk, 0, SHA512_MAC_LEN); + forced_memzero(prk, SHA512_MAC_LEN); if (res < 0) { sm->pmk_len = 0; return -1; diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 41592511e..46ffdca67 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -828,10 +828,10 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem, igtk_elem + 2, 6, igtk, igtk_len) < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the " "driver."); - os_memset(igtk, 0, sizeof(igtk)); + forced_memzero(igtk, sizeof(igtk)); return -1; } - os_memset(igtk, 0, sizeof(igtk)); + forced_memzero(igtk, sizeof(igtk)); return 0; } diff --git a/src/utils/common.c b/src/utils/common.c index 836fef190..27bf435d9 100644 --- a/src/utils/common.c +++ b/src/utils/common.c @@ -970,7 +970,7 @@ void str_clear_free(char *str) { if (str) { size_t len = os_strlen(str); - os_memset(str, 0, len); + forced_memzero(str, len); os_free(str); } } @@ -979,7 +979,7 @@ void str_clear_free(char *str) void bin_clear_free(void *bin, size_t len) { if (bin) { - os_memset(bin, 0, len); + forced_memzero(bin, len); os_free(bin); } } @@ -1259,3 +1259,22 @@ char * get_param(const char *cmd, const char *param) val[len] = '\0'; return val; } + + +/* Try to prevent most compilers from optimizing out clearing of memory that + * becomes unaccessible after this function is called. This is mostly the case + * for clearing local stack variables at the end of a function. This is not + * exactly perfect, i.e., someone could come up with a compiler that figures out + * the pointer is pointing to memset and then end up optimizing the call out, so + * try go a bit further by storing the first octet (now zero) to make this even + * a bit more difficult to optimize out. Once memset_s() is available, that + * could be used here instead. */ +static void * (* const volatile memset_func)(void *, int, size_t) = memset; +static u8 forced_memzero_val; + +void forced_memzero(void *ptr, size_t len) +{ + memset_func(ptr, 0, len); + if (len) + forced_memzero_val = ((u8 *) ptr)[0]; +} diff --git a/src/utils/common.h b/src/utils/common.h index 36f67fa71..17411451d 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -570,6 +570,8 @@ int str_starts(const char *str, const char *start); u8 rssi_to_rcpi(int rssi); char * get_param(const char *cmd, const char *param); +void forced_memzero(void *ptr, 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