WPS: Explicitly clear wpabuf memory with key information
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 28 Apr 2016 17:32:15 +0000 (20:32 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 28 Apr 2016 17:32:15 +0000 (20:32 +0300)
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>
src/wps/wps.c
src/wps/wps_attr_build.c
src/wps/wps_common.c
src/wps/wps_enrollee.c
src/wps/wps_registrar.c

index 7c6dcb2..fade6b6 100644 (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);
index 748620f..c3befc4 100644 (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) {
index c6a1cfd..7e48dd8 100644 (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);
index 9321b72..c0c2b9c 100644 (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;
index 25e88d5..e0c6a91 100644 (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;