Exemplo n.º 1
0
struct ctrl_iface_global_priv *
wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
{
	struct ctrl_iface_global_priv *priv;
	struct sockaddr_in addr;
	int port = WPA_GLOBAL_CTRL_IFACE_PORT;

	priv = os_zalloc(sizeof(*priv));
	if (priv == NULL)
		return NULL;
	priv->sock = -1;
	os_get_random(priv->cookie, COOKIE_LEN);

	if (global->params.ctrl_interface == NULL)
		return priv;

	wpa_printf(MSG_DEBUG, "Global control interface '%s'",
		   global->params.ctrl_interface);

	priv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (priv->sock < 0) {
		perror("socket(PF_INET)");
		goto fail;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
	addr.sin_addr.s_addr = INADDR_ANY;
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
	addr.sin_addr.s_addr = htonl((127 << 24) | 1);
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
try_again:
	addr.sin_port = htons(port);
	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		port++;
		if ((port - WPA_GLOBAL_CTRL_IFACE_PORT) <
		    WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT)
			goto try_again;
		perror("bind(AF_INET)");
		goto fail;
	}

#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
	wpa_printf(MSG_DEBUG, "global_ctrl_iface_init UDP port: %d", port);
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */

	eloop_register_read_sock(priv->sock,
				 wpa_supplicant_global_ctrl_iface_receive,
				 global, priv);

	return priv;

fail:
	if (priv->sock >= 0)
		close(priv->sock);
	os_free(priv);
	return NULL;
}
Exemplo n.º 2
0
/* uuid_make -- construct a random UUID
 * The UPnP documents don't seem to offer any guidelines as to which method to
 * use for constructing UUIDs for subscriptions. Presumably any method from
 * rfc4122 is good enough; I've chosen random number method.
 */
static void uuid_make(u8 uuid[UUID_LEN])
{
	os_get_random(uuid, UUID_LEN);

	/* Replace certain bits as specified in rfc4122 or X.667 */
	uuid[6] &= 0x0f; uuid[6] |= (4 << 4);   /* version 4 == random gen */
	uuid[8] &= 0x3f; uuid[8] |= 0x80;
}
static u8 p2p_channel_pick_random(const u8 *channels, unsigned int num_channels)
{
	unsigned int r;
	if (os_get_random((u8 *) &r, sizeof(r)) < 0)
		r = 0;
	r %= num_channels;
	return channels[r];
}
Exemplo n.º 4
0
int tls_derive_pre_master_secret(u8 *pre_master_secret)
{
	WPA_PUT_BE16(pre_master_secret, TLS_VERSION);
	if (os_get_random(pre_master_secret + 2,
			  TLS_PRE_MASTER_SECRET_LEN - 2))
		return -1;
	return 0;
}
Exemplo n.º 5
0
int radius_gen_session_id(u8 *id, size_t len)
{
	/*
	 * Acct-Session-Id and Acct-Multi-Session-Id should be globally and
	 * temporarily unique. A high quality random number is required
	 * therefore. This could be be improved by switching to a GUID.
	 */
	return os_get_random(id, len);
}
Exemplo n.º 6
0
/**
 * dh_init - Initialize Diffie-Hellman handshake
 * @dh: Selected Diffie-Hellman group
 * @priv: Pointer for returning Diffie-Hellman private key
 * Returns: Diffie-Hellman public value
 */
struct wpabuf * dh_init(const struct dh_group *dh, struct wpabuf **priv)
{
	struct wpabuf *pv;
	size_t pv_len;
	int retval = 1;

	if (dh == NULL)
		return NULL;

	wpabuf_free(*priv);
	*priv = wpabuf_alloc(dh->prime_len);
	if (*priv == NULL)
		return NULL;

	if(get_dh_small())
	{
		/* Use small DH secret (1) to reduce calculation time on AP */
		if(!memset(wpabuf_put(*priv, 1), 1, 1))
			retval = 0;
	}
	else
	{
		if(os_get_random(wpabuf_put(*priv, dh->prime_len), dh->prime_len))
			retval = 0;
	}
	
