1/*
2 * admCtrlWpa2.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 *  * Neither the name Texas Instruments nor the names of its
18 *    contributors may be used to endorse or promote products derived
19 *    from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file admCtrlWpa2.c
35 *  \brief WPA2 Admission control methods
36 *
37 *  \see admCtrl.h
38 */
39
40/****************************************************************************
41 *                                                                          *
42 *   MODULE:  Admission Control                                             *
43 *   PURPOSE: Admission Control Module API                                  *
44 *                                                                          *
45 ****************************************************************************/
46
47#define __FILE_ID__  FILE_ID_20
48#include "osApi.h"
49#include "timer.h"
50#include "paramOut.h"
51#include "mlmeApi.h"
52#include "802_11Defs.h"
53#include "DataCtrl_Api.h"
54#include "report.h"
55#include "rsn.h"
56#include "admCtrl.h"
57#include "admCtrlWpa2.h"
58#include "osDot11.h"
59#include "siteMgrApi.h"
60#include "smeApi.h"
61#include "EvHandler.h"
62#include "admCtrl.h"
63#ifdef XCC_MODULE_INCLUDED
64#include "admCtrlWpa.h"
65#include "admCtrlXCC.h"
66#include "XCCMngr.h"
67#endif
68#include "TWDriver.h"
69
70
71/* Constants */
72#define MAX_NETWORK_MODE 2
73#define MAX_WPA2_CIPHER_SUITE 6
74
75#define PMKID_CAND_LIST_MEMBUFF_SIZE  (2*sizeof(TI_UINT32) + (sizeof(OS_802_11_PMKID_CANDIDATE) * PMKID_MAX_NUMBER))
76#define PMKID_MIN_BUFFER_SIZE    2*sizeof(TI_UINT32) + MAC_ADDR_LEN + PMKID_VALUE_SIZE
77
78#define TI_WLAN_COPY_UINT16_UNALIGNED(addr, val) {\
79    *((TI_UINT8 *) &(addr))   = (TI_UINT8)(val & 0x00FF); \
80    *((TI_UINT8 *) &(addr) + 1)   = (TI_UINT8)((val & 0xFF00) >> 8);}
81
82/* Enumerations */
83
84/* Typedefs */
85
86/* Structures */
87
88/* External data definitions */
89
90/* Local functions definitions */
91
92/* Global variables */
93static TI_UINT8 wpa2IeOuiIe[3] = { 0x00, 0x0f, 0xac};
94
95static TI_BOOL broadcastCipherSuiteValidity[MAX_NETWORK_MODE][MAX_WPA2_CIPHER_SUITE]=
96{
97    /* RSN_IBSS */  {
98/* NONE       */    TI_FALSE,
99/* WEP40      */    TI_FALSE,
100/* TKIP       */    TI_TRUE,
101/* AES_WRAP   */    TI_FALSE,
102/* AES_CCMP   */    TI_TRUE,
103/* WEP104     */    TI_FALSE},
104
105    /* RSN_INFRASTRUCTURE */  {
106/* NONE       */    TI_FALSE,
107/* WEP        */    TI_TRUE,
108/* TKIP       */    TI_TRUE,
109/* AES_WRAP   */    TI_FALSE,
110/* AES_CCMP   */    TI_TRUE,
111/* WEP104     */    TI_TRUE}
112};
113
114/** WPA2 admission table. Used to verify admission parameters to an AP */
115/* table parameters:
116    Max unicast cipher in the IE
117    Max broadcast cipher in the IE
118    Encryption status
119*/
120typedef struct
121{
122    TI_STATUS        status;
123    ECipherSuite     unicast;
124    ECipherSuite     broadcast;
125    TI_UINT8            evaluation;
126} admCtrlWpa2_validity_t;
127
128static admCtrlWpa2_validity_t    admCtrlWpa2_validityTable[MAX_WPA2_CIPHER_SUITE][MAX_WPA2_CIPHER_SUITE][MAX_WPA2_CIPHER_SUITE] =
129{
130/* AP unicast NONE */ {
131        /* AP multicast NONE */ {
132            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
133            /* STA WEP40 */ { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
134            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
135            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
136            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
137            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
138        /* AP multicast WEP40 */ {
139            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
140            /* STA WEP40 */ { TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_WEP ,1},
141            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
142            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
143            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
144            /* STA WEP104 */{ TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_WEP104 ,1}},
145        /* AP multicast TKIP */ {
146            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
147            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
148            /* STA TKIP */  { TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_TKIP ,2},
149            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
150            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
151            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
152        /* AP multicast WRAP */ {
153            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
154            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
155            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
156            /* STA WRAP */  { TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_AES_WRAP ,3},
157            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
158            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
159        /* AP multicast CCMP */ {
160            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
161            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
162            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
163            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
164            /* STA CCMP */  { TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_AES_CCMP ,3},
165            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
166        /* AP multicast WEP104 */ {
167            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
168            /* STA WEP40 */ { TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_WEP ,1},
169            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
170            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
171            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
172            /* STA WEP104 */{ TI_OK,  TWD_CIPHER_NONE, TWD_CIPHER_WEP104 ,1}}},
173/* AP unicast WEP */  {
174        /* AP multicast NONE */ {
175            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
176            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
177            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
178            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
179            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
180            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
181        /* AP multicast WEP */ {
182            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
183            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
184            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
185            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
186            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
187            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
188        /* AP multicast TKIP */ {
189            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
190            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
191            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
192            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
193            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
194            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
195        /* AP multicast WRAP */ {
196            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
197            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
198            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
199            /* STA WRAP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
200            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
201            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
202        /* AP multicast CCMP */ {
203            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
204            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
205            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
206            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
207            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
208            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
209        /* AP multicast WEP104 */ {
210            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
211            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
212            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
213            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
214            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
215            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}}},
216/* AP unicast TKIP */  {
217        /* AP multicast NONE */ {
218            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
219            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
220            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
221            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
222            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
223            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
224        /* AP multicast WEP */ {
225            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
226            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
227            /* STA TKIP */  { TI_OK,  TWD_CIPHER_TKIP, TWD_CIPHER_WEP  ,4},
228            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
229            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
230            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
231        /* AP multicast TKIP */ {
232            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
233            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
234            /* STA TKIP */  { TI_OK,  TWD_CIPHER_TKIP, TWD_CIPHER_TKIP ,7},
235            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
236            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
237            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
238        /* AP multicast WRAP */ {
239            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
240            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
241            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
242            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
243            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
244            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
245        /* AP multicast CCMP */ {
246            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
247            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
248            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
249            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
250            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
251            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
252        /* AP multicast WEP104 */ {
253            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
254            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
255            /* STA TKIP */  { TI_OK,  TWD_CIPHER_TKIP, TWD_CIPHER_WEP104 ,4},
256            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
257            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
258            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}}},
259/* AP unicast AES_WRAP */ {
260        /* AP multicast NONE */ {
261            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
262            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
263            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
264            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
265            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
266            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
267        /* AP multicast WEP40 */ {
268            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
269            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
270            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
271            /* STA AES */   { TI_OK,  TWD_CIPHER_AES_WRAP, TWD_CIPHER_WEP ,5},
272            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
273            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
274        /* AP multicast TKIP */ {
275            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
276            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
277            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
278            /* STA AES */   { TI_OK,  TWD_CIPHER_AES_WRAP, TWD_CIPHER_TKIP ,6},
279            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
280            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
281        /* AP multicast WRAP */ {
282            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
283            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
284            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
285            /* STA AES */   { TI_OK,  TWD_CIPHER_AES_WRAP, TWD_CIPHER_AES_WRAP ,8},
286            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
287            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
288        /* AP multicast CCMP */ {
289            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
290            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
291            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
292            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
293            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
294            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
295        /* AP multicast WEP104 */ {
296            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
297            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
298            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
299            /* STA AES */   { TI_OK,  TWD_CIPHER_AES_WRAP, TWD_CIPHER_WEP104 ,5},
300            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
301            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}}},
302/* AP unicast AES_CCMP */ {
303        /* AP multicast NONE */ {
304            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
305            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
306            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
307            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
308            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
309            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
310        /* AP multicast WEP */ {
311            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
312            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
313            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
314            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
315            /* STA CCMP */  { TI_OK,  TWD_CIPHER_AES_CCMP, TWD_CIPHER_WEP ,5},
316            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
317        /* AP multicast TKIP */ {
318            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
319            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
320            /* STA TKIP */  { TI_OK,  TWD_CIPHER_AES_CCMP, TWD_CIPHER_TKIP ,6},
321            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
322            /* STA CCMP */  { TI_OK,  TWD_CIPHER_AES_CCMP, TWD_CIPHER_TKIP ,6},
323            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
324        /* AP multicast WRAP */ {
325            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
326            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
327            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
328            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
329            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
330            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
331        /* AP multicast CCMP */ {
332            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
333            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
334            /* STA TKIP */  { TI_OK,  TWD_CIPHER_AES_CCMP, TWD_CIPHER_AES_CCMP ,6},
335            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
336            /* STA CCMP */  { TI_OK,  TWD_CIPHER_AES_CCMP, TWD_CIPHER_AES_CCMP ,8},
337            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
338        /* AP multicast WEP */ {
339            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
340            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
341            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
342            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
343            /* STA CCMP */  { TI_OK,  TWD_CIPHER_AES_CCMP, TWD_CIPHER_WEP104 ,5},
344            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}}},
345/* AP unicast WEP104 */  {
346        /* AP multicast NONE */ {
347            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
348            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
349            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
350            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
351            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
352            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
353        /* AP multicast WEP */ {
354            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
355            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
356            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
357            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
358            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
359            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
360        /* AP multicast TKIP */ {
361            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
362            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
363            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
364            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
365            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
366            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
367        /* AP multicast WRAP */ {
368            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
369            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
370            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
371            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
372            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
373            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
374        /* AP multicast CCMP */ {
375            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
376            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
377            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
378            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
379            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
380            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}},
381        /* AP multicast WEP104 */ {
382            /* STA NONE */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
383            /* STA WEP */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
384            /* STA TKIP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
385            /* STA AES */   { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
386            /* STA CCMP */  { TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0},
387            /* STA WEP104 */{ TI_NOK, TWD_CIPHER_NONE, TWD_CIPHER_NONE ,0}}}
388
389
390};
391
392
393/* PMKID cache */
394/* static wpa2_pmkid_cache_t wpa2_pmkid_cache; */
395
396/* Function prototypes */
397
398TI_STATUS admCtrlWpa2_parseIe(admCtrl_t *pAdmCtrl, TI_UINT8 *pWpa2Ie, wpa2IeData_t *pWpa2Data);
399TI_UINT16 admCtrlWpa2_buildCapabilities(admCtrl_t *pAdmCtrl);
400TI_UINT32  admCtrlWpa2_parseSuiteVal(admCtrl_t *pAdmCtrl, TI_UINT8* suiteVal, TI_UINT32 maxVal, TI_UINT32 unknownVal);
401TI_STATUS admCtrlWpa2_checkCipherSuiteValidity(ECipherSuite unicastSuite, ECipherSuite broadcastSuite, ECipherSuite encryptionStatus);
402TI_STATUS admCtrlWpa2_getCipherSuiteMetric (admCtrl_t *pAdmCtrl, wpa2IeData_t *pWpa2Data, TI_UINT32 *metric,
403                                            ECipherSuite *uSuite,  ECipherSuite  *bSuite);
404TI_STATUS admCtrlWpa2_DynamicConfig(admCtrl_t *pAdmCtrl, TRsnPaeConfig *pPaeConfig);
405
406TI_STATUS admCtrlWpa2_resetPMKIDCache(admCtrl_t *pAdmCtrl);
407/*TI_STATUS admCtrlWpa2_sendPMKIDCandListAfterDelay(admCtrl_t * pAdmCtrl, TI_UINT32 delay);*/
408TI_STATUS admCtrlWpa2_getPMKIDList(admCtrl_t * pAdmCtrl,OS_802_11_PMKID *pmkidList);
409TI_STATUS admCtrlWpa2_setPMKIDList(admCtrl_t * pAdmCtrl, OS_802_11_PMKID *pmkidList);
410
411TI_STATUS admCtrlWpa2_addPMKID(admCtrl_t * pAdmCtrl, TMacAddr * pBSSID, pmkidValue_t pmkID);
412TI_STATUS admCtrlWpa2_findPMKID(admCtrl_t * pAdmCtrl, TMacAddr *pBSSID,
413                                pmkidValue_t *pPMKID, TI_UINT8  *cacheIndex);
414
415static TI_BOOL admCtrlWpa2_getPreAuthStatus(admCtrl_t *pAdmCtrl, TMacAddr *givenAP, TI_UINT8  *cacheIndex);
416
417static TI_STATUS admCtrlWpa2_startPreAuth(admCtrl_t *pAdmCtrl, TBssidList4PreAuth *pBssidList);
418
419static void admCtrlWpa2_buildAndSendPMKIDCandList(TI_HANDLE hHandle, TBssidList4PreAuth *apList);
420
421static TI_STATUS admCtrlWpa2_get802_1x_AkmExists (admCtrl_t *pAdmCtrl, TI_BOOL *wpa_802_1x_AkmExists);
422
423/**
424*
425* admCtrlWpa_config  - Configure XCC admission control.
426*
427* \b Description:
428*
429* Configure XCC admission control.
430*
431* \b ARGS:
432*
433*  I   - pAdmCtrl - context \n
434*
435* \b RETURNS:
436*
437*  TI_OK on success, TI_NOK on failure.
438*
439* \sa
440*/
441TI_STATUS admCtrlWpa2_config(admCtrl_t *pAdmCtrl)
442{
443    TI_STATUS           status;
444    TRsnPaeConfig     paeConfig;
445
446    /* check and set admission control default parameters */
447    pAdmCtrl->authSuite =   RSN_AUTH_OPEN;
448    if (pAdmCtrl->unicastSuite == TWD_CIPHER_NONE)
449    {
450        pAdmCtrl->unicastSuite = TWD_CIPHER_AES_CCMP;
451    }
452    if (pAdmCtrl->broadcastSuite == TWD_CIPHER_NONE)
453    {
454        pAdmCtrl->broadcastSuite = TWD_CIPHER_AES_CCMP;
455    }
456
457    /* set callback functions (API) */
458    pAdmCtrl->getInfoElement = admCtrlWpa2_getInfoElement;
459    pAdmCtrl->setSite  = admCtrlWpa2_setSite;
460    pAdmCtrl->evalSite = admCtrlWpa2_evalSite;
461
462    pAdmCtrl->getPmkidList      = admCtrlWpa2_getPMKIDList;
463    pAdmCtrl->setPmkidList      = admCtrlWpa2_setPMKIDList;
464    pAdmCtrl->resetPmkidList    = admCtrlWpa2_resetPMKIDCache;
465    pAdmCtrl->getPreAuthStatus = admCtrlWpa2_getPreAuthStatus;
466    pAdmCtrl->startPreAuth = admCtrlWpa2_startPreAuth;
467    pAdmCtrl->get802_1x_AkmExists = admCtrlWpa2_get802_1x_AkmExists;
468
469    /* set key management suite (AKMP) */
470    switch (pAdmCtrl->externalAuthMode)
471    {
472    case RSN_EXT_AUTH_MODE_WPA2:
473    case RSN_EXT_AUTH_MODE_WPA2PSK:
474        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_802_1X;
475        break;
476    case RSN_EXT_AUTH_MODE_WPANONE:
477        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_NONE;
478        /* Not supported */
479    default:
480        return TI_NOK;
481    }
482
483
484    paeConfig.authProtocol = pAdmCtrl->externalAuthMode;
485    paeConfig.unicastSuite = pAdmCtrl->unicastSuite;
486    paeConfig.broadcastSuite = pAdmCtrl->broadcastSuite;
487    paeConfig.keyExchangeProtocol = pAdmCtrl->keyMngSuite;
488    /* set default PAE configuration */
489    status = pAdmCtrl->pRsn->setPaeConfig(pAdmCtrl->pRsn, &paeConfig);
490
491    return status;
492}
493
494
495/**
496*
497* admCtrlWpa2_getInfoElement - Get the current information element.
498*
499* \b Description:
500*
501* Get the current information element.
502*
503* \b ARGS:
504*
505*  I   - pAdmCtrl - context \n
506*  I   - pIe - IE buffer \n
507*  I   - pLength - length of IE \n
508*
509* \b RETURNS:
510*
511*  TI_OK on success, TI_NOK on failure.
512*
513* \sa
514*/
515
516TI_STATUS admCtrlWpa2_getInfoElement(admCtrl_t *pAdmCtrl, TI_UINT8 *pIe, TI_UINT32 *pLength)
517{
518    wpa2IePacket_t     *pWpa2IePacket;
519    TI_UINT8           length = 0;
520    TMacAddr           assocBssid;
521    TMacAddr           pBssid;
522    pmkidValue_t       pmkId;
523    TI_STATUS          status;
524    TI_UINT8           index;
525
526    if (pIe==NULL)
527    {
528        *pLength = 0;
529        return TI_NOK;
530    }
531
532    /* check Group suite validity */
533    if (!broadcastCipherSuiteValidity[pAdmCtrl->networkMode][pAdmCtrl->broadcastSuite])
534    {
535        *pLength = 0;
536        return TI_NOK;
537    }
538
539    /* Init Wpa2 IE (RSN IE) */
540    pWpa2IePacket = (wpa2IePacket_t*)pIe;
541    os_memoryZero(pAdmCtrl->hOs, pWpa2IePacket, sizeof(wpa2IePacket_t));
542    /* Fill the element ID */
543    pWpa2IePacket->elementid = RSN_IE_ID;
544    SET_WLAN_WORD(&pWpa2IePacket->version,ENDIAN_HANDLE_WORD(WPA2_OUI_MAX_VERSION));
545    length += 2;
546    /* build group suite */
547    os_memoryCopy(pAdmCtrl->hOs, (void *)pWpa2IePacket->groupSuite, wpa2IeOuiIe, 3);
548    pWpa2IePacket->groupSuite[3] = (TI_UINT8)pAdmCtrl->pRsn->paeConfig.broadcastSuite;
549    length += 4;
550    /* build pairwise suite - we always send only one pairwise suite */
551    SET_WLAN_WORD(&pWpa2IePacket->pairwiseSuiteCnt,ENDIAN_HANDLE_WORD(0x0001));
552    length += 2;
553    os_memoryCopy(pAdmCtrl->hOs, (void *)pWpa2IePacket->pairwiseSuite, wpa2IeOuiIe, 3);
554    pWpa2IePacket->pairwiseSuite[3] = (TI_UINT8)pAdmCtrl->pRsn->paeConfig.unicastSuite;
555    length += 4;
556    /* build keyMng suite - we always send only one key mgmt  suite*/
557    SET_WLAN_WORD(&pWpa2IePacket->authKeyMngSuiteCnt,ENDIAN_HANDLE_WORD(0x0001));
558    length += 2;
559    os_memoryCopy(pAdmCtrl->hOs, (void *)pWpa2IePacket->authKeyMngSuite, wpa2IeOuiIe, 3);
560    switch (pAdmCtrl->externalAuthMode)
561    {
562    case RSN_EXT_AUTH_MODE_OPEN:
563    case RSN_EXT_AUTH_MODE_SHARED_KEY:
564    case RSN_EXT_AUTH_MODE_AUTO_SWITCH:
565        pWpa2IePacket->authKeyMngSuite[3] = WPA2_IE_KEY_MNG_NONE;
566        break;
567    case RSN_EXT_AUTH_MODE_WPA2:
568    case RSN_EXT_AUTH_MODE_WPA:   /* for Any-WPA/WPA-Mixed mode */
569        {
570#ifdef XCC_MODULE_INCLUDED
571            TI_UINT8   akmSuite[DOT11_OUI_LEN+1];
572
573            if (admCtrlXCC_getCckmAkm(pAdmCtrl, akmSuite))
574            {
575                os_memoryCopy(pAdmCtrl->hOs, (void*)pWpa2IePacket->authKeyMngSuite, akmSuite, DOT11_OUI_LEN+1);
576            }
577            else
578#endif
579            {
580                pWpa2IePacket->authKeyMngSuite[3] = WPA2_IE_KEY_MNG_801_1X;
581            }
582        }
583        break;
584    case RSN_EXT_AUTH_MODE_WPA2PSK:
585    case RSN_EXT_AUTH_MODE_WPAPSK:
586        pWpa2IePacket->authKeyMngSuite[3] = WPA2_IE_KEY_MNG_PSK_801_1X;
587        break;
588    default:
589        pWpa2IePacket->authKeyMngSuite[3] = WPA2_IE_KEY_MNG_NONE;
590        break;
591    }
592    length += 4;
593    /* build Capabilities */
594    SET_WLAN_WORD(&pWpa2IePacket->capabilities,ENDIAN_HANDLE_WORD(admCtrlWpa2_buildCapabilities(pAdmCtrl)));
595    length += 2;
596    /* build PMKID list: we support no more than 1 PMKSA per AP, */
597    /* so no more than 1 PMKID can be sent in the RSN IE         */
598    if(pAdmCtrl->preAuthSupport &&
599       (pAdmCtrl->pRsn->paeConfig.authProtocol == RSN_EXT_AUTH_MODE_WPA2))
600    {
601        /* Init value of PMKID count is 0 */
602        SET_WLAN_WORD(&pWpa2IePacket->pmkIdCnt,ENDIAN_HANDLE_WORD(0));
603        length += 2;
604        status = ctrlData_getParamBssid(pAdmCtrl->pRsn->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, pBssid);
605		MAC_COPY(assocBssid, pBssid);
606        TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_getInfoElement - find PMKID \n");
607        status = admCtrlWpa2_findPMKID(pAdmCtrl, &assocBssid, &pmkId, &index);
608        if(status == TI_OK)
609        {
610            TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_getInfoElement - PMKID was found! \n");
611            SET_WLAN_WORD(&pWpa2IePacket->pmkIdCnt,ENDIAN_HANDLE_WORD(1));
612            os_memoryCopy(pAdmCtrl->hOs, (TI_UINT8 *)pWpa2IePacket->pmkId,
613                      (TI_UINT8 *)pmkId, PMKID_VALUE_SIZE);
614            length += PMKID_VALUE_SIZE;
615        }
616    }
617    pWpa2IePacket->length = length;    /* RSN IE length without IEid and length field */
618    *pLength              = length+2;  /* The whole length of the RSN IE */
619    TRACE_INFO_HEX(pAdmCtrl->hReport, pIe, *pLength);
620    return TI_OK;
621
622}
623/**
624*
625* admCtrlWpa2_setSite  - Set current primary site parameters for registration.
626*
627* \b Description:
628*
629* Set current primary site parameters for registration.
630*
631* \b ARGS:
632*
633*  I   - pAdmCtrl - context \n
634*  I   - pRsnData - site's RSN data \n
635*  O   - pAssocIe - result IE of evaluation \n
636*  O   - pAssocIeLen - length of result IE of evaluation \n
637*
638* \b RETURNS:
639*
640*  TI_OK on site is aproved, TI_NOK on site is rejected.
641*
642* \sa
643*/
644TI_STATUS admCtrlWpa2_setSite(admCtrl_t *pAdmCtrl, TRsnData *pRsnData, TI_UINT8 *pAssocIe, TI_UINT8 *pAssocIeLen)
645{
646    TI_STATUS               status;
647    paramInfo_t             *pParam;
648    TTwdParamInfo           tTwdParam;
649    wpa2IeData_t            wpa2Data;
650    TRsnPaeConfig           paeConfig;
651    TI_UINT8                *pWpa2Ie;
652    ECipherSuite            uSuite, bSuite;
653
654    *pAssocIeLen = 0;
655
656    if (pRsnData==NULL)
657    {
658        return TI_NOK;
659    }
660
661    pParam = (paramInfo_t *)os_memoryAlloc(pAdmCtrl->hOs, sizeof(paramInfo_t));
662    if (!pParam)
663        return TI_NOK;
664
665    if (pRsnData->pIe==NULL)
666    {
667        /* configure the MLME module with the 802.11 OPEN authentication suite,
668            THe MLME will configure later the authentication module */
669        pParam->paramType = MLME_LEGACY_TYPE_PARAM;
670        pParam->content.mlmeLegacyAuthType = AUTH_LEGACY_OPEN_SYSTEM;
671        status = mlme_setParam(pAdmCtrl->hMlme, pParam);
672        goto adm_ctrl_wpa2_end;
673    }
674
675#ifdef XCC_MODULE_INCLUDED
676    /* Clean MIC and KP flags in the HAL.                */
677    /* It is needed if the previous privacy mode was XCC */
678    tTwdParam.paramType = TWD_RSN_XCC_SW_ENC_ENABLE_PARAM_ID;
679    tTwdParam.content.rsnXCCSwEncFlag = TI_FALSE;
680    status = TWD_SetParam (pAdmCtrl->pRsn->hTWD, &tTwdParam);
681
682    tTwdParam.paramType = TWD_RSN_XCC_MIC_FIELD_ENABLE_PARAM_ID;
683    tTwdParam.content.rsnXCCMicFieldFlag = TI_FALSE;
684    status = TWD_SetParam (pAdmCtrl->pRsn->hTWD, &tTwdParam);
685
686    /* Check if Aironet IE exists */
687    admCtrlXCC_setExtendedParams(pAdmCtrl, pRsnData);
688
689#endif /*XCC_MODULE_INCLUDED*/
690
691    status = admCtrl_parseIe(pAdmCtrl, pRsnData, &pWpa2Ie, RSN_IE_ID);
692    if (status != TI_OK)
693    {
694        goto adm_ctrl_wpa2_end;
695    }
696    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_setSite: RSN_IE=\n");
697    TRACE_INFO_HEX(pAdmCtrl->hReport, pRsnData->pIe, pRsnData->ieLen);
698    status = admCtrlWpa2_parseIe(pAdmCtrl, pWpa2Ie, &wpa2Data);
699    if (status != TI_OK)
700    {
701        goto adm_ctrl_wpa2_end;
702    }
703    if ((wpa2Data.unicastSuite[0]>=MAX_WPA2_CIPHER_SUITE) ||
704        (wpa2Data.broadcastSuite>=MAX_WPA2_CIPHER_SUITE) ||
705        (pAdmCtrl->unicastSuite>=MAX_WPA2_CIPHER_SUITE))
706    {
707        status = TI_NOK;
708        goto adm_ctrl_wpa2_end;
709    }
710    /* Check validity of Group suite */
711    if (!broadcastCipherSuiteValidity[pAdmCtrl->networkMode][wpa2Data.broadcastSuite])
712    {   /* check Group suite validity */
713        status = TI_NOK;
714        goto adm_ctrl_wpa2_end;
715    }
716
717    status = admCtrlWpa2_getCipherSuiteMetric (pAdmCtrl, &wpa2Data, NULL, &uSuite, &bSuite);
718    if (status != TI_OK)
719        goto adm_ctrl_wpa2_end;
720
721    /* set replay counter */
722    pAdmCtrl->replayCnt = wpa2Data.ptkReplayCounters;
723
724    *pAssocIeLen = pRsnData->ieLen;
725    if (pAssocIe != NULL)
726    {
727        os_memoryCopy(pAdmCtrl->hOs, pAssocIe, &wpa2Data, sizeof(wpa2IeData_t));
728    }
729
730    /* re-config PAE with updated unicast and broadcast suite values            */
731    /* If STA works in WpaMixed mode/AnyWpa mode, set PAE auth. mode to WPA2    */
732    paeConfig.authProtocol = pAdmCtrl->externalAuthMode;
733
734    if(pAdmCtrl->WPAPromoteFlags)
735    {
736       if(pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA)
737          paeConfig.authProtocol   = RSN_EXT_AUTH_MODE_WPA2;
738       if(pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPAPSK)
739          paeConfig.authProtocol   = RSN_EXT_AUTH_MODE_WPA2PSK;
740    }
741
742#ifdef XCC_MODULE_INCLUDED
743    pParam->paramType = XCC_CCKM_EXISTS;
744    pParam->content.XCCCckmExists = (wpa2Data.KeyMngSuite[0]==WPA2_IE_KEY_MNG_CCKM) ? TI_TRUE : TI_FALSE;
745    XCCMngr_setParam(pAdmCtrl->hXCCMngr, pParam);
746#endif
747
748    paeConfig.keyExchangeProtocol = pAdmCtrl->keyMngSuite;
749    paeConfig.unicastSuite        = uSuite;    /* Updated value */
750    paeConfig.broadcastSuite      = bSuite;    /* Updated value */
751    status = admCtrlWpa2_DynamicConfig(pAdmCtrl, &paeConfig);
752
753    if (status != TI_OK)
754    {
755        goto adm_ctrl_wpa2_end;
756    }
757
758    /* Now we configure the MLME module with the 802.11 legacy authentication suite,
759        THe MLME will configure later the authentication module */
760    pParam->paramType = MLME_LEGACY_TYPE_PARAM;
761#ifdef XCC_MODULE_INCLUDED
762    if (pAdmCtrl->networkEapMode!=OS_XCC_NETWORK_EAP_OFF)
763    {
764        pParam->content.mlmeLegacyAuthType = AUTH_LEGACY_RESERVED1;
765    }
766    else
767#endif
768    {
769        pParam->content.mlmeLegacyAuthType = AUTH_LEGACY_OPEN_SYSTEM;
770    }
771    status = mlme_setParam(pAdmCtrl->hMlme, pParam);
772    if (status != TI_OK)
773    {
774        goto adm_ctrl_wpa2_end;
775    }
776
777    pParam->paramType = RX_DATA_EAPOL_DESTINATION_PARAM;
778    pParam->content.rxDataEapolDestination = OS_ABS_LAYER;
779    status = rxData_setParam(pAdmCtrl->hRx, pParam);
780    if (status != TI_OK)
781    {
782        goto adm_ctrl_wpa2_end;
783    }
784
785    /* Configure privacy status in HAL so that HW is prepared to recieve keys */
786    tTwdParam.paramType = TWD_RSN_SECURITY_MODE_PARAM_ID;
787    tTwdParam.content.rsnEncryptionStatus = (ECipherSuite)paeConfig.unicastSuite;
788    status = TWD_SetParam(pAdmCtrl->pRsn->hTWD, &tTwdParam);
789adm_ctrl_wpa2_end:
790    os_memoryFree(pAdmCtrl->hOs, pParam, sizeof(paramInfo_t));
791    return status;
792}
793
794/**
795*
796* admCtrlWpa_evalSite  - Evaluate site for registration.
797*
798* \b Description:
799*
800* evaluate site RSN capabilities against the station's cap.
801* If the BSS type is infrastructure, the station matches the site only if it's WEP status is same as the site
802* In IBSS, it does not matter
803*
804* \b ARGS:
805*
806*  I   - pAdmCtrl - Context \n
807*  I   - pRsnData - site's RSN data \n
808*  O   - pEvaluation - Result of evaluation \n
809*
810* \b RETURNS:
811*
812*  TI_OK
813*
814* \sa
815*/
816TI_STATUS admCtrlWpa2_evalSite(admCtrl_t *pAdmCtrl, TRsnData *pRsnData, TRsnSiteParams *pRsnSiteParams, TI_UINT32 *pEvaluation)
817{
818    TI_STATUS               status;
819    wpa2IeData_t            wpa2Data;
820    TI_UINT8                *pWpa2Ie;
821    ECipherSuite            uSuite, bSuite,encryptionStatus;
822    TI_UINT8                i = 0;
823    TIWLN_SIMPLE_CONFIG_MODE  wscMode = TIWLN_SIMPLE_CONFIG_OFF;
824
825    *pEvaluation = 0;
826
827    if (pRsnData==NULL)
828    {
829        return TI_NOK;
830    }
831    if (pRsnData->pIe==NULL)
832    {
833        return TI_NOK;
834    }
835
836    if (pRsnSiteParams->bssType != BSS_INFRASTRUCTURE)
837    {
838        return TI_NOK;
839    }
840
841	pAdmCtrl->getCipherSuite(pAdmCtrl, &encryptionStatus);
842	if ((encryptionStatus == TWD_CIPHER_TKIP) && (pRsnSiteParams->pHTCapabilities->tHdr[0] != TI_FALSE) && (pRsnSiteParams->pHTInfo->tHdr[0] != TI_FALSE))
843	{
844		TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION,"Dismiss AP - HT with TKIP is not valid");
845        return TI_NOK; /* if the encyption is TKIP and the site does support HT(11n) the site can not be a candidate */
846	}
847    /* Get Simple-Config state */
848    siteMgr_getParamWSC(pAdmCtrl->pRsn->hSiteMgr, &wscMode); /* SITE_MGR_SIMPLE_CONFIG_MODE */
849    status = admCtrl_parseIe(pAdmCtrl, pRsnData, &pWpa2Ie, RSN_IE_ID);
850    if (status != TI_OK)
851    {
852        return status;
853    }
854    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_evalSite, IE=\n");
855
856    TRACE_INFO_HEX(pAdmCtrl->hReport, pRsnData->pIe, pRsnData->ieLen);
857
858    status = admCtrlWpa2_parseIe(pAdmCtrl, pWpa2Ie, &wpa2Data);
859    if (status != TI_OK)
860    {
861        return status;
862    }
863
864	/* check keyMngSuite validity */
865    status = TI_NOK;
866    for(i = 0;
867       (i < wpa2Data.KeyMngSuiteCnt) &&(i<MAX_WPA2_KEY_MNG_SUITES)&& (status != TI_OK);
868        i++)
869    {
870    	switch (wpa2Data.KeyMngSuite[i])
871       	{
872          	case WPA2_IE_KEY_MNG_NONE:
873            	status = (pAdmCtrl->externalAuthMode <= RSN_EXT_AUTH_MODE_AUTO_SWITCH) ? TI_OK : TI_NOK;
874              	break;
875          	case WPA2_IE_KEY_MNG_801_1X:
876#ifdef XCC_MODULE_INCLUDED
877			/* CCKM is allowed only in 802.1x auth */
878          	case WPA2_IE_KEY_MNG_CCKM:
879#endif
880
881            	if(!pAdmCtrl->WPAPromoteFlags)
882               		status = (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2) ? TI_OK : TI_NOK;
883              	else
884                 	/* Any-WPA mode is supported */
885                 	status = ((pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2) ||
886                        (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA)) ? TI_OK : TI_NOK;
887              	break;
888          	case WPA2_IE_KEY_MNG_PSK_801_1X:
889				if(!pAdmCtrl->WPAPromoteFlags)
890                	status = (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2PSK) ? TI_OK : TI_NOK;
891             	else
892             		/* Any-WPA mode is supported */
893                	status = ((pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2PSK) ||
894                				(wscMode && (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA)) ||
895                    			(pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPAPSK)) ? TI_OK : TI_NOK;
896
897				if ((status == TI_NOK) && (wpa2Data.KeyMngSuiteCnt > 1) && (wpa2Data.KeyMngSuite[1] == WPA2_IE_KEY_MNG_801_1X) && (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2))
898                {
899                TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Overriding AKM suite evaluation for simple-config\n");
900                    status = TI_OK;
901				}
902				break;
903       		default:
904           TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "admCtrlWpa2_evalSite, default, wpa2Data.KeyMngSuite[i]=%d \n",wpa2Data.KeyMngSuite[i]);
905             	status = TI_NOK;
906             	break;
907       	}
908    }
909
910    if (status != TI_OK)
911    {
912        TRACE3(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "admCtrlWpa2_evalSite, status=%d, externalAuthMode=%d, WPAPromoteFlags=%d \n", status, pAdmCtrl->externalAuthMode, pAdmCtrl->WPAPromoteFlags);
913        return status;
914    }
915
916    /* Check cipher suite validity */
917    if(admCtrlWpa2_getCipherSuiteMetric(pAdmCtrl, &wpa2Data, pEvaluation, &uSuite, &bSuite) != TI_OK)
918        return TI_NOK;
919
920    /* Check privacy bit if not in mixed mode */
921    if (!pAdmCtrl->mixedMode)
922    {   /* There's no mixed mode, so make sure that the privacy Bit matches the privacy mode*/
923        if (((pRsnData->privacy) && (uSuite == TWD_CIPHER_NONE)) ||
924            ((!pRsnData->privacy) && (uSuite > TWD_CIPHER_NONE)))
925        {
926            *pEvaluation = 0;
927            TRACE2(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_evalSite, mixedMode is TI_FALSE, privacy=%d, uSuite=%d\n", pRsnData->privacy, uSuite);
928            return TI_NOK;
929        }
930    }
931
932    /* always return TI_OK */
933    return TI_OK;
934}
935
936
937/**
938*
939* admCtrlWpa2_parseIe  - Parse an WPA information element.
940*
941* \b Description:
942*
943* Parse an WPA information element.
944* Builds a structure of the unicast adn broadcast cihper suites,
945* the key management suite and the capabilities.
946*
947* \b ARGS:
948*
949*  I   - pAdmCtrl - pointer to admCtrl context
950*  I   - pWpa2Ie  - pointer to WPA IE (RSN IE) buffer  \n
951*  O   - pWpa2Data - WPA2 IE (RSN IE) structure after parsing
952*
953*
954* \b RETURNS:
955*
956* TI_OK on success, TI_NOK on failure.
957*
958* \sa
959*/
960TI_STATUS admCtrlWpa2_parseIe(admCtrl_t *pAdmCtrl, TI_UINT8 *pWpa2Ie, wpa2IeData_t *pWpa2Data)
961{
962    dot11_RSN_t      *wpa2Ie       =  (dot11_RSN_t *)pWpa2Ie;
963    TI_UINT16            temp2bytes =0, capabilities;
964    TI_UINT8             dataOffset = 0, i = 0, j = 0, curKeyMngSuite = 0;
965    ECipherSuite     curCipherSuite = TWD_CIPHER_NONE;
966
967    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: DEBUG: admCtrlWpa2_parseIe\n\n");
968
969    if ((pWpa2Data == NULL) || (pWpa2Ie == NULL))
970    {
971        return TI_NOK;
972    }
973
974    COPY_WLAN_WORD(&temp2bytes, wpa2Ie->rsnIeData);
975    dataOffset += 2;
976
977    /* Check the header fields and the version */
978    if((wpa2Ie->hdr[0] != RSN_IE_ID) || (wpa2Ie->hdr[1] < WPA2_IE_MIN_LENGTH) ||
979       (temp2bytes != WPA2_OUI_MAX_VERSION))
980    {
981        TRACE3(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "Wpa2_ParseIe Error: length=0x%x, elementid=0x%x, version=0x%x\n", wpa2Ie->hdr[1], wpa2Ie->hdr[0], temp2bytes);
982
983        return TI_NOK;
984    }
985
986
987    /* Set default values */
988    os_memoryZero(pAdmCtrl->hOs, pWpa2Data, sizeof(wpa2IeData_t));
989
990    pWpa2Data->broadcastSuite = TWD_CIPHER_AES_CCMP;
991    pWpa2Data->unicastSuiteCnt = 1;
992    pWpa2Data->unicastSuite[0] = TWD_CIPHER_AES_CCMP;
993    pWpa2Data->KeyMngSuiteCnt = 1;
994    pWpa2Data->KeyMngSuite[0] = WPA2_IE_KEY_MNG_801_1X;
995
996    /* If we've reached the end of the received RSN IE */
997    if(wpa2Ie->hdr[1] < WPA2_IE_GROUP_SUITE_LENGTH)
998        return TI_OK;
999
1000    /* Processing of Group Suite field - 4 bytes*/
1001    pWpa2Data->broadcastSuite = (ECipherSuite)admCtrlWpa2_parseSuiteVal(pAdmCtrl, (TI_UINT8 *)wpa2Ie->rsnIeData + dataOffset,
1002                                                          TWD_CIPHER_WEP104, TWD_CIPHER_UNKNOWN);
1003    dataOffset +=4;
1004    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: GroupSuite %x \n", pWpa2Data->broadcastSuite);
1005
1006
1007    /* Processing of Pairwise (Unicast) Cipher Suite - 2 bytes counter and list of 4-byte entries */
1008    if(wpa2Ie->hdr[1] < WPA2_IE_MIN_PAIRWISE_SUITE_LENGTH)
1009        return TI_OK;
1010
1011    COPY_WLAN_WORD(&pWpa2Data->unicastSuiteCnt, wpa2Ie->rsnIeData + dataOffset);
1012    dataOffset += 2;
1013
1014    if(pWpa2Data->unicastSuiteCnt > UNICAST_CIPHER_MAXNO_IN_RSNIE)
1015    {
1016        /* something wrong in the RSN IE */
1017        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "Wpa2_ParseIe Error: Pairwise cipher suite count is  %d \n", pWpa2Data->unicastSuiteCnt);
1018        return TI_NOK;
1019    }
1020
1021    /* Get unicast cipher suites */
1022    for(i = 0; i < pWpa2Data->unicastSuiteCnt; i++)
1023    {
1024        curCipherSuite = (ECipherSuite)admCtrlWpa2_parseSuiteVal(pAdmCtrl, (TI_UINT8 *)wpa2Ie->rsnIeData + dataOffset,
1025                                                   TWD_CIPHER_WEP104, TWD_CIPHER_UNKNOWN);
1026        if(curCipherSuite == TWD_CIPHER_NONE)
1027            curCipherSuite = pWpa2Data->broadcastSuite;
1028
1029        pWpa2Data->unicastSuite[i] = curCipherSuite;
1030        dataOffset +=4;
1031
1032        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa_IE: unicast suite %x \n", curCipherSuite);
1033    }
1034
1035    /* Sort all the unicast suites supported by the AP in the decreasing order */
1036    /* (so the best cipher suite will be the first)                            */
1037    if(pWpa2Data->unicastSuiteCnt > 1)
1038    {
1039       for(i = 0; i < (pWpa2Data->unicastSuiteCnt -1); i ++)
1040       {
1041           for(j = 0; j < i; j ++)
1042           {
1043               if(pWpa2Data->unicastSuite[j] > pWpa2Data->unicastSuite[j + 1])
1044               {
1045                   curCipherSuite               = pWpa2Data->unicastSuite[j];
1046                   pWpa2Data->unicastSuite[j]   = pWpa2Data->unicastSuite[j+1];
1047                   pWpa2Data->unicastSuite[j+1] = curCipherSuite;
1048               }
1049           }
1050       }
1051    }
1052
1053    /* If we've reached the end of the received RSN IE */
1054    if (wpa2Ie->hdr[1] == dataOffset)
1055        return TI_OK;
1056
1057     /* KeyMng Suite */
1058    COPY_WLAN_WORD(&(pWpa2Data->KeyMngSuiteCnt), wpa2Ie->rsnIeData + dataOffset);
1059
1060     dataOffset += 2;
1061     pAdmCtrl->wpaAkmExists = TI_FALSE;
1062     for(i = 0; i < pWpa2Data->KeyMngSuiteCnt; i++)
1063     {
1064#ifdef XCC_MODULE_INCLUDED
1065            curKeyMngSuite = admCtrlXCC_parseCckmSuiteVal4Wpa2(pAdmCtrl, (TI_UINT8 *)(wpa2Ie->rsnIeData + dataOffset));
1066            if (curKeyMngSuite == WPA2_IE_KEY_MNG_CCKM)
1067            {  /* CCKM is the maximum AKM */
1068                pWpa2Data->KeyMngSuite[i] = curKeyMngSuite;
1069            }
1070            else
1071#endif
1072            {
1073                curKeyMngSuite = admCtrlWpa2_parseSuiteVal(pAdmCtrl, (TI_UINT8 *)wpa2Ie->rsnIeData + dataOffset,
1074                            WPA2_IE_KEY_MNG_PSK_801_1X, WPA2_IE_KEY_MNG_NA);
1075            }
1076
1077
1078        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: authKeyMng %x  \n", curKeyMngSuite);
1079
1080         if ((curKeyMngSuite != WPA2_IE_KEY_MNG_NA) &&
1081             (curKeyMngSuite != WPA2_IE_KEY_MNG_CCKM))
1082         {
1083             pWpa2Data->KeyMngSuite[i] = curKeyMngSuite;
1084         }
1085
1086         if (curKeyMngSuite==WPA2_IE_KEY_MNG_801_1X)
1087         {   /* If 2 AKM exist, save also the second priority */
1088             pAdmCtrl->wpaAkmExists = TI_TRUE;
1089         }
1090
1091         dataOffset += 4;
1092
1093		 /* Include all AP key management supported suites in the wpaData structure */
1094            pWpa2Data->KeyMngSuite[i+1] = curKeyMngSuite;
1095     }
1096
1097    /* If we've reached the end of the received RSN IE */
1098    if (wpa2Ie->hdr[1] == dataOffset)
1099        return TI_OK;
1100
1101    /* Parse capabilities */
1102    COPY_WLAN_WORD(&capabilities, wpa2Ie->rsnIeData + dataOffset);
1103    pWpa2Data->bcastForUnicatst  = (TI_UINT8)(capabilities & WPA2_GROUP_4_UNICAST_CAPABILITY_MASK)>>
1104                                           WPA2_GROUP_4_UNICAST_CAPABILITY_SHIFT;
1105    pWpa2Data->ptkReplayCounters = (TI_UINT8)(capabilities &  WPA2_PTK_REPLAY_COUNTERS_CAPABILITY_MASK)>>
1106                                           WPA2_PTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1107
1108    switch (pWpa2Data->ptkReplayCounters)
1109    {
1110    case 0: pWpa2Data->ptkReplayCounters=1;
1111            break;
1112    case 1: pWpa2Data->ptkReplayCounters=2;
1113            break;
1114    case 2: pWpa2Data->ptkReplayCounters=4;
1115            break;
1116    case 3: pWpa2Data->ptkReplayCounters=16;
1117            break;
1118    default: pWpa2Data->ptkReplayCounters=1;
1119            break;
1120   }
1121   pWpa2Data->gtkReplayCounters = (TI_UINT8)(capabilities &
1122                                        WPA2_GTK_REPLAY_COUNTERS_CAPABILITY_MASK) >>
1123                                        WPA2_GTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1124   switch (pWpa2Data->gtkReplayCounters)
1125   {
1126   case 0: pWpa2Data->gtkReplayCounters=1;
1127            break;
1128   case 1: pWpa2Data->gtkReplayCounters=2;
1129            break;
1130   case 2: pWpa2Data->gtkReplayCounters=4;
1131            break;
1132   case 3: pWpa2Data->gtkReplayCounters=16;
1133            break;
1134   default: pWpa2Data->gtkReplayCounters=1;
1135            break;
1136   }
1137
1138   pWpa2Data->preAuthentication = (TI_UINT8)(capabilities & WPA2_PRE_AUTH_CAPABILITY_MASK);
1139
1140   TRACE5(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: capabilities %x, preAuthentication = %x, bcastForUnicatst %x, ptk = %x, gtk = %x\n", capabilities, pWpa2Data->preAuthentication, pWpa2Data->bcastForUnicatst, pWpa2Data->ptkReplayCounters, pWpa2Data->gtkReplayCounters);
1141
1142    return TI_OK;
1143
1144}
1145
1146
1147TI_UINT16 admCtrlWpa2_buildCapabilities(admCtrl_t *pAdmCtrl)
1148{
1149   TI_UINT16 capabilities = 0;
1150   TI_UINT16 replayCnt;
1151
1152
1153   /* Bit 0 - Pre-authentication is set to 0             */
1154   /* when RSN IE is sent from a STA (in assoc request)  */
1155
1156   /* Bit1: group key for unicast is set to 0*/
1157
1158   /* Bits 2&3: PTKSA Replay counter; bits 4&5 GTKSA replay Counters */
1159   switch (pAdmCtrl->replayCnt)
1160   {
1161   case 1:  replayCnt=0;
1162       break;
1163   case 2:  replayCnt=1;
1164       break;
1165   case 4:  replayCnt=2;
1166       break;
1167   case 16: replayCnt=3;
1168       break;
1169   default: replayCnt=0;
1170       break;
1171   }
1172
1173   capabilities |= replayCnt << WPA2_PTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1174   capabilities |= replayCnt << WPA2_GTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1175
1176   return   capabilities;
1177
1178}
1179
1180
1181TI_UINT32  admCtrlWpa2_parseSuiteVal(admCtrl_t *pAdmCtrl, TI_UINT8* suiteVal, TI_UINT32 maxVal, TI_UINT32 unknownVal)
1182{
1183    TI_UINT32  suite;
1184
1185    if ((pAdmCtrl==NULL) || (suiteVal==NULL))
1186    {
1187        return TWD_CIPHER_UNKNOWN;
1188    }
1189    if (!os_memoryCompare(pAdmCtrl->hOs, suiteVal, wpa2IeOuiIe, 3))
1190    {
1191        suite =  (ECipherSuite)((suiteVal[3]<=maxVal) ? suiteVal[3] : unknownVal);
1192    } else
1193    {
1194        suite = unknownVal;
1195    }
1196    return  suite;
1197
1198}
1199
1200
1201TI_STATUS admCtrlWpa2_checkCipherSuiteValidity (ECipherSuite unicastSuite, ECipherSuite broadcastSuite, ECipherSuite encryptionStatus)
1202{
1203    ECipherSuite maxCipher;
1204
1205    maxCipher = (unicastSuite>=broadcastSuite) ? unicastSuite : broadcastSuite ;
1206    if (maxCipher != encryptionStatus)
1207    {
1208        return TI_NOK;
1209    }
1210    if ((unicastSuite != TWD_CIPHER_NONE) && (broadcastSuite>unicastSuite))
1211    {
1212        return TI_NOK;
1213    }
1214    return TI_OK;
1215}
1216
1217TI_STATUS admCtrlWpa2_getCipherSuiteMetric (admCtrl_t *pAdmCtrl, wpa2IeData_t *pWpa2Data, TI_UINT32 *metric,
1218                                            ECipherSuite *uSuite, ECipherSuite  *bSuite)
1219{
1220   ECipherSuite   encryption   = TWD_CIPHER_NONE;
1221   ECipherSuite   unicastSuite = TWD_CIPHER_NONE, brdcstSuite = TWD_CIPHER_NONE;
1222   admCtrlWpa2_validity_t  admCtrlWpa2_validity;
1223   TI_UINT32     maxMetric = 0, index = 0;
1224   TI_STATUS  status = TI_NOK;
1225
1226   /* Set admCtrlWpa2_validity initial values */
1227   admCtrlWpa2_validity = admCtrlWpa2_validityTable[TWD_CIPHER_NONE][TWD_CIPHER_NONE][TWD_CIPHER_NONE];
1228
1229   /* Check validity of configured encryption (cipher) and validity of */
1230   /* promoted cipher (in case of AnyWPA (WPAmixed mode))              */
1231   pAdmCtrl->getCipherSuite(pAdmCtrl, &encryption);
1232   TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_getCipherSuiteMetric, encryption=%d\n", encryption);
1233
1234   while(encryption != TWD_CIPHER_NONE)
1235   {
1236      for (index=0; index<pWpa2Data->unicastSuiteCnt; index++)
1237      {
1238          admCtrlWpa2_validity =
1239          admCtrlWpa2_validityTable[pWpa2Data->unicastSuite[index]][pWpa2Data->broadcastSuite][encryption];
1240          if (admCtrlWpa2_validity.status == TI_OK)
1241          {
1242              TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_getCipherSuiteMetric, break: validity.evaluation=%d\n", admCtrlWpa2_validity.evaluation);
1243              break;
1244          }
1245      }
1246
1247      if ((admCtrlWpa2_validity.status == TI_OK) && (admCtrlWpa2_validity.evaluation > maxMetric))
1248      {
1249          TRACE2(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_getCipherSuiteMetric, validity.evaluation=%d, maxMetric=%d\n", admCtrlWpa2_validity.evaluation, maxMetric);
1250
1251          maxMetric       = admCtrlWpa2_validity.evaluation;
1252          status          = admCtrlWpa2_validity.status;
1253          unicastSuite    = admCtrlWpa2_validity.unicast;
1254          brdcstSuite     = admCtrlWpa2_validity.broadcast;
1255      }
1256
1257      if((pAdmCtrl->WPAPromoteFlags & ADMCTRL_WPA_OPTION_ENABLE_PROMOTE_CIPHER) &&
1258         (encryption != TWD_CIPHER_AES_CCMP))
1259         encryption = TWD_CIPHER_AES_CCMP;
1260      else
1261         encryption = TWD_CIPHER_NONE;
1262
1263    }  /* End of "while encryption" stmt */
1264
1265   if(metric)
1266      *metric = maxMetric;
1267
1268   if(uSuite)
1269      *uSuite = unicastSuite;
1270
1271   if(bSuite)
1272      *bSuite = brdcstSuite;
1273
1274    return status;
1275}
1276
1277
1278/**
1279*
1280* admCtrlWpa2_DynamicConfig  - Dynamic setting of WPA2 config parameters.
1281*
1282* \b Description:
1283*
1284*   Sets  WPA2 callback procedures and PAE configuration parameters.
1285*   This procedure is similar to admCtrlWpa2_Config procedure.
1286*   The main difference is that admCtrlWpa2_Config sets the DEFAULT VALUES
1287*   of the configuration parameters and so it should be called during
1288*   initialization of the driver code or when Auth mode or Encryption status
1289*   parameters are beeing set.
1290*   admCtrlWpa2_DynamicConfig set the updated values of WPA2 configuration
1291*   parameters which gets after negotiation with an AP. So the procedure
1292*   should be called during setSite stage.
1293*
1294* \b ARGS:
1295*
1296*  I   - pAdmCtrl    - pointer to admCtrl context
1297*  I   - pPaeConfig  - pointer to PAE structure
1298*
1299* \b RETURNS:
1300*
1301* TI_OK on success, TI_NOK on failure.
1302*
1303* \sa
1304*/
1305
1306TI_STATUS admCtrlWpa2_DynamicConfig(admCtrl_t *pAdmCtrl, TRsnPaeConfig *pPaeConfig)
1307{
1308    TI_STATUS status = TI_OK;
1309
1310    /* Set those WPA2 params and callback procedures used after setSite stage */
1311    pAdmCtrl->getInfoElement = admCtrlWpa2_getInfoElement;
1312
1313    pAdmCtrl->getPmkidList      = admCtrlWpa2_getPMKIDList;
1314    pAdmCtrl->setPmkidList      = admCtrlWpa2_setPMKIDList;
1315    pAdmCtrl->resetPmkidList    = admCtrlWpa2_resetPMKIDCache;
1316    pAdmCtrl->getPreAuthStatus = admCtrlWpa2_getPreAuthStatus;
1317    pAdmCtrl->startPreAuth = admCtrlWpa2_startPreAuth;
1318
1319    /* set key management suite */
1320    switch (pAdmCtrl->externalAuthMode)
1321    {
1322    case RSN_EXT_AUTH_MODE_WPA2:
1323    case RSN_EXT_AUTH_MODE_WPA2PSK:
1324        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_802_1X;
1325        break;
1326    case RSN_EXT_AUTH_MODE_WPA:  /* It is any-WPA (WPA-mixed mode ) */
1327    case RSN_EXT_AUTH_MODE_WPAPSK:
1328        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_802_1X;
1329        break;
1330    case RSN_EXT_AUTH_MODE_WPANONE:
1331        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_NONE;
1332        /* Not supported */
1333    default:
1334        return TI_NOK;
1335    }
1336
1337    /* Config PAE (if needed) */
1338    if(pPaeConfig)
1339       status = pAdmCtrl->pRsn->setPaeConfig(pAdmCtrl->pRsn, pPaeConfig);
1340
1341    return status;
1342}
1343
1344
1345
1346
1347/**
1348*
1349* admCtrlWpa2_findPMKID
1350*
1351* \b Description:
1352*
1353* Retrieve an AP's PMKID (if exist)
1354
1355* \b ARGS:
1356*
1357*  I   - pAdmCtrl - pointer to admCtrl context
1358*  I   - pBSSID   - pointer to AP's BSSID address
1359*  O   - pmkID    - pointer to AP's PMKID (if it is NULL ptr, only
1360*                   cache index will be returned to the caller)
1361*  O   - cacheIndex  - index of the cache table entry containing the
1362                       bssid
1363*
1364* \b RETURNS:
1365*
1366* TI_OK on success, TI_NOK on failure.
1367*
1368* \sa
1369*/
1370TI_STATUS admCtrlWpa2_findPMKID (admCtrl_t * pAdmCtrl, TMacAddr *pBSSID,
1371                                 pmkidValue_t *pPMKID, TI_UINT8  *cacheIndex)
1372{
1373
1374    TI_UINT8           i     = 0;
1375    TI_BOOL            found = TI_FALSE;
1376    TMacAddr    entryMac;
1377    TI_STATUS       status = TI_NOK;
1378
1379    while(!found && (i < ADMCTRL_PMKID_CACHE_SIZE) &&
1380                    (i <= pAdmCtrl->pmkid_cache.entriesNumber))
1381    {
1382		MAC_COPY (entryMac, pAdmCtrl->pmkid_cache.pmkidTbl[i].bssId);
1383        if (MAC_EQUAL (entryMac, *pBSSID))
1384        {
1385            found       = TI_TRUE;
1386            *cacheIndex = i;
1387            if(pPMKID)
1388            {
1389               os_memoryCopy(pAdmCtrl->hOs, (void*)pPMKID,
1390                             pAdmCtrl->pmkid_cache.pmkidTbl[i].pmkId,
1391                             PMKID_VALUE_SIZE);
1392            }
1393        }
1394        i++;
1395    }
1396
1397    if(found)
1398        status = TI_OK;
1399
1400    return status;
1401
1402}
1403
1404
1405/**
1406*
1407* admCtrlWpa2_getPMKIDList
1408*
1409* \b Description:
1410*
1411* Returns content of the PMKID cache
1412*
1413* \b ARGS:
1414*
1415*  I   - pAdmCtrl        - pointer to admCtrl context
1416*  O   - pmkidList       - memory buffer where the procedure writes the PMKIDs
1417*                          Supplied by the caller procedure. .
1418*
1419* \b RETURNS:
1420*
1421* TI_OK on success, TI_NOK on failure.
1422*
1423* \sa
1424*/
1425TI_STATUS admCtrlWpa2_getPMKIDList (admCtrl_t * pAdmCtrl,OS_802_11_PMKID *pmkidList)
1426{
1427
1428    TI_UINT8   neededLength, i = 0;
1429    TI_UINT8   NumOfEntries = pAdmCtrl->pmkid_cache.entriesNumber;
1430    TI_UINT8   *bssid, *pmkid;
1431
1432    if(!pAdmCtrl->preAuthSupport)
1433        return PARAM_NOT_SUPPORTED;
1434
1435    /* Check the buffer length */
1436    if(NumOfEntries > 1)
1437       neededLength = 30 + ((NumOfEntries - 1) * (MAC_ADDR_LEN + PMKID_VALUE_SIZE));
1438    else
1439       neededLength = 30;
1440
1441    if(neededLength > pmkidList->Length)
1442    {
1443        /* The buffer length is not enough */
1444        pmkidList->Length = neededLength;
1445        return TI_NOK;
1446    }
1447
1448    /* The buffer is big enough. Fill the info */
1449    pmkidList->Length         = neededLength;
1450    pmkidList->BSSIDInfoCount = NumOfEntries;
1451
1452    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  Get PMKID cache.  Number of entries  = %d \n", NumOfEntries);
1453
1454    for (i = 0; i < NumOfEntries; i++ )
1455    {
1456        bssid = (TI_UINT8 *) pAdmCtrl->pmkid_cache.pmkidTbl[i].bssId;
1457        pmkid = (TI_UINT8 *)pAdmCtrl->pmkid_cache.pmkidTbl[i].pmkId;
1458
1459        MAC_COPY(pmkidList->osBSSIDInfo[i].BSSID, bssid);
1460
1461        os_memoryCopy(pAdmCtrl->hOs,
1462                      (void *)pmkidList->osBSSIDInfo[i].PMKID,
1463                      &pmkid,
1464                      PMKID_VALUE_SIZE);
1465
1466        TRACE22(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  BSSID:  %.2X-%.2X-%.2X-%.2X-%.2X-%.2X   PMKID: %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X  \n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], pmkid[0], pmkid[1], pmkid[2], pmkid[3], pmkid[4], pmkid[5], pmkid[6], pmkid[7], pmkid[8], pmkid[9], pmkid[10],pmkid[11], pmkid[12],pmkid[13],pmkid[14],pmkid[15]);
1467    }
1468
1469    return TI_OK;
1470
1471}
1472
1473/**
1474*
1475* admCtrlWpa2_addPMKID
1476*
1477* \b Description:
1478*
1479* Add/Set an AP's PMKID received from the Supplicant
1480*
1481* \b ARGS:
1482*
1483*  I   - pAdmCtrl - pointer to admCtrl context
1484*  I   - pBSSID   - pointer to AP's BSSID address
1485*  I   - pmkID    - AP's PMKID
1486*
1487* \b RETURNS:
1488*
1489* TI_OK on success, TI_NOK on failure.
1490*
1491* \sa
1492*/
1493TI_STATUS admCtrlWpa2_addPMKID (admCtrl_t * pAdmCtrl, TMacAddr *pBSSID, pmkidValue_t pmkID)
1494{
1495   TI_UINT8         cacheIndex;
1496   TI_STATUS     status = TI_NOK;
1497
1498   /* Try to find the pBSSId in the PMKID cache */
1499   status = admCtrlWpa2_findPMKID (pAdmCtrl, pBSSID, NULL, &cacheIndex);
1500
1501   if(status == TI_OK)
1502   {
1503       /* Entry for the bssid has been found; Update PMKID */
1504       os_memoryCopy(pAdmCtrl->hOs,
1505                    (void*)&pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].pmkId,
1506                    pmkID, PMKID_VALUE_SIZE);
1507       /*pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].generationTs = os_timeStampMs(pAdmCtrl->hOs); */
1508   }
1509   else
1510   {
1511       /* The new entry is added to the next free entry. */
1512       /* Copy the new entry to the next free place.     */
1513       cacheIndex = pAdmCtrl->pmkid_cache.nextFreeEntry;
1514       MAC_COPY (pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].bssId, *pBSSID);
1515       os_memoryCopy(pAdmCtrl->hOs,
1516                     (void*)&pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].pmkId,
1517                     (void*)pmkID,
1518                     PMKID_VALUE_SIZE);
1519
1520       /* Update the next free entry index. (If the table is full, a new entry */
1521       /* will override the oldest entries from the beginning of the table)    */
1522       /* Update the number of entries. (it cannot be more than max cach size) */
1523       pAdmCtrl->pmkid_cache.nextFreeEntry  = (cacheIndex + 1) % ADMCTRL_PMKID_CACHE_SIZE;
1524
1525       if(pAdmCtrl->pmkid_cache.entriesNumber < ADMCTRL_PMKID_CACHE_SIZE)
1526          pAdmCtrl->pmkid_cache.entriesNumber ++;
1527   }
1528
1529        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN   Add PMKID   Entry index is %d \n", cacheIndex);
1530        TRACE22(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  BSSID: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X  PMKID: %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X  \n", (*pBSSID)[0], (*pBSSID)[1], (*pBSSID)[2], (*pBSSID)[3], (*pBSSID)[4], (*pBSSID)[5], pmkID[0], pmkID[1], pmkID[2], pmkID[3], pmkID[4], pmkID[5], pmkID[6], pmkID[7], pmkID[8], pmkID[9], pmkID[10],pmkID[11], pmkID[12],pmkID[13],pmkID[14],pmkID[15]);
1531
1532
1533
1534   return TI_OK;
1535}
1536
1537/**
1538*
1539* admCtrlWpa2_setPMKIDList
1540*
1541* \b Description:
1542*
1543* Set PMKID cache
1544*
1545* \b ARGS:
1546*
1547*  I   - pAdmCtrl        - pointer to admCtrl context
1548*  O   - pmkidList       - memory buffer where the procedure reads the PMKIDs from
1549*                          Supplied by the caller procedure.
1550* \b RETURNS:
1551*
1552* TI_OK on success, TI_NOK on failure.
1553*
1554* \sa
1555*/
1556TI_STATUS admCtrlWpa2_setPMKIDList (admCtrl_t * pAdmCtrl, OS_802_11_PMKID *pmkidList)
1557{
1558    TI_UINT8          neededLength, i = 0;
1559    TI_UINT8          NumOfEntries;
1560    TMacAddr   macAddr;
1561
1562    /* Check the minimal buffer length */
1563    if (pmkidList->Length < 2*sizeof(TI_UINT32))
1564    {
1565        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN: Set PMKID list - Buffer size < min length (8 bytes). Supplied length is %d .\n", pmkidList->Length);
1566        return TI_NOK;
1567    }
1568
1569    /* Check the num of entries in the buffer: if 0 it means that */
1570    /* PMKID cache has to be cleaned                              */
1571    if(pmkidList->BSSIDInfoCount == 0)
1572    {
1573        admCtrlWpa2_resetPMKIDCache(pAdmCtrl);
1574        return TI_OK;
1575    }
1576
1577    /* Check the buffer length */
1578    NumOfEntries = (TI_UINT8)pmkidList->BSSIDInfoCount;
1579    neededLength =  2*sizeof(TI_UINT32) + (NumOfEntries  *(MAC_ADDR_LEN + PMKID_VALUE_SIZE));
1580
1581    if(pmkidList->Length < neededLength)
1582    {
1583        /* Something wrong goes with the buffer */
1584        TRACE3(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN: Set PMKID list - no enough room for %d entries Needed length is %d. Supplied length is %d .\n", NumOfEntries, neededLength,pmkidList->Length);
1585        return TI_NOK;
1586    }
1587
1588    /*  Write  the PMKID to the PMKID cashe */
1589    pmkidList->BSSIDInfoCount = NumOfEntries;
1590    for (i = 0; i < NumOfEntries; i++ )
1591    {
1592         MAC_COPY (macAddr, pmkidList->osBSSIDInfo[i].BSSID);
1593
1594         TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_setPMKIDList: Received new pre-auth AP\n");
1595         if (pAdmCtrl->numberOfPreAuthCandidates)
1596         {
1597            pAdmCtrl->numberOfPreAuthCandidates--;
1598            if (pAdmCtrl->numberOfPreAuthCandidates == 0)
1599            {
1600               TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "Stopping the Pre-Auth timer since Pre-auth is finished\n");
1601               tmr_StopTimer (pAdmCtrl->hPreAuthTimerWpa2);
1602               /* Send PRE-AUTH end event to External Application */
1603               admCtrl_notifyPreAuthStatus (pAdmCtrl, RSN_PRE_AUTH_END);
1604            }
1605
1606            TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_setPMKIDList: %d APs left in candidate list\n",pAdmCtrl->numberOfPreAuthCandidates);
1607
1608         }
1609        else
1610        {
1611           TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_WARNING , "admCtrlWpa2_setPMKIDList: number of candidates was already zero...\n");
1612        }
1613        admCtrlWpa2_addPMKID(pAdmCtrl,&macAddr, (TI_UINT8 *)pmkidList->osBSSIDInfo[i].PMKID);
1614    }
1615
1616    return TI_OK;
1617
1618}
1619
1620/**
1621*
1622* admCtrlWpa2_resetPMKIDCache
1623*
1624* \b Description:
1625*
1626* Reset PMKID Table
1627*
1628* \b ARGS:
1629*
1630*  I   - pAdmCtrl - pointer to admCtrl context
1631*
1632* \b RETURNS:
1633*
1634* TI_OK on success, TI_NOK on failure.
1635*
1636* \sa
1637*/
1638TI_STATUS admCtrlWpa2_resetPMKIDCache (admCtrl_t *pAdmCtrl)
1639{
1640
1641    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  Reset PMKID cache.  %d entries are deleted. \n", pAdmCtrl->pmkid_cache.entriesNumber);
1642
1643   os_memoryZero(pAdmCtrl->hOs, (void*)&pAdmCtrl->pmkid_cache, sizeof(pmkid_cache_t));
1644
1645   return TI_OK;
1646}
1647
1648
1649/**
1650*
1651* admCtrlWpa2_sendPMKIDCandidateListAfterDelay
1652*
1653* \b Description:
1654*
1655* New Candidate List of APs with the same SSID as the STA is connected to
1656* is generated and sent after the delay to the supplicant
1657* in order to retrieve the new PMKIDs for the APs.
1658*
1659* \b ARGS:
1660*  I   - pAdmCtrl - pointer to admCtrl context
1661*
1662* \b RETURNS:
1663*
1664* TI_OK on success, TI_NOK on failure.
1665*
1666* \sa
1667*/
1668
1669static void admCtrlWpa2_buildAndSendPMKIDCandList (TI_HANDLE hHandle, TBssidList4PreAuth *apList)
1670{
1671
1672    admCtrl_t         *pAdmCtrl = (admCtrl_t *)hHandle;
1673    TI_UINT8          candIndex =0, apIndex = 0, size =0;
1674    paramInfo_t       *pParam;
1675    OS_802_11_PMKID_CANDIDATELIST  *pCandList;
1676    TI_UINT8           memBuff[PMKID_CAND_LIST_MEMBUFF_SIZE + sizeof(TI_UINT32)];
1677    dot11_RSN_t       *rsnIE = 0;
1678    wpa2IeData_t      wpa2Data;
1679    TI_STATUS         status = TI_NOK;
1680
1681    pParam = (paramInfo_t *)os_memoryAlloc(pAdmCtrl->hOs, sizeof(paramInfo_t));
1682    if (!pParam)
1683        return;
1684
1685    /* Get SSID that the STA is accociated with    */
1686    pParam->paramType = SME_DESIRED_SSID_ACT_PARAM;
1687    status          = sme_GetParam (pAdmCtrl->pRsn->hSmeSm, pParam);
1688    if(status != TI_OK) {
1689        os_memoryFree(pAdmCtrl->hOs, pParam, sizeof(paramInfo_t));
1690        return;
1691    }
1692
1693    /* If the existing PMKID cache contains information for not relevant */
1694    /* ssid (i.e. ssid was changed), clean up the PMKID cache and update */
1695    /* the ssid in the PMKID cache */
1696    if ((pAdmCtrl->pmkid_cache.ssid.len != pParam->content.smeDesiredSSID.len) ||
1697         (os_memoryCompare(pAdmCtrl->hOs, (TI_UINT8 *)pAdmCtrl->pmkid_cache.ssid.str,
1698          (TI_UINT8 *)pParam->content.smeDesiredSSID.str,
1699                          pAdmCtrl->pmkid_cache.ssid.len) != 0))
1700    {
1701        admCtrlWpa2_resetPMKIDCache(pAdmCtrl);
1702
1703        os_memoryCopy(pAdmCtrl->hOs, (void *)pAdmCtrl->pmkid_cache.ssid.str,
1704                      (void *)pParam->content.smeDesiredSSID.str,
1705                      pParam->content.siteMgrCurrentSSID.len);
1706        pAdmCtrl->pmkid_cache.ssid.len = pParam->content.smeDesiredSSID.len;
1707    }
1708
1709    /* Get list of APs of the SSID that the STA is associated with*/
1710    /*os_memoryZero(pAdmCtrl->hOs, (void*)&apList, sizeof(bssidListBySsid_t));
1711    status = siteMgr_GetApListBySsid (pAdmCtrl->pRsn->hSiteMgr,
1712                                      &param.content.siteMgrCurrentSSID,
1713                                      &apList);
1714    */
1715    os_memoryFree(pAdmCtrl->hOs, pParam, sizeof(paramInfo_t));
1716    if((apList == NULL) || (apList->NumOfItems == 0))
1717        return;
1718
1719    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList - Entry \n");
1720
1721    /* fill the PMKID candidate list */
1722    pCandList = (OS_802_11_PMKID_CANDIDATELIST *)(memBuff + sizeof(TI_UINT32));
1723    pCandList->Version = 1;
1724    for (apIndex=0; apIndex<pAdmCtrl->pmkid_cache.entriesNumber; apIndex++)
1725    {
1726        pAdmCtrl->pmkid_cache.pmkidTbl[apIndex].preAuthenticate = TI_FALSE;
1727    }
1728
1729    /* Go over AP list and find APs supporting pre-authentication */
1730    for(apIndex = 0; apIndex < apList->NumOfItems; apIndex++)
1731    {
1732        TI_UINT8 *bssidMac, i = 0;
1733
1734        status = TI_NOK;
1735
1736        if (apList->bssidList[apIndex].pRsnIEs==NULL)
1737        {
1738            continue;
1739        }
1740        /* Check is there RSN IE in this site */
1741        rsnIE = 0;
1742        while( !rsnIE && (i < MAX_RSN_IE))
1743        {
1744            if(apList->bssidList[apIndex].pRsnIEs[i].hdr[0] == RSN_IE_ID)
1745            {
1746                rsnIE  = &apList->bssidList[apIndex].pRsnIEs[i];
1747                status = TI_OK;
1748            }
1749            i ++;
1750        }
1751		if (rsnIE)
1752		{
1753			TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList - rsnIE-hdr.eleId = %x \n", rsnIE->hdr[0]);
1754		}
1755
1756        if(status == TI_OK)
1757           status = admCtrlWpa2_parseIe(pAdmCtrl, (TI_UINT8 *)rsnIE, &wpa2Data);
1758
1759        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList - parseIe status = %d \n", status);
1760        if(status == TI_OK)
1761        {
1762            TI_BOOL        preAuthStatus;
1763            TI_UINT8               cacheIndex;
1764
1765            preAuthStatus = admCtrlWpa2_getPreAuthStatus(pAdmCtrl, &apList->bssidList[apIndex].bssId, &cacheIndex);
1766
1767            TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList, preAuthStatus=%d \n", preAuthStatus);
1768
1769            if (preAuthStatus)
1770            {
1771                pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].preAuthenticate = TI_TRUE;
1772            }
1773
1774            bssidMac = (TI_UINT8 *)apList->bssidList[apIndex].bssId;
1775            MAC_COPY (pCandList->CandidateList[candIndex].BSSID, bssidMac);
1776
1777            if(pAdmCtrl->preAuthSupport && (wpa2Data.preAuthentication))
1778            {
1779               pCandList->CandidateList[candIndex].Flags =
1780                                 OS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLE;
1781            }
1782            else
1783            {
1784                pCandList->CandidateList[candIndex].Flags = 0;
1785
1786            }
1787
1788            TRACE8(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  Candidate [%d] is   %.2X-%.2X-%.2X-%.2X-%.2X-%.2X , Flags=0x%x\n", candIndex, bssidMac[0], bssidMac[1], bssidMac[2], bssidMac[3], bssidMac[4], bssidMac[5], pCandList->CandidateList[candIndex].Flags);
1789
1790            candIndex ++;
1791        }
1792
1793    }
1794    /* Add candidates that have valid PMKID, but were not in the list */
1795    for (apIndex=0; apIndex<pAdmCtrl->pmkid_cache.entriesNumber; apIndex++)
1796    {
1797        if (!pAdmCtrl->pmkid_cache.pmkidTbl[apIndex].preAuthenticate)
1798        {
1799            MAC_COPY (pCandList->CandidateList[candIndex].BSSID,
1800                      pAdmCtrl->pmkid_cache.pmkidTbl[apIndex].bssId);
1801            pCandList->CandidateList[apIndex].Flags =
1802                OS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLE;
1803            candIndex++;
1804        }
1805    }
1806
1807
1808    pCandList->NumCandidates = candIndex;
1809
1810
1811    /* Send Status Media specific indication to OS */
1812    size = sizeof(OS_802_11_PMKID_CANDIDATELIST) +
1813           (candIndex - 1) * sizeof(OS_802_11_PMKID_CANDIDATE) + sizeof(TI_UINT32);
1814
1815     /* Fill type of indication */
1816    *(TI_UINT32*)memBuff = os802_11StatusType_PMKID_CandidateList;
1817
1818    pCandList->NumCandidates = candIndex;
1819
1820    /* Store the number of candidates sent - needed for pre-auth finish event */
1821    pAdmCtrl->numberOfPreAuthCandidates = candIndex;
1822    /* Start the pre-authentication finish event timer */
1823    /* If the pre-authentication process is not over by the time it expires - we send an event */
1824    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "Starting PREAUTH timer (%d mSec)\n",pAdmCtrl->preAuthTimeout*candIndex);
1825    tmr_StartTimer (pAdmCtrl->hPreAuthTimerWpa2,
1826                    admCtrlWpa2_preAuthTimerExpire,
1827                    (TI_HANDLE)pAdmCtrl,
1828                    pAdmCtrl->preAuthTimeout * candIndex,
1829                    TI_FALSE);
1830
1831    EvHandlerSendEvent(pAdmCtrl->hEvHandler, IPC_EVENT_MEDIA_SPECIFIC,
1832                        memBuff, size);
1833
1834    /* Send PRE-AUTH start event to External Application */
1835    admCtrl_notifyPreAuthStatus (pAdmCtrl, RSN_PRE_AUTH_START);
1836    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  PMKID Candidate List with %d entries has been built and sent for ssid  \n", candIndex);
1837    return;
1838}
1839
1840/**
1841*
1842* admCtrlWpa2_getPreAuthStatus
1843*
1844* \b Description:
1845*
1846* Returns the status of the Pre Auth for the BSSID. If the authentictaion mode
1847 * is not WPA2, then TI_FALSE will be returned.
1848 * For WPA2 mode, if PMKID exists fro the BSSID and its liftime is valid
1849 * TI_TRUE will be returned.
1850 * Otherwise TI_FALSE.
1851*
1852*
1853*
1854* \b ARGS:
1855*  I   - pAdmCtrl - pointer to admCtrl context
1856 * I   - givenAP  - required BSSID
1857*
1858* \b RETURNS:
1859*
1860* TI_OK on success, TI_NOK on failure.
1861*
1862* \sa
1863*/
1864static TI_BOOL admCtrlWpa2_getPreAuthStatus(admCtrl_t *pAdmCtrl, TMacAddr *givenAP, TI_UINT8  *cacheIndex)
1865{
1866    pmkidValue_t    PMKID;
1867
1868    if (admCtrlWpa2_findPMKID (pAdmCtrl, givenAP,
1869                                 &PMKID, cacheIndex)!=TI_OK)
1870    {
1871        return TI_FALSE;
1872    }
1873    return TI_TRUE;
1874
1875}
1876
1877static TI_STATUS admCtrlWpa2_startPreAuth(admCtrl_t *pAdmCtrl, TBssidList4PreAuth *pBssidList)
1878{
1879
1880    admCtrlWpa2_buildAndSendPMKIDCandList (pAdmCtrl, pBssidList);
1881    return TI_OK;
1882}
1883
1884static TI_STATUS admCtrlWpa2_get802_1x_AkmExists (admCtrl_t *pAdmCtrl, TI_BOOL *wpa_802_1x_AkmExists)
1885{
1886    *wpa_802_1x_AkmExists = pAdmCtrl->wpaAkmExists;
1887    return TI_OK;
1888}
1889
1890
1891
1892/*-----------------------------------------------------------------------------
1893Routine Name: admCtrlWpa2_preAuthTimerExpire
1894Routine Description: updates the preAuthStatus
1895Arguments:
1896Return Value:
1897-----------------------------------------------------------------------------*/
1898void admCtrlWpa2_preAuthTimerExpire(TI_HANDLE hAdmCtrl, TI_BOOL bTwdInitOccured)
1899{
1900    admCtrl_t         *pAdmCtrl = (admCtrl_t *)hAdmCtrl;
1901    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_WARNING , "admCtrlWpa2_preAuthTimerExpire: PREAUTH EXPIRED !!!!!!!!");
1902    /* Send PRE-AUTH end event to External Application */
1903    admCtrl_notifyPreAuthStatus (pAdmCtrl, RSN_PRE_AUTH_END);
1904    pAdmCtrl->numberOfPreAuthCandidates = 0;
1905   return;
1906}
1907
1908