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>
This commit is contained in:
parent
e1923f5b6a
commit
31bc66e4d1
25 changed files with 98 additions and 72 deletions
|
@ -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…
Reference in a new issue