Problem setting keys with ndiswrapper after authentication?

Jouni Malinen jkmaline at cc.hut.fi
Sat Nov 27 23:55:36 EST 2004


ndiswrapper-general cc'ed; please, apply the attached patch to
ndiswrapper CVS.


On Fri, Nov 26, 2004 at 10:16:21AM +0100, Romano Giannetti wrote:

> Well. I have ndiswrapper installed (last version, 0.12rc3), with a realtek
> ndis5 driver version 173. 

> First of all, I set essid manually (no way to obtain this in scan mode, so I
> disabled it) and "up" the interface 

OK, although support for scanning for specific SSID with ndiswrapper
when using wpa_supplicant should be added at some point.. Unfortunately,
this seems to be somewhat complex task with NDIS and multiple possible
authentication modes.

> [root at rukbat wifi]# iwconfig wlan0 mode managed essid upco_wlan key 0 open
> [root at rukbat wifi]# iwconfig wlan0 && ifconfig wlan0
> wlan0     IEEE 802.11b  ESSID:"upco_wlan"  
>           Mode:Managed  Frequency:2.427GHz  Access Point: 00:11:5C:77:82:40  

OK, so association works when done manually. I tested this with
wpa_supplicant doing scanning and it actually failed. ndiswrapper ended
up configuring the driver to reject APs that were using encryption.. I
fixed wpa_supplicant to set cipher suite to WEP-104 when using IEEE
802.1X (available in the current Host AP CVS snapshot) and this seemed
to have fixed the association part.

> EAPOL: Decrypted(RC4) key - hexdump(len=13): 13 ab d7 39 ef 08 e0 bc 63 a7 d1 a8 b9
> EAPOL: Setting dynamic WEP key: broadcast keyidx 0 len 13
> key data: key_idx=0 set_tx=0
> trying to set key...
> result of iw_set_ext, RESULT -1
> 
> ***** HERE is the fault!!!

Indeed. There's a bug in the way the current ndiswrapper handles WEP
keys from wpa_supplicant. wpa_set_key() tries to convert the WPA key set
structure into normal wireless extensions WEP configuration, but does it
incorrectly. The key is already in binary form, so no hex2bin conversion
is needed. In addition, key index needs +1 to match the wireless
extensions.

The attached patch to the current ndiswrapper CVS version fixes these
problems. With this patch and the current CVS version of wpa_supplicant,
I was able to complete IEEE 802.1X (non-WPA) authentication and use the
encrypted data connection (both unicast and multicast worked).

-- 
Jouni Malinen                                            PGP id EFC895FA
-------------- next part --------------
Index: driver/iw_ndis.c
===================================================================
RCS file: /cvsroot/ndiswrapper/ndiswrapper/driver/iw_ndis.c,v
retrieving revision 1.83
diff -u -p -r1.83 iw_ndis.c
--- driver/iw_ndis.c	22 Nov 2004 06:02:50 -0000	1.83
+++ driver/iw_ndis.c	28 Nov 2004 04:34:03 -0000
@@ -1276,48 +1276,6 @@ static int wpa_set_wpa(struct net_device
 	}
 }
 
-static int char_to_hex(int c)
-{
-	if (c >= '0' && c <= '9')
-		return c - '0';
-	if (c >= 'a' && c <= 'f')
-		return c - 'a' + 10;
-	return -1;
-}
-
-/* convert key in string to hex digits - 2 chars make up one digit */
-static int key_str_to_hex(const char *str, unsigned char *key, int str_len)
-{
-	int i, key_len;
-
-	if (!memcmp(str, "s:", 2))
-	{
-		key_len = str_len-2;
-		if (key_len >= IW_ENCODING_TOKEN_MAX)
-			TRACEEXIT(return -1);
-		memcpy(key, str+2, key_len);
-	}
-	else
-		for (i = key_len = 0; i < str_len-1; i += 2, key_len++)
-		{
-			int c1, c2;
-
-			if (key_len >= IW_ENCODING_TOKEN_MAX)
-				TRACEEXIT(return -1);
-			/* sscanf(str, "%1X", &ch) doesn't seem to work */
-			c1 = char_to_hex(tolower(str[i]));
-			c2 = char_to_hex(tolower(str[i+1]));
-			if (c1 < 0 || c2 < 0)
-				TRACEEXIT(return -1);
-			key[key_len] = c1 << 4 | c2;
-		}
-	DBGTRACE("key length = %d", key_len);
-	if (key_len == 5 || key_len == 13)
-		TRACEEXIT(return key_len);
-	else
-		TRACEEXIT(return -1);
-}
-
 static int remove_key(struct ndis_handle *handle, int key_index,
 		      mac_address bssid)
 {
@@ -1392,25 +1350,20 @@ static int wpa_set_key(struct net_device
 	if (wpa_key.alg == WPA_ALG_WEP)
 	{
 		union iwreq_data encr_req;
-		unsigned char key[IW_ENCODING_TOKEN_MAX];
-		int i;
 
 		if (test_bit(CAPA_ENCR_NONE, &handle->capa))
 			TRACEEXIT(return -EINVAL);
 
 		memset(&encr_req, 0, sizeof(encr_req));
-		encr_req.data.flags = wpa_key.key_index;
+		encr_req.encoding.flags = wpa_key.key_index + 1;
 		/* auth mode is set with set_auth_alg */
 		if (handle->auth_mode == AUTHMODE_OPEN)
-			encr_req.data.flags |= IW_ENCODE_OPEN;
+			encr_req.encoding.flags |= IW_ENCODE_OPEN;
 		else
-			encr_req.data.flags |= IW_ENCODE_RESTRICTED;
-		i = key_str_to_hex(usrkey, key, wpa_key.key_len);
-		if (i < 0)
-			TRACEEXIT(return -EINVAL);
-		encr_req.data.length = i;
-		encr_req.data.pointer = key;
-		if (iw_set_encr(dev, info, &encr_req, key))
+			encr_req.encoding.flags |= IW_ENCODE_RESTRICTED;
+		encr_req.encoding.length = wpa_key.key_len;
+		encr_req.encoding.pointer = wpa_key.key;
+		if (iw_set_encr(dev, info, &encr_req, usrkey))
 			TRACEEXIT(return -EINVAL);
 		else
 			TRACEEXIT(return 0);


More information about the HostAP mailing list