WPS: Explicitly clear wpabuf memory with key information

This reduces duration that private keying material might remain in the
process memory by clearing wpabuf data used in WPS operations when there
is possibility of the buffer including keys or related material.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2016-04-28 20:32:15 +03:00 committed by Jouni Malinen
parent 0663ae22ff
commit 60d9f67c68
5 changed files with 48 additions and 48 deletions

View file

@ -174,7 +174,7 @@ void wps_deinit(struct wps_data *data)
} else if (data->registrar)
wps_registrar_unlock_pin(data->wps->registrar, data->uuid_e);
wpabuf_free(data->dh_privkey);
wpabuf_clear_free(data->dh_privkey);
wpabuf_free(data->dh_pubkey_e);
wpabuf_free(data->dh_pubkey_r);
wpabuf_free(data->last_msg);

View file

@ -23,7 +23,7 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
struct wpabuf *pubkey;
wpa_printf(MSG_DEBUG, "WPS: * Public Key");
wpabuf_free(wps->dh_privkey);
wpabuf_clear_free(wps->dh_privkey);
wps->dh_privkey = NULL;
if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey &&
wps->wps->dh_ctx) {

View file

@ -90,7 +90,7 @@ int wps_derive_keys(struct wps_data *wps)
}
/* Own DH private key is not needed anymore */
wpabuf_free(wps->dh_privkey);
wpabuf_clear_free(wps->dh_privkey);
wps->dh_privkey = NULL;
wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared);
@ -100,7 +100,7 @@ int wps_derive_keys(struct wps_data *wps)
len[0] = wpabuf_len(dh_shared);
sha256_vector(1, addr, len, dhkey);
wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey));
wpabuf_free(dh_shared);
wpabuf_clear_free(dh_shared);
/* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */
addr[0] = wps->nonce_e;
@ -173,7 +173,7 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size);
if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted),
wpabuf_len(decrypted))) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
return NULL;
}
@ -184,14 +184,14 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
pad = *pos;
if (pad > wpabuf_len(decrypted)) {
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value");
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
return NULL;
}
for (i = 0; i < pad; i++) {
if (*pos-- != pad) {
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad "
"string");
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
return NULL;
}
}
@ -373,7 +373,7 @@ struct wpabuf * wps_get_oob_cred(struct wps_context *wps, int rf_band,
wps_build_mac_addr(plain, wps->dev.mac_addr) ||
wps_build_wfa_ext(plain, 0, NULL, 0)) {
os_free(data.new_psk);
wpabuf_free(plain);
wpabuf_clear_free(plain);
return NULL;
}
@ -421,7 +421,7 @@ struct wpabuf * wps_build_nfc_pw_token(u16 dev_pw_id,
wps_build_wfa_ext(data, 0, NULL, 0)) {
wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
"token");
wpabuf_free(data);
wpabuf_clear_free(data);
return NULL;
}
@ -658,7 +658,7 @@ int wps_nfc_gen_dh(struct wpabuf **pubkey, struct wpabuf **privkey)
wpabuf_free(*pubkey);
*pubkey = pub;
wpabuf_free(*privkey);
wpabuf_clear_free(*privkey);
*privkey = priv;
return 0;
@ -689,7 +689,7 @@ struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
}
*id = 0x10 + val % 0xfff0;
wpabuf_free(*dev_pw);
wpabuf_clear_free(*dev_pw);
*dev_pw = pw;
return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw);

View file

