From: Jouni Malinen Date: Thu, 28 Apr 2016 17:32:15 +0000 (+0300) Subject: WPS: Explicitly clear wpabuf memory with key information X-Git-Tag: hostap_2_6~524 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=60d9f67c68f2cb83f116b81944f3429981ec9cea;p=thirdparty%2Fhostap.git 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 --- diff --git a/src/wps/wps.c b/src/wps/wps.c index 7c6dcb2b3..fade6b690 100644 --- a/src/wps/wps.c +++ b/src/wps/wps.c @@ -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); diff --git a/src/wps/wps_attr_build.c b/src/wps/wps_attr_build.c index 748620f94..c3befc4f1 100644 --- a/src/wps/wps_attr_build.c +++ b/src/wps/wps_attr_build.c @@ -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) { diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index c6a1cfda8..7e48dd8c4 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -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); diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 9321b721a..c0c2b9ccb 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -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; diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 25e88d5ad..e0c6a912b 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -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;