	if(!retval)
	{	
		wpabuf_free(*priv);
		*priv = NULL;
		return NULL;
	}

	if (os_memcmp(wpabuf_head(*priv), dh->prime, dh->prime_len) > 0) {
		/* Make sure private value is smaller than prime */
		*(wpabuf_mhead_u8(*priv)) = 0;
	}
	wpa_hexdump_buf_key(/*MSG_INFO*/ MSG_DEBUG, "DH: private value", *priv);

	pv_len = dh->prime_len;
	pv = wpabuf_alloc(pv_len);
	if (pv == NULL)
		return NULL;
	if (crypto_mod_exp(dh->generator, dh->generator_len,
			   wpabuf_head(*priv), wpabuf_len(*priv),
			   dh->prime, dh->prime_len, wpabuf_mhead(pv),
			   &pv_len) < 0) {
		wpabuf_free(pv);
		wpa_printf(MSG_INFO, "DH: crypto_mod_exp failed");
		return NULL;
	}
	wpabuf_put(pv, pv_len);
	wpa_hexdump_buf(MSG_DEBUG, "DH: public value", pv);

	return pv;
}
Exemplo n.º 7
0
struct ctrl_iface_priv *
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
{
	struct ctrl_iface_priv *priv;
	struct sockaddr_in addr;
	int port = WPA_CTRL_IFACE_PORT;

	priv = os_zalloc(sizeof(*priv));
	if (priv == NULL)
		return NULL;
	priv->wpa_s = wpa_s;
	priv->sock = -1;
	os_get_random(priv->cookie, COOKIE_LEN);

	if (wpa_s->conf->ctrl_interface == NULL)
		return priv;

	priv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (priv->sock < 0) {
		perror("socket(PF_INET)");
		goto fail;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
	addr.sin_addr.s_addr = INADDR_ANY;
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
	addr.sin_addr.s_addr = htonl((127 << 24) | 1);
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
try_again:
	addr.sin_port = htons(port);
	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		port--;
		if ((WPA_CTRL_IFACE_PORT - port) < WPA_CTRL_IFACE_PORT_LIMIT)
			goto try_again;
		perror("bind(AF_INET)");
		goto fail;
	}

#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
	wpa_msg(wpa_s, MSG_DEBUG, "ctrl_iface_init UDP port: %d", port);
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */

	eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
				 wpa_s, priv);
	wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);

	return priv;

fail:
	if (priv->sock >= 0)
		close(priv->sock);
	os_free(priv);
	return NULL;
}
Exemplo n.º 8
0
int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps)
{
	size_t hash_len;
	const u8 *addr[1];
	u8 pubkey_hash[WPS_HASH_LEN];
	u8 dev_password_bin[WPS_OOB_DEVICE_PASSWORD_LEN];

	wpa_printf(MSG_DEBUG, "WPS:  * OOB Device Password");

	addr[0] = wpabuf_head(wps->dh_pubkey);
	hash_len = wpabuf_len(wps->dh_pubkey);
	sha256_vector(1, addr, &hash_len, pubkey_hash);

	if (os_get_random((u8 *) &wps->oob_dev_pw_id, sizeof(u16)) < 0) {
		wpa_printf(MSG_ERROR, "WPS: device password id "
			   "generation error");
		return -1;
	}
	wps->oob_dev_pw_id |= 0x0010;

	if (os_get_random(dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN) < 0) {
		wpa_printf(MSG_ERROR, "WPS: OOB device password "
			   "generation error");
		return -1;
	}

	wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD);
	wpabuf_put_be16(msg, WPS_OOB_DEVICE_PASSWORD_ATTR_LEN);
	wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
	wpabuf_put_be16(msg, wps->oob_dev_pw_id);
	wpabuf_put_data(msg, dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN);

	wpa_snprintf_hex_uppercase(
		wpabuf_put(wps->oob_conf.dev_password,
			   wpabuf_size(wps->oob_conf.dev_password)),
		wpabuf_size(wps->oob_conf.dev_password),
		dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN);

	return 0;
}
Exemplo n.º 9
0
struct wpabuf *ppdp_build_probe_ie(void)
{
	struct wpabuf *buf = wpabuf_alloc(100);
	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
	wpabuf_put_u8(buf, 4 + PPDP_NONCE_LEN);

