Merge branch 'pm-cpufreq'
[deliverable/linux.git] / drivers / staging / vt6656 / wpactl.c
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 "usbpipe.h"
42 #include "rf.h"
43
44 static int msglevel = MSG_LEVEL_INFO;
45
46 /*
47 * Description:
48 * Set WPA algorithm & keys
49 *
50 * Parameters:
51 * In:
52 * pDevice -
53 * param -
54 * Out:
55 *
56 * Return Value:
57 *
58 */
59 int wpa_set_keys(struct vnt_private *pDevice, void *ctx)
60 {
61 struct viawget_wpa_param *param = ctx;
62 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
63 u32 dwKeyIndex = 0;
64 u8 abyKey[MAX_KEY_LEN];
65 u8 abySeq[MAX_KEY_LEN];
66 u64 KeyRSC;
67 u8 byKeyDecMode = KEY_CTL_WEP;
68 int ret = 0;
69 u8 uu;
70 int ii;
71
72 if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
73 return -EINVAL;
74
75 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n",
76 param->u.wpa_key.alg_name);
77 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
78 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
79 pDevice->bEncryptionEnable = false;
80 pDevice->byKeyIndex = 0;
81 pDevice->bTransmitKey = false;
82 for (uu=0; uu<MAX_KEY_TABLE; uu++) {
83 MACvDisableKeyEntry(pDevice, uu);
84 }
85 return ret;
86 }
87
88 if (param->u.wpa_key.key_len > sizeof(abyKey))
89 return -EINVAL;
90
91 memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
92
93 dwKeyIndex = (u32)(param->u.wpa_key.key_index);
94
95 if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
96 if (dwKeyIndex > 3) {
97 return -EINVAL;
98 } else {
99 if (param->u.wpa_key.set_tx) {
100 pDevice->byKeyIndex = (u8)dwKeyIndex;
101 pDevice->bTransmitKey = true;
102 dwKeyIndex |= (1 << 31);
103 }
104 KeybSetDefaultKey( pDevice,
105 &(pDevice->sKey),
106 dwKeyIndex & ~(BIT30 | USE_KEYRSC),
107 param->u.wpa_key.key_len,
108 NULL,
109 abyKey,
110 KEY_CTL_WEP
111 );
112
113 }
114 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
115 pDevice->bEncryptionEnable = true;
116 return ret;
117 }
118
119 if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq))
120 return -EINVAL;
121
122 memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
123
124 if (param->u.wpa_key.seq_len > 0) {
125 for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
126 if (ii < 4)
127 KeyRSC |= (abySeq[ii] << (ii * 8));
128 else
129 KeyRSC |= (abySeq[ii] << ((ii-4) * 8));
130 }
131 dwKeyIndex |= 1 << 29;
132 }
133
134 if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
135 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n");
136 return -EINVAL;
137 }
138
139 if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
140 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
141 }
142
143 if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
144 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
145 }
146
147 if (param->u.wpa_key.set_tx)
148 dwKeyIndex |= (1 << 31);
149
150 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
151 byKeyDecMode = KEY_CTL_CCMP;
152 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
153 byKeyDecMode = KEY_CTL_TKIP;
154 else
155 byKeyDecMode = KEY_CTL_WEP;
156
157 // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
158 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
159 if (param->u.wpa_key.key_len == MAX_KEY_LEN)
160 byKeyDecMode = KEY_CTL_TKIP;
161 else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
162 byKeyDecMode = KEY_CTL_WEP;
163 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
164 byKeyDecMode = KEY_CTL_WEP;
165 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
166 if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
167 byKeyDecMode = KEY_CTL_WEP;
168 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
169 byKeyDecMode = KEY_CTL_WEP;
170 }
171
172 // Check TKIP key length
173 if ((byKeyDecMode == KEY_CTL_TKIP) &&
174 (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
175 // TKIP Key must be 256 bits
176 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - TKIP Key must be 256 bits!\n");
177 return -EINVAL;
178 }
179 // Check AES key length
180 if ((byKeyDecMode == KEY_CTL_CCMP) &&
181 (param->u.wpa_key.key_len != AES_KEY_LEN)) {
182 // AES Key must be 128 bits
183 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
184 return -EINVAL;
185 }
186
187 if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
188 /* if broadcast, set the key as every key entry's group key */
189 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
190
191 if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex,
192 param->u.wpa_key.key_len,
193 &KeyRSC,
194 (u8 *)abyKey,
195 byKeyDecMode
196 ) == true) &&
197 (KeybSetDefaultKey(pDevice,
198 &(pDevice->sKey),
199 dwKeyIndex,
200 param->u.wpa_key.key_len,
201 &KeyRSC,
202 (u8 *)abyKey,
203 byKeyDecMode
204 ) == true) ) {
205 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
206 } else {
207 return -EINVAL;
208 }
209 } else {
210 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
211 // BSSID not 0xffffffffffff
212 // Pairwise Key can't be WEP
213 if (byKeyDecMode == KEY_CTL_WEP) {
214 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
215 return -EINVAL;
216 }
217 dwKeyIndex |= (1 << 30); // set pairwise key
218 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
219 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
220 return -EINVAL;
221 }
222 if (KeybSetKey(pDevice, &(pDevice->sKey), &param->addr[0],
223 dwKeyIndex, param->u.wpa_key.key_len,
224 &KeyRSC, (u8 *)abyKey, byKeyDecMode
225 ) == true) {
226 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
227 } else {
228 // Key Table Full
229 if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
230 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
231 return -EINVAL;
232 } else {
233 // Save Key and configure just before associate/reassociate to BSSID
234 // we do not implement now
235 return -EINVAL;
236 }
237 }
238 } // BSSID not 0xffffffffffff
239 if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
240 pDevice->byKeyIndex = (u8)param->u.wpa_key.key_index;
241 pDevice->bTransmitKey = true;
242 }
243 pDevice->bEncryptionEnable = true;
244
245 return ret;
246 }
247
This page took 0.035752 seconds and 5 git commands to generate.