int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg) { struct wpabuf *pubkey; wpa_printf(MSG_DEBUG, "WPS: * Public Key"); pubkey = dh_init(dh_groups_get(WPS_DH_GROUP), &wps->dh_privkey); pubkey = wpabuf_zeropad(pubkey, 192); if (pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " "Diffie-Hellman handshake"); 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 hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type, char *path, char *method, char *name) { struct wps_context *wps = hapd->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_R) { /* * 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 = dh_init(dh_groups_get(WPS_DH_GROUP), &wps->dh_privkey); wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192); if (wps->dh_pubkey == NULL) { wpa_printf(MSG_ERROR, "WPS: Failed to initialize " "Diffie-Hellman handshake"); return -1; } } if (wps_process_oob(wps, oob_dev, 1) < 0) goto error; if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E || wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) && hostapd_wps_add_pin(hapd, NULL, "any", wpabuf_head(wps->oob_conf.dev_password), 0) < 0) goto error; return 0; error: wpabuf_free(wps->dh_pubkey); wps->dh_pubkey = NULL; wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; return -1; }
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 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 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); return -1; } wpa_hexdump_buf(MSG_DEBUG, "WPS: Generated new DH pubkey", pub); dh5_free(dh_ctx); wpabuf_free(*pubkey); *pubkey = pub; wpabuf_free(*privkey); *privkey = priv; 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; } 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; }