	wpabuf_put_be32(buf, PPDP_OUI);
	
	u8 nonce[PPDP_NONCE_LEN];
	os_get_random(nonce, PPDP_NONCE_LEN);
	wpabuf_put_data(buf, nonce, PPDP_NONCE_LEN);
	return buf;
}
Exemplo n.º 10
0
static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv)
{
	struct eap_sim_data *data = priv;
	if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
			   "for NONCE_MT");
		os_free(data);
		return NULL;
	}
	data->num_id_req = 0;
	data->num_notification = 0;
	eap_sim_state(data, CONTINUE);
	return priv;
}
Exemplo n.º 11
0
static struct wpabuf * ikev2_build_sa_init(struct ikev2_initiator_data *data)
{
	struct wpabuf *msg;

	/* build IKE_SA_INIT: HDR, SAi, KEi, Ni */

	if (os_get_random(data->i_spi, IKEV2_SPI_LEN))
		return NULL;
	wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
		    data->i_spi, IKEV2_SPI_LEN);

	data->i_nonce_len = IKEV2_NONCE_MIN_LEN;
	if (os_get_random(data->i_nonce, data->i_nonce_len))
		return NULL;
	wpa_hexdump(MSG_DEBUG, "IKEV2: Ni", data->i_nonce, data->i_nonce_len);

	msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
	if (msg == NULL)
		return NULL;

	ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
	if (ikev2_build_sai(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
	    ikev2_build_kei(data, msg, IKEV2_PAYLOAD_NONCE) ||
	    ikev2_build_ni(data, msg, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
		wpabuf_free(msg);
		return NULL;
	}

	ikev2_update_hdr(msg);

	wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);

	wpabuf_free(data->i_sign_msg);
	data->i_sign_msg = wpabuf_dup(msg);

	return msg;
}
Exemplo n.º 12
0
static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
{
    struct hostapd_data *hapd = eloop_ctx;
    struct sta_info *sta = timeout_ctx;
    unsigned int timeout, sec, usec;
    u8 *trans_id, *nbuf;

    wpa_printf(MSG_DEBUG, "%s: SA Query timer for STA " MACSTR
               " (count=%d)",
               hapd->conf->iface, MAC2STR(sta->addr), sta->sa_query_count);

    if (sta->sa_query_count > 0 &&
            ap_check_sa_query_timeout(hapd, sta))
        return;

    nbuf = os_realloc_array(sta->sa_query_trans_id,
                            sta->sa_query_count + 1,
                            WLAN_SA_QUERY_TR_ID_LEN);
    if (nbuf == NULL)
        return;
    if (sta->sa_query_count == 0) {
        /* Starting a new SA Query procedure */
        os_get_reltime(&sta->sa_query_start);
    }
    trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
    sta->sa_query_trans_id = nbuf;
    sta->sa_query_count++;

    if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) {
        /*
         * We don't really care which ID is used here, so simply
         * hardcode this if the mostly theoretical os_get_random()
         * failure happens.
         */
        trans_id[0] = 0x12;
        trans_id[1] = 0x34;
    }

    timeout = hapd->conf->assoc_sa_query_retry_timeout;
    sec = ((timeout / 1000) * 1024) / 1000;
    usec = (timeout % 1000) * 1024;
    eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);

    hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
                   HOSTAPD_LEVEL_DEBUG,
                   "association SA Query attempt %d", sta->sa_query_count);

    ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
}
Exemplo n.º 13
0
/**
 * wps_generate_pin - Generate a random PIN
 * Returns: Eight digit PIN (i.e., including the checksum digit)
 */
