/** * wps_deinit - Deinitialize WPS Registration protocol data * @data: WPS Registration protocol data from wps_init() */ void wps_deinit(struct wps_data *data) { if (data->wps_pin_revealed) { wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and " "negotiation failed"); if (data->registrar) wps_registrar_invalidate_pin(data->wps->registrar, data->uuid_e); } else if (data->registrar) wps_registrar_unlock_pin(data->wps->registrar, data->uuid_e); /* @@@ Free wpa key and essid pointers @@@ */ if (data->key) free(data->key); if (data->essid) free(data->essid); wpabuf_free(data->dh_privkey); wpabuf_free(data->dh_pubkey_e); wpabuf_free(data->dh_pubkey_r); wpabuf_free(data->last_msg); os_free(data->dev_password); os_free(data->new_psk); wps_device_data_free(&data->peer_dev); os_free(data->new_ap_settings); dh5_free(data->dh_ctx); os_free(data); }
/** * wps_deinit - Deinitialize WPS Registration protocol data * @data: WPS Registration protocol data from wps_init() */ void wps_deinit(struct wps_data *data) { #ifdef CONFIG_WPS_NFC if (data->registrar && data->nfc_pw_token) wps_registrar_remove_nfc_pw_token(data->wps->registrar, data->nfc_pw_token); #endif /* CONFIG_WPS_NFC */ if (data->wps_pin_revealed) { wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and " "negotiation failed"); if (data->registrar) wps_registrar_invalidate_pin(data->wps->registrar, data->uuid_e); } else if (data->registrar) wps_registrar_unlock_pin(data->wps->registrar, data->uuid_e); wpabuf_free(data->dh_privkey); wpabuf_free(data->dh_pubkey_e); wpabuf_free(data->dh_pubkey_r); wpabuf_free(data->last_msg); bin_clear_free(data->dev_password, data->dev_password_len); bin_clear_free(data->alt_dev_password, data->alt_dev_password_len); bin_clear_free(data->new_psk, data->new_psk_len); wps_device_data_free(&data->peer_dev); bin_clear_free(data->new_ap_settings, sizeof(*data->new_ap_settings)); dh5_free(data->dh_ctx); os_free(data); }
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); if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) { wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys"); wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey); wps->dh_ctx = wps->wps->dh_ctx; wps->wps->dh_ctx = NULL; pubkey = wpabuf_dup(wps->wps->dh_pubkey); #ifdef CONFIG_WPS_NFC } else if (wps->dev_pw_id >= 0x10 && wps->wps->ap && wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id) { wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys"); wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey); pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_pubkey); wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, pubkey); #endif /* CONFIG_WPS_NFC */ } else { wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys"); wps->dh_privkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); pubkey = wpabuf_zeropad(pubkey, 192); } if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " "Diffie-Hellman handshake"); wpabuf_free(pubkey); return -1; } wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey); wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey); wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); wpabuf_put_be16(msg, wpabuf_len(pubkey)); wpabuf_put_buf(msg, pubkey); if (wps->registrar) { wpabuf_free(wps->dh_pubkey_r); wps->dh_pubkey_r = pubkey; } else { wpabuf_free(wps->dh_pubkey_e); wps->dh_pubkey_e = pubkey; } return 0; }
int wps_nfc_gen_dh(struct wpabuf **pubkey, struct wpabuf **privkey) { struct wpabuf *priv = NULL, *pub = NULL; void *dh_ctx; dh_ctx = dh5_init(&priv, &pub); if (dh_ctx == NULL) return -1; pub = wpabuf_zeropad(pub, 192); if (pub == NULL) { wpabuf_free(priv); dh5_free(dh_ctx); return -1; } wpa_hexdump_buf(MSG_DEBUG, "WPS: Generated new DH pubkey", pub); dh5_free(dh_ctx); wpabuf_free(*pubkey); *pubkey = pub; wpabuf_clear_free(*privkey); *privkey = priv; return 0; }
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, char *path, char *method, char *name) { struct wps_context *wps = wpa_s->wps; struct oob_device_data *oob_dev; oob_dev = wps_get_oob_device(device_type); if (oob_dev == NULL) return -1; oob_dev->device_path = path; oob_dev->device_name = name; wps->oob_conf.oob_method = wps_get_oob_method(method); if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) { /* * Use pre-configured DH keys in order to be able to write the * key hash into the OOB file. */ wpabuf_free(wps->dh_pubkey); wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; wps->dh_pubkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &wps->dh_pubkey); wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192); if (wps->dh_ctx == NULL || wps->dh_pubkey == NULL) { wpa_printf(MSG_ERROR, "WPS: Failed to initialize " "Diffie-Hellman handshake"); return -1; } } if (wps->oob_conf.oob_method == OOB_METHOD_CRED) wpas_clear_wps(wpa_s); if (wps_process_oob(wps, oob_dev, 0) < 0) return -1; if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E || wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) && wpas_wps_start_pin(wpa_s, NULL, wpabuf_head(wps->oob_conf.dev_password), 0, DEV_PW_DEFAULT) < 0) return -1; return 0; }
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); //if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) { if (wps->wps->dh_privkey) { wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys"); wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey); wps->dh_ctx = wps->wps->dh_ctx; wps->wps->dh_ctx = NULL; pubkey = wpabuf_dup(wps->wps->dh_pubkey); } else { wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys"); wps->dh_privkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); pubkey = wpabuf_zeropad(pubkey, 192); } if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " "Diffie-Hellman handshake"); wpabuf_free(pubkey); return -1; } wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); wpabuf_put_be16(msg, wpabuf_len(pubkey)); wpabuf_put_buf(msg, pubkey); if (wps->registrar) { wpabuf_free(wps->dh_pubkey_r); wps->dh_pubkey_r = pubkey; } else { wpabuf_free(wps->dh_pubkey_e); wps->dh_pubkey_e = pubkey; } return 0; }
int wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id, const struct wpabuf *pw, const u8 *pubkey_hash) { struct hostapd_data *hapd; struct wps_context *wps; if (!wpa_s->ap_iface) return -1; hapd = wpa_s->ap_iface->bss[0]; wps = hapd->wps; if (wpa_s->p2pdev->conf->wps_nfc_dh_pubkey == NULL || wpa_s->p2pdev->conf->wps_nfc_dh_privkey == NULL) { wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known"); return -1; } dh5_free(wps->dh_ctx); wpabuf_free(wps->dh_pubkey); wpabuf_free(wps->dh_privkey); wps->dh_privkey = wpabuf_dup( wpa_s->p2pdev->conf->wps_nfc_dh_privkey); wps->dh_pubkey = wpabuf_dup( wpa_s->p2pdev->conf->wps_nfc_dh_pubkey); if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) { wps->dh_ctx = NULL; wpabuf_free(wps->dh_pubkey); wps->dh_pubkey = NULL; wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; return -1; } wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey); if (wps->dh_ctx == NULL) return -1; return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash, pw_id, pw ? wpabuf_head(pw) : NULL, pw ? wpabuf_len(pw) : 0, 1); }
struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, struct wpabuf **privkey, struct wpabuf **dev_pw) { struct wpabuf *priv = NULL, *pub = NULL, *pw; void *dh_ctx; u16 val; pw = wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN); if (pw == NULL) return NULL; if (random_get_bytes(wpabuf_put(pw, WPS_OOB_DEVICE_PASSWORD_LEN), WPS_OOB_DEVICE_PASSWORD_LEN) || random_get_bytes((u8 *) &val, sizeof(val))) { wpabuf_free(pw); return NULL; } dh_ctx = dh5_init(&priv, &pub); if (dh_ctx == NULL) { wpabuf_free(pw); return NULL; } dh5_free(dh_ctx); *id = 0x10 + val % 0xfff0; wpabuf_free(*pubkey); *pubkey = pub; wpabuf_free(*privkey); *privkey = priv; wpabuf_free(*dev_pw); *dev_pw = pw; return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw); }
int wps_derive_keys(struct wps_data *wps) { struct wpabuf *pubkey, *dh_shared; u8 dhkey[SHA256_MAC_LEN], kdk[SHA256_MAC_LEN]; const u8 *addr[3]; size_t len[3]; u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN]; if (wps->dh_privkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available"); return -1; } pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r; if (pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available"); return -1; } wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey); wpa_hexdump_buf(MSG_DEBUG, "WPS: DH peer Public Key", pubkey); dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey); dh5_free(wps->dh_ctx); wps->dh_ctx = NULL; dh_shared = wpabuf_zeropad(dh_shared, 192); if (dh_shared == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key"); return -1; } /* Own DH private key is not needed anymore */ wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared); /* DHKey = SHA-256(g^AB mod p) */ addr[0] = wpabuf_head(dh_shared); 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); /* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */ addr[0] = wps->nonce_e; len[0] = WPS_NONCE_LEN; addr[1] = wps->mac_addr_e; len[1] = ETH_ALEN; addr[2] = wps->nonce_r; len[2] = WPS_NONCE_LEN; hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk); wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk)); wps_kdf(kdk, NULL, 0, "Wi-Fi Easy and Secure Key Derivation", keys, sizeof(keys)); os_memcpy(wps->authkey, keys, WPS_AUTHKEY_LEN); os_memcpy(wps->keywrapkey, keys + WPS_AUTHKEY_LEN, WPS_KEYWRAPKEY_LEN); os_memcpy(wps->emsk, keys + WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN, WPS_EMSK_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: AuthKey", wps->authkey, WPS_AUTHKEY_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey", wps->keywrapkey, WPS_KEYWRAPKEY_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN); return 0; }
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); //if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) { if (wps->wps->dh_privkey) { wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys"); wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey); wps->dh_ctx = wps->wps->dh_ctx; wps->wps->dh_ctx = NULL; pubkey = wpabuf_dup(wps->wps->dh_pubkey); } else { wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys"); wps->dh_privkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); pubkey = wpabuf_zeropad(pubkey, 192); } if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " "Diffie-Hellman handshake"); wpabuf_free(pubkey); return -1; } wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); wpabuf_put_be16(msg, wpabuf_len(pubkey)); wpabuf_put_buf(msg, pubkey); if (wps->registrar) { wpabuf_free(wps->dh_pubkey_r); wps->dh_pubkey_r = pubkey; unsigned char *v; v = wpabuf_mhead_u8(pubkey); memset(pixie_pkr, 0, sizeof (pixie_pkr)); if (get_debug() == 4) { //verbose (-vvv) printf("[P] PKR: "); } int pixiecnt = 0; for (; pixiecnt < 192; pixiecnt++) { if (get_debug() == 4) { //verbose (-vvv) printf("%02x", v[pixiecnt]); } sprintf(cmd_pixie_aux, "%02x", v[pixiecnt]); strcat(pixie_pkr, cmd_pixie_aux); if (pixiecnt != 191) { if (get_debug() == 4) { //verbose (-vvv) printf(":"); } strcat(pixie_pkr, ":"); } } if (get_debug() == 4) { //verbose (-vvv) printf("\n"); } } else { wpabuf_free(wps->dh_pubkey_e); wps->dh_pubkey_e = pubkey; } return 0; }
int wps_derive_keys(struct wps_data *wps) { struct wpabuf *pubkey, *dh_shared; u8 dhkey[SHA256_MAC_LEN], kdk[SHA256_MAC_LEN]; const u8 *addr[3]; size_t len[3]; u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN]; if (wps->dh_privkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available"); return -1; } pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r; if (pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available"); return -1; } dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey); dh5_free(wps->dh_ctx); wps->dh_ctx = NULL; dh_shared = wpabuf_zeropad(dh_shared, 192); if (dh_shared == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key"); return -1; } /* Own DH private key is not needed anymore */ wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared); /* DHKey = SHA-256(g^AB mod p) */ addr[0] = wpabuf_head(dh_shared); 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); /* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */ addr[0] = wps->nonce_e; len[0] = WPS_NONCE_LEN; addr[1] = wps->mac_addr_e; len[1] = ETH_ALEN; addr[2] = wps->nonce_r; len[2] = WPS_NONCE_LEN; hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk); wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk)); wps_kdf(kdk, NULL, 0, "Wi-Fi Easy and Secure Key Derivation", keys, sizeof(keys)); os_memcpy(wps->authkey, keys, WPS_AUTHKEY_LEN); os_memcpy(wps->keywrapkey, keys + WPS_AUTHKEY_LEN, WPS_KEYWRAPKEY_LEN); os_memcpy(wps->emsk, keys + WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN, WPS_EMSK_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: AuthKey", wps->authkey, WPS_AUTHKEY_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey", wps->keywrapkey, WPS_KEYWRAPKEY_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN); /****** ADD THIS PART ******/ memset(pixie_authkey,0,sizeof(pixie_authkey)); if ( get_debug()==4 ) { //verbose (-vvv) printf("[P] AuthKey: "); } int pixiecnt = 0; for (; pixiecnt < WPS_AUTHKEY_LEN; pixiecnt++) { if ( get_debug()==4 ) { //verbose (-vvv) printf("%02x", wps->authkey[pixiecnt]); } sprintf(cmd_pixie_aux, "%02x", wps->authkey[pixiecnt]); strcat(pixie_authkey, cmd_pixie_aux); if (pixiecnt != WPS_AUTHKEY_LEN - 1) { if ( get_debug()==4 ) { //verbose (-vvv) printf(":"); } strcat(pixie_authkey,":"); } } if ( get_debug()==4 ) { //verbose (-vvv) printf("\n"); } /******/ return 0; }