2009-06-13 11:38:31 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* File: wpactl.c
|
|
|
|
*
|
|
|
|
* Purpose: handle wpa supplicant ioctl input/out functions
|
|
|
|
*
|
|
|
|
* Author: Lyndon Chen
|
|
|
|
*
|
|
|
|
* Date: July 28, 2006
|
|
|
|
*
|
|
|
|
* Functions:
|
|
|
|
*
|
|
|
|
* Revision History:
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "wpactl.h"
|
|
|
|
#include "key.h"
|
|
|
|
#include "mac.h"
|
|
|
|
#include "device.h"
|
|
|
|
#include "wmgr.h"
|
|
|
|
#include "iocmd.h"
|
|
|
|
#include "iowpa.h"
|
|
|
|
#include "control.h"
|
|
|
|
#include "rndis.h"
|
|
|
|
#include "rf.h"
|
|
|
|
|
2012-01-16 20:28:23 +00:00
|
|
|
static int msglevel = MSG_LEVEL_INFO;
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Description:
|
|
|
|
* Set WPA algorithm & keys
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* In:
|
|
|
|
* pDevice -
|
|
|
|
* param -
|
|
|
|
* Out:
|
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
*
|
|
|
|
*/
|
2012-12-10 22:14:36 +00:00
|
|
|
int wpa_set_keys(struct vnt_private *pDevice, void *ctx)
|
2009-06-13 11:38:31 +00:00
|
|
|
{
|
2012-01-16 20:28:23 +00:00
|
|
|
struct viawget_wpa_param *param = ctx;
|
2012-12-10 22:14:36 +00:00
|
|
|
struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
|
2013-02-26 01:32:53 +00:00
|
|
|
u32 dwKeyIndex = 0;
|
2013-02-26 01:32:51 +00:00
|
|
|
u8 abyKey[MAX_KEY_LEN];
|
|
|
|
u8 abySeq[MAX_KEY_LEN];
|
2012-11-28 21:11:02 +00:00
|
|
|
u64 KeyRSC;
|
2013-02-26 01:32:51 +00:00
|
|
|
u8 byKeyDecMode = KEY_CTL_WEP;
|
2009-06-13 11:38:31 +00:00
|
|
|
int ret = 0;
|
2012-01-16 20:28:23 +00:00
|
|
|
int uu;
|
|
|
|
int ii;
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2012-01-16 20:28:23 +00:00
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n",
|
|
|
|
param->u.wpa_key.alg_name);
|
2009-06-13 11:38:31 +00:00
|
|
|
if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
|
2012-01-16 20:28:23 +00:00
|
|
|
pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
|
2013-02-13 01:36:29 +00:00
|
|
|
pDevice->bEncryptionEnable = false;
|
2012-01-16 20:28:23 +00:00
|
|
|
pDevice->byKeyIndex = 0;
|
2013-02-13 01:36:29 +00:00
|
|
|
pDevice->bTransmitKey = false;
|
2012-01-16 20:28:23 +00:00
|
|
|
for (uu=0; uu<MAX_KEY_TABLE; uu++) {
|
|
|
|
MACvDisableKeyEntry(pDevice, uu);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2009-06-13 11:38:31 +00:00
|
|
|
|
2014-01-03 20:59:41 +00:00
|
|
|
if (param->u.wpa_key.key_len > sizeof(abyKey))
|
2011-09-29 06:13:18 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2012-11-24 14:56:09 +00:00
|
|
|
memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
|
2009-06-13 11:38:31 +00:00
|
|
|
|
2013-02-26 01:32:53 +00:00
|
|
|
dwKeyIndex = (u32)(param->u.wpa_key.key_index);
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
|
2012-01-16 20:28:23 +00:00
|
|
|
if (dwKeyIndex > 3) {
|
|
|
|
return -EINVAL;
|
|
|
|
} else {
|
|
|
|
if (param->u.wpa_key.set_tx) {
|
2013-02-26 01:32:51 +00:00
|
|
|
pDevice->byKeyIndex = (u8)dwKeyIndex;
|
2013-02-13 01:36:30 +00:00
|
|
|
pDevice->bTransmitKey = true;
|
2012-01-16 20:28:23 +00:00
|
|
|
dwKeyIndex |= (1 << 31);
|
|
|
|
}
|
|
|
|
KeybSetDefaultKey( pDevice,
|
|
|
|
&(pDevice->sKey),
|
|
|
|
dwKeyIndex & ~(BIT30 | USE_KEYRSC),
|
|
|
|
param->u.wpa_key.key_len,
|
|
|
|
NULL,
|
|
|
|
abyKey,
|
|
|
|
KEY_CTL_WEP
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
|
2013-02-13 01:36:30 +00:00
|
|
|
pDevice->bEncryptionEnable = true;
|
2012-01-16 20:28:23 +00:00
|
|
|
return ret;
|
2009-06-13 11:38:31 +00:00
|
|
|
}
|
|
|
|
|
2011-09-29 06:13:18 +00:00
|
|
|
if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2012-11-24 14:56:09 +00:00
|
|
|
memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
if (param->u.wpa_key.seq_len > 0) {
|
|
|
|
for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
|
2012-01-16 20:28:23 +00:00
|
|
|
if (ii < 4)
|
2012-11-28 21:11:02 +00:00
|
|
|
KeyRSC |= (abySeq[ii] << (ii * 8));
|
2012-01-16 20:28:23 +00:00
|
|
|
else
|
2012-11-28 21:11:02 +00:00
|
|
|
KeyRSC |= (abySeq[ii] << ((ii-4) * 8));
|
2009-06-13 11:38:31 +00:00
|
|
|
}
|
|
|
|
dwKeyIndex |= 1 << 29;
|
|
|
|
}
|
|
|
|
|
2012-01-16 20:28:23 +00:00
|
|
|
if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
|
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
|
2012-01-16 20:28:23 +00:00
|
|
|
pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
|
|
|
|
}
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
|
2012-01-16 20:28:23 +00:00
|
|
|
pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
|
|
|
|
}
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
if (param->u.wpa_key.set_tx)
|
|
|
|
dwKeyIndex |= (1 << 31);
|
|
|
|
|
2012-01-16 20:28:23 +00:00
|
|
|
if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
|
|
|
|
byKeyDecMode = KEY_CTL_CCMP;
|
|
|
|
else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
|
|
|
|
byKeyDecMode = KEY_CTL_TKIP;
|
|
|
|
else
|
|
|
|
byKeyDecMode = KEY_CTL_WEP;
|
|
|
|
|
|
|
|
// Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
|
|
|
|
if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
|
|
|
|
if (param->u.wpa_key.key_len == MAX_KEY_LEN)
|
|
|
|
byKeyDecMode = KEY_CTL_TKIP;
|
|
|
|
else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
|
|
|
|
byKeyDecMode = KEY_CTL_WEP;
|
|
|
|
else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
|
|
|
|
byKeyDecMode = KEY_CTL_WEP;
|
|
|
|
} else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
|
|
|
|
if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
|
|
|
|
byKeyDecMode = KEY_CTL_WEP;
|
|
|
|
else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
|
|
|
|
byKeyDecMode = KEY_CTL_WEP;
|
|
|
|
}
|
2009-06-13 11:38:31 +00:00
|
|
|
|
2012-01-16 20:28:23 +00:00
|
|
|
// Check TKIP key length
|
|
|
|
if ((byKeyDecMode == KEY_CTL_TKIP) &&
|
|
|
|
(param->u.wpa_key.key_len != MAX_KEY_LEN)) {
|
|
|
|
// TKIP Key must be 256 bits
|
2012-08-26 15:16:43 +00:00
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - TKIP Key must be 256 bits!\n");
|
2012-01-16 20:28:23 +00:00
|
|
|
return -EINVAL;
|
2009-06-13 11:38:31 +00:00
|
|
|
}
|
2012-01-16 20:28:23 +00:00
|
|
|
// Check AES key length
|
|
|
|
if ((byKeyDecMode == KEY_CTL_CCMP) &&
|
|
|
|
(param->u.wpa_key.key_len != AES_KEY_LEN)) {
|
|
|
|
// AES Key must be 128 bits
|
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2009-06-13 11:38:31 +00:00
|
|
|
|
2012-01-16 20:28:23 +00:00
|
|
|
if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) {
|
|
|
|
/* if broadcast, set the key as every key entry's group key */
|
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
|
|
|
|
|
|
|
|
if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex,
|
|
|
|
param->u.wpa_key.key_len,
|
2012-11-28 21:11:02 +00:00
|
|
|
&KeyRSC,
|
2013-02-26 01:32:51 +00:00
|
|
|
(u8 *)abyKey,
|
2012-01-16 20:28:23 +00:00
|
|
|
byKeyDecMode
|
2013-02-13 01:36:30 +00:00
|
|
|
) == true) &&
|
2012-01-16 20:28:23 +00:00
|
|
|
(KeybSetDefaultKey(pDevice,
|
|
|
|
&(pDevice->sKey),
|
|
|
|
dwKeyIndex,
|
|
|
|
param->u.wpa_key.key_len,
|
2012-11-28 21:11:02 +00:00
|
|
|
&KeyRSC,
|
2013-02-26 01:32:51 +00:00
|
|
|
(u8 *)abyKey,
|
2012-01-16 20:28:23 +00:00
|
|
|
byKeyDecMode
|
2013-02-13 01:36:30 +00:00
|
|
|
) == true) ) {
|
2012-01-16 20:28:23 +00:00
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
|
|
|
|
} else {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
|
|
|
|
// BSSID not 0xffffffffffff
|
|
|
|
// Pairwise Key can't be WEP
|
|
|
|
if (byKeyDecMode == KEY_CTL_WEP) {
|
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
dwKeyIndex |= (1 << 30); // set pairwise key
|
|
|
|
if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
|
|
|
|
//DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (KeybSetKey(pDevice, &(pDevice->sKey), ¶m->addr[0],
|
|
|
|
dwKeyIndex, param->u.wpa_key.key_len,
|
2013-02-26 01:32:51 +00:00
|
|
|
&KeyRSC, (u8 *)abyKey, byKeyDecMode
|
2013-02-13 01:36:30 +00:00
|
|
|
) == true) {
|
2012-01-16 20:28:23 +00:00
|
|
|
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
|
|
|
|
} else {
|
|
|
|
// Key Table Full
|
Staging: Convert uses of compare_ether_addr to ether_addr_equal
Preliminary to removing compare_ether_addr altogether:
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Additionally:
Used is_zero_ether_addr, removed now unused variable
Converted uses of &foo[0] to foo
Done via cocci script: (and a little typing)
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-09-01 19:15:47 +00:00
|
|
|
if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
|
2012-01-16 20:28:23 +00:00
|
|
|
//DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
|
|
|
|
return -EINVAL;
|
|
|
|
} else {
|
|
|
|
// Save Key and configure just before associate/reassociate to BSSID
|
|
|
|
// we do not implement now
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // BSSID not 0xffffffffffff
|
|
|
|
if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
|
2013-02-26 01:32:51 +00:00
|
|
|
pDevice->byKeyIndex = (u8)param->u.wpa_key.key_index;
|
2013-02-13 01:36:30 +00:00
|
|
|
pDevice->bTransmitKey = true;
|
2012-01-16 20:28:23 +00:00
|
|
|
}
|
2013-02-13 01:36:30 +00:00
|
|
|
pDevice->bEncryptionEnable = true;
|
2009-06-13 11:38:31 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|