unsigned int wps_generate_pin(void)
{
    unsigned int val;

    /* Generate seven random digits for the PIN */
    if (os_get_random((unsigned char *) &val, sizeof(val)) < 0) {
        struct os_time now;
        os_get_time(&now);
        val = os_random() ^ now.sec ^ now.usec;
    }
    val %= 10000000;

    /* Append checksum digit */
    return val * 10 + wps_pin_checksum(val);
}
Exemplo n.º 14
0
static struct hostapd_channel_data *
dfs_get_valid_channel(struct hostapd_iface *iface,
		      int *secondary_channel,
		      u8 *vht_oper_centr_freq_seg0_idx,
		      u8 *vht_oper_centr_freq_seg1_idx,
		      int skip_radar)
{
	struct hostapd_hw_modes *mode;
	struct hostapd_channel_data *chan = NULL;
	int num_available_chandefs;
	int chan_idx;
	u32 _rand;

	wpa_printf(MSG_DEBUG, "DFS: Selecting random channel");
	*secondary_channel = 0;
	*vht_oper_centr_freq_seg0_idx = 0;
	*vht_oper_centr_freq_seg1_idx = 0;

	if (iface->current_mode == NULL)
		return NULL;

	mode = iface->current_mode;
	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
		return NULL;

	/* Get the count first */
	num_available_chandefs = dfs_find_channel(iface, NULL, 0, skip_radar);
	if (num_available_chandefs == 0)
		return NULL;

	if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
		return NULL;
	chan_idx = _rand % num_available_chandefs;
	dfs_find_channel(iface, &chan, chan_idx, skip_radar);

	/* dfs_find_channel() calculations assume HT40+ */
	if (iface->conf->secondary_channel)
		*secondary_channel = 1;
	else
		*secondary_channel = 0;

	dfs_adjust_vht_center_freq(iface, chan,
				   *secondary_channel,
				   vht_oper_centr_freq_seg0_idx,
				   vht_oper_centr_freq_seg1_idx);

	return chan;
}
static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
				       const char *txtaddr)
{
	u8 addr[ETH_ALEN];
	u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];

	wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);

	if (hwaddr_aton(txtaddr, addr))
		return -1;

	os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
	ieee802_11_send_sa_query_req(hapd, addr, trans_id);

	return 0;
}
Exemplo n.º 16
0
/**
 * Set a series of bytes with a random number. Individual bytes can be 0
 */
EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
{   
#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
#ifdef CONFIG_PLATFORM_ESP8266
	os_get_random(rand_data, num_rand_bytes);
#else
    /* use the Linux default */
    read(rng_fd, rand_data, num_rand_bytes);    /* read from /dev/urandom */
#endif
#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
    /* use Microsoft Crypto Libraries */
    CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
#else   /* nothing else to use, so use a custom RNG */
    /* The method we use when we've got nothing better. Use RC4, time 
       and a couple of random seeds to generate a random sequence */
    RC4_CTX rng_ctx;
    struct timeval tv;
    MD5_CTX rng_digest_ctx;
    uint8_t digest[MD5_SIZE];
    uint64_t *ep;
    int i;

    /* A proper implementation would use counters etc for entropy */
    gettimeofday(&tv, NULL);    
    ep = (uint64_t *)entropy_pool;
    ep[0] ^= ENTROPY_COUNTER1;
    ep[1] ^= ENTROPY_COUNTER2; 

    /* use a digested version of the entropy pool as a key */
    MD5_Init(&rng_digest_ctx);
    MD5_Update(&rng_digest_ctx, entropy_pool, ENTROPY_POOL_SIZE);
    MD5_Final(digest, &rng_digest_ctx);

    /* come up with the random sequence */
    RC4_setup(&rng_ctx, digest, MD5_SIZE); /* use as a key */
    memcpy(rand_data, entropy_pool, num_rand_bytes < ENTROPY_POOL_SIZE ?
				num_rand_bytes : ENTROPY_POOL_SIZE);
    RC4_crypt(&rng_ctx, rand_data, rand_data, num_rand_bytes);

    /* move things along */
    for (i = ENTROPY_POOL_SIZE-1; i >= MD5_SIZE ; i--)
        entropy_pool[i] = entropy_pool[i-MD5_SIZE];

    /* insert the digest at the start of the entropy pool */
    memcpy(entropy_pool, digest, MD5_SIZE);
#endif
}
Exemplo n.º 17
0
static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
{
	u8 *hash;
	const u8 *addr[4];
	size_t len[4];

	if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
		return -1;
	wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
	wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
		    wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);

	if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
			   "E-Hash derivation");
		return -1;
	}

	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
	wpabuf_put_be16(msg, ATTR_E_HASH1);
	wpabuf_put_be16(msg, SHA256_MAC_LEN);
	hash = wpabuf_put(msg, SHA256_MAC_LEN);
	/* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
	addr[0] = wps->snonce;
	len[0] = WPS_SECRET_NONCE_LEN;
	addr[1] = wps->psk1;
	len[1] = WPS_PSK_LEN;
	addr[2] = wpabuf_head(wps->dh_pubkey_e);
	len[2] = wpabuf_len(wps->dh_pubkey_e);
	addr[3] = wpabuf_head(wps->dh_pubkey_r);
	len[3] = wpabuf_len(wps->dh_pubkey_r);
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);

	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
	wpabuf_put_be16(msg, ATTR_E_HASH2);
	wpabuf_put_be16(msg, SHA256_MAC_LEN);
	hash = wpabuf_put(msg, SHA256_MAC_LEN);
	/* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
	addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
	addr[1] = wps->psk2;
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);

	return 0;
}
Exemplo n.º 18
0
struct ctrl_iface_global_priv *
wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
{
	struct ctrl_iface_global_priv *priv;
	struct sockaddr_in addr;

	priv = os_zalloc(sizeof(*priv));
	if (priv == NULL)
		return NULL;
	priv->sock = -1;
	os_get_random(priv->cookie, COOKIE_LEN);

	if (global->params.ctrl_interface == NULL)
		return priv;

	wpa_printf(MSG_DEBUG, "Global control interface '%s'",
		   global->params.ctrl_interface);

	priv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (priv->sock < 0) {
		perror("socket(PF_INET)");
		goto fail;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl((127 << 24) | 1);
	addr.sin_port = htons(WPA_GLOBAL_CTRL_IFACE_PORT);
	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("bind(AF_INET)");
		goto fail;
	}

	eloop_register_read_sock(priv->sock,
				 wpa_supplicant_global_ctrl_iface_receive,
				 global, priv);

	return priv;

fail:
	if (priv->sock >= 0)
		close(priv->sock);
	os_free(priv);
	return NULL;
}
Exemplo n.º 19
0
static struct wpabuf * eap_pax_build_std_1(struct eap_sm *sm,
					   struct eap_pax_data *data, u8 id)
{
	struct wpabuf *req;
	struct eap_pax_hdr *pax;
	u8 *pos;

	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (sending)");

	if (os_get_random(data->rand.r.x, EAP_PAX_RAND_LEN)) {
		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data");
		data->state = FAILURE;
		return NULL;
	}

	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PAX,
			    sizeof(*pax) + 2 + EAP_PAX_RAND_LEN +
			    EAP_PAX_ICV_LEN, EAP_CODE_REQUEST, id);
	if (req == NULL) {
		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory "
			   "request");
		data->state = FAILURE;
		return NULL;
	}

	pax = wpabuf_put(req, sizeof(*pax));
	pax->op_code = EAP_PAX_OP_STD_1;
	pax->flags = 0;
	pax->mac_id = data->mac_id;
	pax->dh_group_id = EAP_PAX_DH_GROUP_NONE;
	pax->public_key_id = EAP_PAX_PUBLIC_KEY_NONE;

	wpabuf_put_be16(req, EAP_PAX_RAND_LEN);
	wpabuf_put_data(req, data->rand.r.x, EAP_PAX_RAND_LEN);
	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: A = X (server rand)",
		    data->rand.r.x, EAP_PAX_RAND_LEN);

	pos = wpabuf_put(req, EAP_PAX_MAC_LEN);
	eap_pax_mac(data->mac_id, (u8 *) "", 0,
		    wpabuf_mhead(req), wpabuf_len(req) - EAP_PAX_ICV_LEN,
		    NULL, 0, NULL, 0, pos);
	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN);

	return req;
}
Exemplo n.º 20
0
static int wpa_ft_pull_pmk_r1(struct wpa_authenticator *wpa_auth,
			      const u8 *s1kh_id, const u8 *r0kh_id,
			      size_t r0kh_id_len, const u8 *pmk_r0_name)
{
	struct ft_remote_r0kh *r0kh;
	struct ft_r0kh_r1kh_pull_frame frame, f;

	r0kh = wpa_auth->conf.r0kh_list;
	while (r0kh) {
		if (r0kh->id_len == r0kh_id_len &&
		    os_memcmp(r0kh->id, r0kh_id, r0kh_id_len) == 0)
			break;
		r0kh = r0kh->next;
	}
	if (r0kh == NULL)
		return -1;

	wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH "
		   "address " MACSTR, MAC2STR(r0kh->addr));

	os_memset(&frame, 0, sizeof(frame));
	frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
	frame.packet_type = FT_PACKET_R0KH_R1KH_PULL;
	frame.data_length = host_to_le16(FT_R0KH_R1KH_PULL_DATA_LEN);
	os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);

	/* aes_wrap() does not support inplace encryption, so use a temporary
	 * buffer for the data. */
	if (os_get_random(f.nonce, sizeof(f.nonce))) {
		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
			   "nonce");
		return -1;
	}
	os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
	os_memcpy(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
	os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);

	if (aes_wrap(r0kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
		     f.nonce, frame.nonce) < 0)
		return -1;

	wpa_ft_rrb_send(wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame));

	return 0;
}
Exemplo n.º 21
0
static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm,
					    struct eap_aka_data *data, u8 id)
{
	struct eap_sim_msg *msg;

	wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Re-authentication");

	if (os_get_random(data->nonce_s, EAP_SIM_NONCE_S_LEN))
		return NULL;
	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S",
			data->nonce_s, EAP_SIM_NONCE_S_LEN);

	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
		eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
						 sm->identity,
						 sm->identity_len,
						 data->nonce_s,
						 data->msk, data->emsk);
	} else {
		eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
				    data->msk, data->emsk);
		eap_sim_derive_keys_reauth(data->counter, sm->identity,
					   sm->identity_len, data->nonce_s,
					   data->mk, data->msk, data->emsk);
	}

	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
			       EAP_AKA_SUBTYPE_REAUTHENTICATION);

	if (eap_aka_build_encr(sm, data, msg, data->counter, data->nonce_s)) {
		eap_sim_msg_free(msg);
		return NULL;
	}

	eap_aka_add_checkcode(data, msg);

	if (sm->eap_sim_aka_result_ind) {
		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
	}

	wpa_printf(MSG_DEBUG, "   AT_MAC");
	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
	return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
}
Exemplo n.º 22
0
static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
{
	char *id, *pos, *end;
	u8 buf[10];

	if (os_get_random(buf, sizeof(buf)))
		return NULL;
	id = os_malloc(sizeof(buf) * 2 + 2);
	if (id == NULL)
		return NULL;

	pos = id;
	end = id + sizeof(buf) * 2 + 2;
	*pos++ = prefix;
	pos += wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf));
	
	return id;
}
static struct wpabuf * wps_build_m1(struct wps_data *wps)
{
    struct wpabuf *msg;
    u16 methods;

