Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.13-rc5 248 lines 7.0 kB view raw
1/* 2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * 20 * File: wpactl.c 21 * 22 * Purpose: handle wpa supplicant ioctl input/out functions 23 * 24 * Author: Lyndon Chen 25 * 26 * Date: July 28, 2006 27 * 28 * Functions: 29 * 30 * Revision History: 31 * 32 */ 33 34#include "wpactl.h" 35#include "key.h" 36#include "mac.h" 37#include "device.h" 38#include "wmgr.h" 39#include "iocmd.h" 40#include "iowpa.h" 41#include "control.h" 42#include "rndis.h" 43#include "rf.h" 44 45static int msglevel = MSG_LEVEL_INFO; 46 47/* 48 * Description: 49 * Set WPA algorithm & keys 50 * 51 * Parameters: 52 * In: 53 * pDevice - 54 * param - 55 * Out: 56 * 57 * Return Value: 58 * 59 */ 60int wpa_set_keys(struct vnt_private *pDevice, void *ctx) 61{ 62 struct viawget_wpa_param *param = ctx; 63 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; 64 u32 dwKeyIndex = 0; 65 u8 abyKey[MAX_KEY_LEN]; 66 u8 abySeq[MAX_KEY_LEN]; 67 u64 KeyRSC; 68 u8 byKeyDecMode = KEY_CTL_WEP; 69 int ret = 0; 70 int uu; 71 int ii; 72 73 if (param->u.wpa_key.alg_name > WPA_ALG_CCMP) 74 return -EINVAL; 75 76 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", 77 param->u.wpa_key.alg_name); 78 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { 79 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 80 pDevice->bEncryptionEnable = false; 81 pDevice->byKeyIndex = 0; 82 pDevice->bTransmitKey = false; 83 for (uu=0; uu<MAX_KEY_TABLE; uu++) { 84 MACvDisableKeyEntry(pDevice, uu); 85 } 86 return ret; 87 } 88 89 if (param->u.wpa_key.key && param->u.wpa_key.key_len > sizeof(abyKey)) 90 return -EINVAL; 91 92 memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); 93 94 dwKeyIndex = (u32)(param->u.wpa_key.key_index); 95 96 if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { 97 if (dwKeyIndex > 3) { 98 return -EINVAL; 99 } else { 100 if (param->u.wpa_key.set_tx) { 101 pDevice->byKeyIndex = (u8)dwKeyIndex; 102 pDevice->bTransmitKey = true; 103 dwKeyIndex |= (1 << 31); 104 } 105 KeybSetDefaultKey( pDevice, 106 &(pDevice->sKey), 107 dwKeyIndex & ~(BIT30 | USE_KEYRSC), 108 param->u.wpa_key.key_len, 109 NULL, 110 abyKey, 111 KEY_CTL_WEP 112 ); 113 114 } 115 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 116 pDevice->bEncryptionEnable = true; 117 return ret; 118 } 119 120 if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq)) 121 return -EINVAL; 122 123 memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); 124 125 if (param->u.wpa_key.seq_len > 0) { 126 for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) { 127 if (ii < 4) 128 KeyRSC |= (abySeq[ii] << (ii * 8)); 129 else 130 KeyRSC |= (abySeq[ii] << ((ii-4) * 8)); 131 } 132 dwKeyIndex |= 1 << 29; 133 } 134 135 if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { 136 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n"); 137 return -EINVAL; 138 } 139 140 if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) { 141 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 142 } 143 144 if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) { 145 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 146 } 147 148 if (param->u.wpa_key.set_tx) 149 dwKeyIndex |= (1 << 31); 150 151 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) 152 byKeyDecMode = KEY_CTL_CCMP; 153 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) 154 byKeyDecMode = KEY_CTL_TKIP; 155 else 156 byKeyDecMode = KEY_CTL_WEP; 157 158 // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled 159 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { 160 if (param->u.wpa_key.key_len == MAX_KEY_LEN) 161 byKeyDecMode = KEY_CTL_TKIP; 162 else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) 163 byKeyDecMode = KEY_CTL_WEP; 164 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) 165 byKeyDecMode = KEY_CTL_WEP; 166 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { 167 if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) 168 byKeyDecMode = KEY_CTL_WEP; 169 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) 170 byKeyDecMode = KEY_CTL_WEP; 171 } 172 173 // Check TKIP key length 174 if ((byKeyDecMode == KEY_CTL_TKIP) && 175 (param->u.wpa_key.key_len != MAX_KEY_LEN)) { 176 // TKIP Key must be 256 bits 177 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - TKIP Key must be 256 bits!\n"); 178 return -EINVAL; 179 } 180 // Check AES key length 181 if ((byKeyDecMode == KEY_CTL_CCMP) && 182 (param->u.wpa_key.key_len != AES_KEY_LEN)) { 183 // AES Key must be 128 bits 184 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n"); 185 return -EINVAL; 186 } 187 188 if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) { 189 /* if broadcast, set the key as every key entry's group key */ 190 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); 191 192 if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex, 193 param->u.wpa_key.key_len, 194 &KeyRSC, 195 (u8 *)abyKey, 196 byKeyDecMode 197 ) == true) && 198 (KeybSetDefaultKey(pDevice, 199 &(pDevice->sKey), 200 dwKeyIndex, 201 param->u.wpa_key.key_len, 202 &KeyRSC, 203 (u8 *)abyKey, 204 byKeyDecMode 205 ) == true) ) { 206 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); 207 } else { 208 return -EINVAL; 209 } 210 } else { 211 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n"); 212 // BSSID not 0xffffffffffff 213 // Pairwise Key can't be WEP 214 if (byKeyDecMode == KEY_CTL_WEP) { 215 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n"); 216 return -EINVAL; 217 } 218 dwKeyIndex |= (1 << 30); // set pairwise key 219 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { 220 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n")); 221 return -EINVAL; 222 } 223 if (KeybSetKey(pDevice, &(pDevice->sKey), &param->addr[0], 224 dwKeyIndex, param->u.wpa_key.key_len, 225 &KeyRSC, (u8 *)abyKey, byKeyDecMode 226 ) == true) { 227 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); 228 } else { 229 // Key Table Full 230 if (ether_addr_equal(param->addr, pDevice->abyBSSID)) { 231 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n")); 232 return -EINVAL; 233 } else { 234 // Save Key and configure just before associate/reassociate to BSSID 235 // we do not implement now 236 return -EINVAL; 237 } 238 } 239 } // BSSID not 0xffffffffffff 240 if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { 241 pDevice->byKeyIndex = (u8)param->u.wpa_key.key_index; 242 pDevice->bTransmitKey = true; 243 } 244 pDevice->bEncryptionEnable = true; 245 246 return ret; 247} 248