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;
#endif /* CONFIG_SHA256 */
#endif /* CONFIG_SHA384 */
+ forced_memzero(data, sizeof(data));
+
return ret;
}
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
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,
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);
sm->MICVerified = TRUE;
os_memcpy(&sm->PTK, &PTK, sizeof(PTK));
+ forced_memzero(&PTK, sizeof(PTK));
sm->PTK_valid = TRUE;
}
return NULL;
}
+ forced_memzero(keybuf, sizeof(keybuf));
*len = subelem_len;
return subelem;
}
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;
}
ret = 0;
out:
- if (plain) {
- os_memset(plain, 0, plain_len);
- os_free(plain);
- }
+ bin_clear_free(plain, plain_len);
return ret;
/* Wipe variables */
a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF
- os_memset(block, 0, 64);
+ forced_memzero(block, 64);
#endif
}
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 ===== */
}
counter++;
}
- os_memset(hash, 0, sizeof(hash));
+ forced_memzero(hash, sizeof(hash));
return 0;
}
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;
}
len[0] = SHA1_MAC_LEN;
}
- os_memset(hash, 0, SHA1_MAC_LEN);
+ forced_memzero(hash, SHA1_MAC_LEN);
return 0;
}
_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;
}
if (iter == 255) {
os_memset(out, 0, outlen);
- os_memset(T, 0, SHA256_MAC_LEN);
+ forced_memzero(T, SHA256_MAC_LEN);
return -1;
}
iter++;
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;
}
buf[pos - 1] &= mask;
}
- os_memset(hash, 0, sizeof(hash));
+ forced_memzero(hash, sizeof(hash));
return 0;
}
if (iter == 255) {
os_memset(out, 0, outlen);
- os_memset(T, 0, SHA384_MAC_LEN);
+ forced_memzero(T, SHA384_MAC_LEN);
return -1;
}
iter++;
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;
}
buf[pos - 1] &= mask;
}
- os_memset(hash, 0, sizeof(hash));
+ forced_memzero(hash, sizeof(hash));
return 0;
}
if (iter == 255) {
os_memset(out, 0, outlen);
- os_memset(T, 0, SHA512_MAC_LEN);
+ forced_memzero(T, SHA512_MAC_LEN);
return -1;
}
iter++;
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;
}
buf[pos - 1] &= mask;
}
- os_memset(hash, 0, sizeof(hash));
+ forced_memzero(hash, sizeof(hash));
return 0;
}
_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);
_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);
*/
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);
}
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);
}
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);
}
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);
}
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);
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;
}
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)",
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;
}
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);
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) {
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);
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;
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;
}
"key");
}
- os_memset(csk, 0, sizeof(csk));
+ forced_memzero(csk, sizeof(csk));
return eapKeyData;
}
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");
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;
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;
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,
"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;
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;
}
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) {
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 "
return;
failed:
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
}
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 ||
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;
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. */
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);
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;
}
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;
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;
}
{
if (str) {
size_t len = os_strlen(str);
- os_memset(str, 0, len);
+ forced_memzero(str, len);
os_free(str);
}
}
void bin_clear_free(void *bin, size_t len)
{
if (bin) {
- os_memset(bin, 0, len);
+ forced_memzero(bin, len);
os_free(bin);
}
}
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];
+}
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