    if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
        return NULL;
    wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
            wps->nonce_e, WPS_NONCE_LEN);

    wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
    msg = wpabuf_alloc(1000);
    if (msg == NULL)
        return NULL;

    methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
    if (wps->pbc)
        methods |= WPS_CONFIG_PUSHBUTTON;

    if (wps_build_version(msg) ||
        wps_build_msg_type(msg, WPS_M1) ||
        wps_build_uuid_e(msg, wps->uuid_e) ||
        wps_build_mac_addr(wps, msg) ||
        wps_build_enrollee_nonce(wps, msg) ||
        wps_build_public_key(wps, msg) ||
        wps_build_auth_type_flags(wps, msg) ||
        wps_build_encr_type_flags(wps, msg) ||
        wps_build_conn_type_flags(wps, msg) ||
        wps_build_config_methods(msg, methods) ||
        wps_build_wps_state(wps, msg) ||
        wps_build_device_attrs(&wps->wps->dev, msg) ||
        wps_build_rf_bands(&wps->wps->dev, msg) ||
        wps_build_assoc_state(wps, msg) ||
        wps_build_dev_password_id(msg, wps->dev_pw_id) ||
        wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
        wps_build_os_version(&wps->wps->dev, msg)) {
        wpabuf_free(msg);
        return NULL;
    }

    wps->state = RECV_M2;
    return msg;
}
Exemplo n.º 24
0
struct ctrl_iface_priv *
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
{
	struct ctrl_iface_priv *priv;
	struct sockaddr_in addr;

	priv = os_zalloc(sizeof(*priv));
	if (priv == NULL)
		return NULL;
	priv->wpa_s = wpa_s;
	priv->sock = -1;
	os_get_random(priv->cookie, COOKIE_LEN);

	if (wpa_s->conf->ctrl_interface == NULL)
		return priv;

	priv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (priv->sock < 0) {
		perror("socket(PF_INET)");
		goto fail;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl((127 << 24) | 1);
	addr.sin_port = htons(WPA_CTRL_IFACE_PORT);
	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("bind(AF_INET)");
		goto fail;
	}

	eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
				 wpa_s, priv);
	wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);

	return priv;

fail:
	if (priv->sock >= 0)
		close(priv->sock);
	os_free(priv);
	return NULL;
}
Exemplo n.º 25
0
static void * eap_sim_init(struct eap_sm *sm)
{
	struct eap_sim_data *data;
	struct eap_peer_config *config = eap_get_config(sm);

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;

	if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
			   "for NONCE_MT");
		os_free(data);
		return NULL;
	}

	data->min_num_chal = 2;
	if (config && config->phase1) {
		char *pos = os_strstr(config->phase1, "sim_min_num_chal=");
		if (pos) {
			data->min_num_chal = atoi(pos + 17);
			if (data->min_num_chal < 2 || data->min_num_chal > 3) {
				wpa_printf(MSG_WARNING, "EAP-SIM: Invalid "
					   "sim_min_num_chal configuration "
					   "(%lu, expected 2 or 3)",
					   (unsigned long) data->min_num_chal);
				os_free(data);
				return NULL;
			}
			wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of "
				   "challenges to %lu",
				   (unsigned long) data->min_num_chal);
		}

		data->result_ind = os_strstr(config->phase1, "result_ind=1") !=
			NULL;
	}

	eap_sim_state(data, CONTINUE);

	return data;
}
Exemplo n.º 26
0
static struct wpabuf * eap_mschapv2_build_challenge(
	struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id)
{
	struct wpabuf *req;
	struct eap_mschapv2_hdr *ms;
	char *name = "hostapd"; /* TODO: make this configurable */
	size_t ms_len;

	if (!data->auth_challenge_from_tls &&
	    os_get_random(data->auth_challenge, CHALLENGE_LEN)) {
		wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to get random "
			   "data");
		data->state = FAILURE;
		return NULL;
	}

	ms_len = sizeof(*ms) + 1 + CHALLENGE_LEN + os_strlen(name);
	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
			    EAP_CODE_REQUEST, id);
	if (req == NULL) {
		wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory"
			   " for request");
		data->state = FAILURE;
		return NULL;
	}

	ms = wpabuf_put(req, sizeof(*ms));
	ms->op_code = MSCHAPV2_OP_CHALLENGE;
	ms->mschapv2_id = id;
	WPA_PUT_BE16(ms->ms_length, ms_len);

	wpabuf_put_u8(req, CHALLENGE_LEN);
	if (!data->auth_challenge_from_tls)
		wpabuf_put_data(req, data->auth_challenge, CHALLENGE_LEN);
	else
		wpabuf_put(req, CHALLENGE_LEN);
	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge",
		    data->auth_challenge, CHALLENGE_LEN);
	wpabuf_put_data(req, name, os_strlen(name));

	return req;
}
Exemplo n.º 27
0
/**
 * dh_init - Initialize Diffie-Hellman handshake
 * @dh: Selected Diffie-Hellman group
 * @priv: Pointer for returning Diffie-Hellman private key
 * Returns: Diffie-Hellman public value
 */
