More forceful clearing of stack memory with keys

gcc 8.3.0 was apparently clever enough to optimize away the previously
used os_memset() to explicitly clear a stack buffer that contains keys
when that clearing happened just before returning from the function.
Since memset_s() is not exactly portable (or commonly available yet..),
use a less robust mechanism that is still pretty likely to prevent
current compilers from optimizing the explicit clearing of the memory
away.

Signed-off-by: Jouni Malinen <j@w1.fi>
master
Jouni Malinen 5 years ago
parent e1923f5b6a
commit 31bc66e4d1

@ -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;
}

@ -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;

@ -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 ===== */

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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);

@ -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);

@ -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);

@ -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;
}

@ -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);

@ -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);

@ -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;
}

@ -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");

@ -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;

@ -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;
}

@ -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];
}

@ -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

Loading…
Cancel
Save