Ejemplo n.º 1
0
/**
 * 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);
}
Ejemplo n.º 2
0
/**
 * 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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}