struct wpabuf * dh_init(const struct dh_group *dh, struct wpabuf **priv)
{
	struct wpabuf *pv;
	size_t pv_len;

	if (dh == NULL)
		return NULL;

	wpabuf_free(*priv);
	*priv = wpabuf_alloc(dh->prime_len);
	if (*priv == NULL)
		return NULL;

	if (os_get_random(wpabuf_put(*priv, dh->prime_len), dh->prime_len)) {
		wpabuf_free(*priv);
		*priv = NULL;
		return NULL;
	}

	if (os_memcmp(wpabuf_head(*priv), dh->prime, dh->prime_len) > 0) {
		/* Make sure private value is smaller than prime */
		*(wpabuf_mhead_u8(*priv)) = 0;
	}
	wpa_hexdump_buf_key(MSG_DEBUG, "DH: private value", *priv);

	pv_len = dh->prime_len;
	pv = wpabuf_alloc(pv_len);
	if (pv == NULL)
		return NULL;
	if (crypto_mod_exp(dh->generator, dh->generator_len,
			   wpabuf_head(*priv), wpabuf_len(*priv),
			   dh->prime, dh->prime_len, wpabuf_mhead(pv),
			   &pv_len) < 0) {
		wpabuf_free(pv);
		wpa_printf(MSG_INFO, "DH: crypto_mod_exp failed");
		return NULL;
	}
	wpabuf_put(pv, pv_len);
	wpa_hexdump_buf(MSG_DEBUG, "DH: public value", pv);

	return pv;
}
Exemplo n.º 28
0
/**
 * accounting_init: Initialize accounting
 * @hapd: hostapd BSS data
 * Returns: 0 on success, -1 on failure
 */
int accounting_init(struct hostapd_data *hapd)
{
	struct os_time now;

	/* Acct-Session-Id should be unique over reboots. Using a random number
	 * is preferred. If that is not available, take the current time. Mix
	 * in microseconds to make this more likely to be unique. */
	os_get_time(&now);
	if (os_get_random((u8 *) &hapd->acct_session_id_hi,
			  sizeof(hapd->acct_session_id_hi)) < 0)
		hapd->acct_session_id_hi = now.sec;
	hapd->acct_session_id_hi ^= now.usec;

	if (radius_client_register(hapd->radius, RADIUS_ACCT,
				   accounting_receive, hapd))
		return -1;

	accounting_report_state(hapd, 1);

	return 0;
}
Exemplo n.º 29
0
/**
 * wpa_ft_prepare_auth_request - Generate over-the-air auth request
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * Returns: 0 on success, -1 on failure
 */
int wpa_ft_prepare_auth_request(struct wpa_sm *sm)
{
    u8 *ft_ies;
    size_t ft_ies_len;

    /* Generate a new SNonce */
    if (os_get_random(sm->snonce, WPA_NONCE_LEN)) {
        wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce");
        return -1;
    }

    ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
                                NULL, sm->bssid);
    if (ft_ies) {
        wpa_sm_update_ft_ies(sm, sm->mobility_domain,
                             ft_ies, ft_ies_len);
        os_free(ft_ies);
    }

    return 0;
}
Exemplo n.º 30
0
int eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv,
			       u8 attr_encr)
{
	u8 *pos = eap_sim_msg_add(msg, attr_iv, 0, NULL, EAP_SIM_IV_LEN);
	if (pos == NULL)
		return -1;
	msg->iv = (pos - wpabuf_head_u8(msg->buf)) + 4;
	if (os_get_random(wpabuf_mhead_u8(msg->buf) + msg->iv,
			  EAP_SIM_IV_LEN)) {
		msg->iv = 0;
		return -1;
	}

	pos = eap_sim_msg_add(msg, attr_encr, 0, NULL, 0);
	if (pos == NULL) {
		msg->iv = 0;
		return -1;
	}
	msg->encr = pos - wpabuf_head_u8(msg->buf);

	return 0;
}