Add support for the driver which do 4-way handshake

Add the support for the Linux wireless drivers which want to do
4-way handshake and need to know the PSK before the handshake.

Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
This commit is contained in:
Masakazu Mokuno 2008-06-18 11:09:00 +03:00 committed by Jouni Malinen
parent e0f775b2a4
commit 84737a46a4

View file

@ -29,6 +29,7 @@
#include "priv_netlink.h" #include "priv_netlink.h"
#include "driver_wext.h" #include "driver_wext.h"
#include "ieee802_11_defs.h" #include "ieee802_11_defs.h"
#include "wpa_common.h"
#ifdef CONFIG_CLIENT_MLME #ifdef CONFIG_CLIENT_MLME
#include <netpacket/packet.h> #include <netpacket/packet.h>
@ -1677,8 +1678,12 @@ static int wpa_driver_wext_get_range(void *priv)
drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x", if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
drv->capa.key_mgmt, drv->capa.enc); drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x "
"flags 0x%x",
drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
} else { } else {
wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - " wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
"assuming WPA is not supported"); "assuming WPA is not supported");
@ -1699,6 +1704,43 @@ static int wpa_driver_wext_set_wpa(void *priv, int enabled)
} }
static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
const u8 *psk)
{
struct iw_encode_ext *ext;
struct iwreq iwr;
int ret;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
return 0;
if (!psk)
return 0;
os_memset(&iwr, 0, sizeof(iwr));
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
ext = os_zalloc(sizeof(*ext) + PMK_LEN);
if (ext == NULL)
return -1;
iwr.u.encoding.pointer = (caddr_t) ext;
iwr.u.encoding.length = sizeof(*ext) + PMK_LEN;
ext->key_len = PMK_LEN;
os_memcpy(&ext->key, psk, ext->key_len);
ext->alg = IW_ENCODE_ALG_PMK;
ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);
if (ret < 0)
perror("ioctl[SIOCSIWENCODEEXT] PMK");
os_free(ext);
return ret;
}
static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg, static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg,
const u8 *addr, int key_idx, const u8 *addr, int key_idx,
int set_tx, const u8 *seq, int set_tx, const u8 *seq,
@ -1755,6 +1797,9 @@ static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg,
case WPA_ALG_CCMP: case WPA_ALG_CCMP:
ext->alg = IW_ENCODE_ALG_CCMP; ext->alg = IW_ENCODE_ALG_CCMP;
break; break;
case WPA_ALG_PMK:
ext->alg = IW_ENCODE_ALG_PMK;
break;
default: default:
wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d", wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
__FUNCTION__, alg); __FUNCTION__, alg);
@ -2101,7 +2146,9 @@ int wpa_driver_wext_associate(void *priv,
allow_unencrypted_eapol = 0; allow_unencrypted_eapol = 0;
else else
allow_unencrypted_eapol = 1; allow_unencrypted_eapol = 1;
if (wpa_driver_wext_set_psk(drv, params->psk) < 0)
ret = -1;
if (wpa_driver_wext_set_auth_param(drv, if (wpa_driver_wext_set_auth_param(drv,
IW_AUTH_RX_UNENCRYPTED_EAPOL, IW_AUTH_RX_UNENCRYPTED_EAPOL,
allow_unencrypted_eapol) < 0) allow_unencrypted_eapol) < 0)