@ -224,11 +224,11 @@ static struct wpabuf * wps_build_m5(struct wps_data *wps)
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
wps->state = RECV_M6;
return msg;
@ -394,11 +394,11 @@ static struct wpabuf * wps_build_m7(struct wps_data *wps)
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
if (wps->wps->ap && wps->wps->registrar) {
/*
@ -1007,11 +1007,11 @@ static enum wps_process_res wps_process_m2(struct wps_data *wps,
eattr.key_wrap_auth) ||
wps_process_creds(wps, eattr.cred, eattr.cred_len,
eattr.num_cred, attr->version2 != NULL)) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = WPS_MSG_DONE;
return WPS_CONTINUE;
@ -1112,7 +1112,7 @@ static enum wps_process_res wps_process_m4(struct wps_data *wps,
}
if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
@ -1122,11 +1122,11 @@ static enum wps_process_res wps_process_m4(struct wps_data *wps,
if (wps_parse_msg(decrypted, &eattr) < 0 ||
wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
wps_process_r_snonce1(wps, eattr.r_snonce1)) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_M5;
return WPS_CONTINUE;
@ -1165,7 +1165,7 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps,
}
if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
@ -1175,11 +1175,11 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps,
if (wps_parse_msg(decrypted, &eattr) < 0 ||
wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
wps_process_r_snonce2(wps, eattr.r_snonce2)) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
if (wps->wps->ap)
wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
@ -1236,7 +1236,7 @@ static enum wps_process_res wps_process_m8(struct wps_data *wps,
if (wps_validate_m8_encr(decrypted, wps->wps->ap,
attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
@ -1249,11 +1249,11 @@ static enum wps_process_res wps_process_m8(struct wps_data *wps,
eattr.num_cred, attr->version2 != NULL) ||
wps_process_ap_settings_e(wps, &eattr, decrypted,
attr->version2 != NULL)) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = WPS_MSG_DONE;
return WPS_CONTINUE;

View file

@ -703,7 +703,7 @@ void wps_registrar_deinit(struct wps_registrar *reg)
eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
wps_registrar_flush(reg);
wpabuf_free(reg->extra_cred);
wpabuf_clear_free(reg->extra_cred);
os_free(reg);
}
@ -1577,13 +1577,13 @@ int wps_build_credential_wrap(struct wpabuf *msg,
if (wbuf == NULL)
return -1;
if (wps_build_credential(wbuf, cred)) {
wpabuf_free(wbuf);
wpabuf_clear_free(wbuf);
return -1;
}
wpabuf_put_be16(msg, ATTR_CRED);
wpabuf_put_be16(msg, wpabuf_len(wbuf));
wpabuf_put_buf(msg, wbuf);
wpabuf_free(wbuf);
wpabuf_clear_free(wbuf);
return 0;
}
@ -1751,14 +1751,14 @@ use_provided:
return -1;
if (wps_build_credential(cred, &wps->cred)) {
wpabuf_free(cred);
wpabuf_clear_free(cred);
return -1;
}
wpabuf_put_be16(msg, ATTR_CRED);
wpabuf_put_be16(msg, wpabuf_len(cred));
wpabuf_put_buf(msg, cred);
wpabuf_free(cred);
wpabuf_clear_free(cred);
skip_cred_build:
if (wps->wps->registrar->extra_cred) {
@ -1796,7 +1796,7 @@ static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
}
if (wps_build_ap_settings(wps, plain)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
@ -1804,7 +1804,7 @@ static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
wpabuf_put_be16(msg, ATTR_CRED);
wpabuf_put_be16(msg, wpabuf_len(plain));
wpabuf_put_buf(msg, plain);
wpabuf_free(plain);
wpabuf_clear_free(plain);
return msg;
}
@ -1864,10 +1864,10 @@ static struct wpabuf * wps_build_m2(struct wps_data *wps)
wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain)) {
wpabuf_free(msg);
wpabuf_free(plain);
wpabuf_clear_free(plain);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
config_in_m2 = 1;
}
#endif /* CONFIG_WPS_NFC */
@ -1949,11 +1949,11 @@ static struct wpabuf * wps_build_m4(struct wps_data *wps)
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
wps->state = RECV_M5;
return msg;
@ -1984,11 +1984,11 @@ static struct wpabuf * wps_build_m6(struct wps_data *wps)
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
wps->wps_pin_revealed = 1;
wps->state = RECV_M7;
@ -2021,11 +2021,11 @@ static struct wpabuf * wps_build_m8(struct wps_data *wps)
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_free(msg);
wpabuf_clear_free(plain);
wpabuf_clear_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
wps->state = RECV_DONE;
return msg;
@ -2785,7 +2785,7 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps,
}
if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
@ -2795,11 +2795,11 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps,
if (wps_parse_msg(decrypted, &eattr) < 0 ||
wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
wps_process_e_snonce1(wps, eattr.e_snonce1)) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_M6;
return WPS_CONTINUE;
@ -2937,7 +2937,7 @@ static enum wps_process_res wps_process_m7(struct wps_data *wps,
if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er,
attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
@ -2948,12 +2948,12 @@ static enum wps_process_res wps_process_m7(struct wps_data *wps,
wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
wps_process_e_snonce2(wps, eattr.e_snonce2) ||
wps_process_ap_settings_r(wps, &eattr)) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_M8;
return WPS_CONTINUE;