1/*
2 * admCtrlWpa2.c
3 *
4 * Copyright(c) 1998 - 2010 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];
572
573            if (admCtrlXCC_getCckmAkm(pAdmCtrl, akmSuite))
574            {
575                os_memoryCopy(pAdmCtrl->hOs, (void*)pWpa2IePacket->authKeyMngSuite, akmSuite, DOT11_OUI_LEN);
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    {
664        return TI_NOK;
665    }
666
667    if (pRsnData->pIe==NULL)
668    {
669        /* configure the MLME module with the 802.11 OPEN authentication suite,
670            THe MLME will configure later the authentication module */
671        pParam->paramType = MLME_LEGACY_TYPE_PARAM;
672        pParam->content.mlmeLegacyAuthType = AUTH_LEGACY_OPEN_SYSTEM;
673        status = mlme_setParam(pAdmCtrl->hMlme, pParam);
674        goto adm_ctrl_wpa2_end;
675    }
676
677#ifdef XCC_MODULE_INCLUDED
678    /* Clean MIC and KP flags in the HAL.                */
679    /* It is needed if the previous privacy mode was XCC */
680    tTwdParam.paramType = TWD_RSN_XCC_SW_ENC_ENABLE_PARAM_ID;
681    tTwdParam.content.rsnXCCSwEncFlag = TI_FALSE;
682    status = TWD_SetParam (pAdmCtrl->pRsn->hTWD, &tTwdParam);
683
684    tTwdParam.paramType = TWD_RSN_XCC_MIC_FIELD_ENABLE_PARAM_ID;
685    tTwdParam.content.rsnXCCMicFieldFlag = TI_FALSE;
686    status = TWD_SetParam (pAdmCtrl->pRsn->hTWD, &tTwdParam);
687
688    /* Check if Aironet IE exists */
689    admCtrlXCC_setExtendedParams(pAdmCtrl, pRsnData);
690
691#endif /*XCC_MODULE_INCLUDED*/
692
693    status = admCtrl_parseIe(pAdmCtrl, pRsnData, &pWpa2Ie, RSN_IE_ID);
694    if (status != TI_OK)
695    {
696        goto adm_ctrl_wpa2_end;
697    }
698    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_setSite: RSN_IE=\n");
699    TRACE_INFO_HEX(pAdmCtrl->hReport, pRsnData->pIe, pRsnData->ieLen);
700    status = admCtrlWpa2_parseIe(pAdmCtrl, pWpa2Ie, &wpa2Data);
701    if (status != TI_OK)
702    {
703        goto adm_ctrl_wpa2_end;
704    }
705    if ((wpa2Data.unicastSuite[0]>=MAX_WPA2_CIPHER_SUITE) ||
706        (wpa2Data.broadcastSuite>=MAX_WPA2_CIPHER_SUITE) ||
707        (pAdmCtrl->unicastSuite>=MAX_WPA2_CIPHER_SUITE))
708    {
709        status = TI_NOK;
710        goto adm_ctrl_wpa2_end;
711    }
712    /* Check validity of Group suite */
713    if (!broadcastCipherSuiteValidity[pAdmCtrl->networkMode][wpa2Data.broadcastSuite])
714    {   /* check Group suite validity */
715        status = TI_NOK;
716        goto adm_ctrl_wpa2_end;
717    }
718
719    status = admCtrlWpa2_getCipherSuiteMetric (pAdmCtrl, &wpa2Data, NULL, &uSuite, &bSuite);
720    if (status != TI_OK)
721        goto adm_ctrl_wpa2_end;
722
723    /* set replay counter */
724    pAdmCtrl->replayCnt = wpa2Data.ptkReplayCounters;
725
726    *pAssocIeLen = pRsnData->ieLen;
727    if (pAssocIe != NULL)
728    {
729        os_memoryCopy(pAdmCtrl->hOs, pAssocIe, &wpa2Data, sizeof(wpa2IeData_t));
730    }
731
732    /* re-config PAE with updated unicast and broadcast suite values            */
733    /* If STA works in WpaMixed mode/AnyWpa mode, set PAE auth. mode to WPA2    */
734    paeConfig.authProtocol = pAdmCtrl->externalAuthMode;
735
736    if(pAdmCtrl->WPAPromoteFlags)
737    {
738       if(pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA)
739          paeConfig.authProtocol   = RSN_EXT_AUTH_MODE_WPA2;
740       if(pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPAPSK)
741          paeConfig.authProtocol   = RSN_EXT_AUTH_MODE_WPA2PSK;
742    }
743
744#ifdef XCC_MODULE_INCLUDED
745    pParam->paramType = XCC_CCKM_EXISTS;
746    pParam->content.XCCCckmExists = (wpa2Data.KeyMngSuite[0]==WPA2_IE_KEY_MNG_CCKM) ? TI_TRUE : TI_FALSE;
747    XCCMngr_setParam(pAdmCtrl->hXCCMngr, pParam);
748#endif
749
750    paeConfig.keyExchangeProtocol = pAdmCtrl->keyMngSuite;
751    paeConfig.unicastSuite        = uSuite;    /* Updated value */
752    paeConfig.broadcastSuite      = bSuite;    /* Updated value */
753    status = admCtrlWpa2_DynamicConfig(pAdmCtrl, &paeConfig);
754
755    if (status != TI_OK)
756    {
757        goto adm_ctrl_wpa2_end;
758    }
759
760    /* Now we configure the MLME module with the 802.11 legacy authentication suite,
761        THe MLME will configure later the authentication module */
762    pParam->paramType = MLME_LEGACY_TYPE_PARAM;
763#ifdef XCC_MODULE_INCLUDED
764    if (pAdmCtrl->networkEapMode!=OS_XCC_NETWORK_EAP_OFF)
765    {
766        pParam->content.mlmeLegacyAuthType = AUTH_LEGACY_RESERVED1;
767    }
768    else
769#endif
770    {
771        pParam->content.mlmeLegacyAuthType = AUTH_LEGACY_OPEN_SYSTEM;
772    }
773    status = mlme_setParam(pAdmCtrl->hMlme, pParam);
774    if (status != TI_OK)
775    {
776        goto adm_ctrl_wpa2_end;
777    }
778
779    pParam->paramType = RX_DATA_EAPOL_DESTINATION_PARAM;
780    pParam->content.rxDataEapolDestination = OS_ABS_LAYER;
781    status = rxData_setParam(pAdmCtrl->hRx, pParam);
782    if (status != TI_OK)
783    {
784        goto adm_ctrl_wpa2_end;
785    }
786
787    /* Configure privacy status in HAL so that HW is prepared to recieve keys */
788    tTwdParam.paramType = TWD_RSN_SECURITY_MODE_PARAM_ID;
789    tTwdParam.content.rsnEncryptionStatus = (ECipherSuite)paeConfig.unicastSuite;
790    status = TWD_SetParam(pAdmCtrl->pRsn->hTWD, &tTwdParam);
791adm_ctrl_wpa2_end:
792    os_memoryFree(pAdmCtrl->hOs, pParam, sizeof(paramInfo_t));
793    return status;
794}
795
796/**
797*
798* admCtrlWpa_evalSite  - Evaluate site for registration.
799*
800* \b Description:
801*
802* evaluate site RSN capabilities against the station's cap.
803* If the BSS type is infrastructure, the station matches the site only if it's WEP status is same as the site
804* In IBSS, it does not matter
805*
806* \b ARGS:
807*
808*  I   - pAdmCtrl - Context \n
809*  I   - pRsnData - site's RSN data \n
810*  O   - pEvaluation - Result of evaluation \n
811*
812* \b RETURNS:
813*
814*  TI_OK
815*
816* \sa
817*/
818TI_STATUS admCtrlWpa2_evalSite(admCtrl_t *pAdmCtrl, TRsnData *pRsnData, TRsnSiteParams *pRsnSiteParams, TI_UINT32 *pEvaluation)
819{
820    TI_STATUS               status;
821    wpa2IeData_t            wpa2Data;
822    TI_UINT8                *pWpa2Ie;
823    ECipherSuite            uSuite, bSuite;
824    TI_UINT8                i = 0;
825    TIWLN_SIMPLE_CONFIG_MODE  wscMode = TIWLN_SIMPLE_CONFIG_OFF;
826
827    *pEvaluation = 0;
828
829    if (pRsnData==NULL)
830    {
831        return TI_NOK;
832    }
833    if (pRsnData->pIe==NULL)
834    {
835        return TI_NOK;
836    }
837
838    if (pRsnSiteParams->bssType != BSS_INFRASTRUCTURE)
839    {
840        return TI_NOK;
841    }
842
843    /* Get Simple-Config state */
844    siteMgr_getParamWSC(pAdmCtrl->pRsn->hSiteMgr, &wscMode); /* SITE_MGR_SIMPLE_CONFIG_MODE */
845    status = admCtrl_parseIe(pAdmCtrl, pRsnData, &pWpa2Ie, RSN_IE_ID);
846    if (status != TI_OK)
847    {
848        return status;
849    }
850    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_evalSite, IE=\n");
851
852    TRACE_INFO_HEX(pAdmCtrl->hReport, pRsnData->pIe, pRsnData->ieLen);
853
854    status = admCtrlWpa2_parseIe(pAdmCtrl, pWpa2Ie, &wpa2Data);
855    if (status != TI_OK)
856    {
857        return status;
858    }
859
860	/* check keyMngSuite validity */
861    status = TI_NOK;
862    for(i = 0;
863       (i < wpa2Data.KeyMngSuiteCnt) &&(i<MAX_WPA2_KEY_MNG_SUITES)&& (status != TI_OK);
864        i++)
865    {
866    	switch (wpa2Data.KeyMngSuite[i])
867       	{
868          	case WPA2_IE_KEY_MNG_NONE:
869            	status = (pAdmCtrl->externalAuthMode <= RSN_EXT_AUTH_MODE_AUTO_SWITCH) ? TI_OK : TI_NOK;
870              	break;
871          	case WPA2_IE_KEY_MNG_801_1X:
872#ifdef XCC_MODULE_INCLUDED
873			/* CCKM is allowed only in 802.1x auth */
874          	case WPA2_IE_KEY_MNG_CCKM:
875#endif
876
877            	if(!pAdmCtrl->WPAPromoteFlags)
878               		status = (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2) ? TI_OK : TI_NOK;
879              	else
880                 	/* Any-WPA mode is supported */
881                 	status = ((pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2) ||
882                        (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA)) ? TI_OK : TI_NOK;
883              	break;
884          	case WPA2_IE_KEY_MNG_PSK_801_1X:
885				if(!pAdmCtrl->WPAPromoteFlags)
886                	status = (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2PSK) ? TI_OK : TI_NOK;
887             	else
888             		/* Any-WPA mode is supported */
889                	status = ((pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2PSK) ||
890                				(wscMode && (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA)) ||
891                    			(pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPAPSK)) ? TI_OK : TI_NOK;
892
893				if ((status == TI_NOK) && (wpa2Data.KeyMngSuiteCnt > 1) && (wpa2Data.KeyMngSuite[1] == WPA2_IE_KEY_MNG_801_1X) && (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA2))
894                {
895                TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Overriding AKM suite evaluation for simple-config\n");
896                    status = TI_OK;
897				}
898				break;
899       		default:
900           TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "admCtrlWpa2_evalSite, default, wpa2Data.KeyMngSuite[i]=%d \n",wpa2Data.KeyMngSuite[i]);
901             	status = TI_NOK;
902             	break;
903       	}
904    }
905
906    if (status != TI_OK)
907    {
908        TRACE3(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "admCtrlWpa2_evalSite, status=%d, externalAuthMode=%d, WPAPromoteFlags=%d \n", status, pAdmCtrl->externalAuthMode, pAdmCtrl->WPAPromoteFlags);
909        return status;
910    }
911
912    /* Check cipher suite validity */
913    if(admCtrlWpa2_getCipherSuiteMetric(pAdmCtrl, &wpa2Data, pEvaluation, &uSuite, &bSuite) != TI_OK)
914        return TI_NOK;
915
916    /* Check privacy bit if not in mixed mode */
917    if (!pAdmCtrl->mixedMode)
918    {   /* There's no mixed mode, so make sure that the privacy Bit matches the privacy mode*/
919        if (((pRsnData->privacy) && (uSuite == TWD_CIPHER_NONE)) ||
920            ((!pRsnData->privacy) && (uSuite > TWD_CIPHER_NONE)))
921        {
922            *pEvaluation = 0;
923            TRACE2(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_evalSite, mixedMode is TI_FALSE, privacy=%d, uSuite=%d\n", pRsnData->privacy, uSuite);
924            return TI_NOK;
925        }
926    }
927
928    /* always return TI_OK */
929    return TI_OK;
930}
931
932
933/**
934*
935* admCtrlWpa2_parseIe  - Parse an WPA information element.
936*
937* \b Description:
938*
939* Parse an WPA information element.
940* Builds a structure of the unicast adn broadcast cihper suites,
941* the key management suite and the capabilities.
942*
943* \b ARGS:
944*
945*  I   - pAdmCtrl - pointer to admCtrl context
946*  I   - pWpa2Ie  - pointer to WPA IE (RSN IE) buffer  \n
947*  O   - pWpa2Data - WPA2 IE (RSN IE) structure after parsing
948*
949*
950* \b RETURNS:
951*
952* TI_OK on success, TI_NOK on failure.
953*
954* \sa
955*/
956TI_STATUS admCtrlWpa2_parseIe(admCtrl_t *pAdmCtrl, TI_UINT8 *pWpa2Ie, wpa2IeData_t *pWpa2Data)
957{
958    dot11_RSN_t      *wpa2Ie       =  (dot11_RSN_t *)pWpa2Ie;
959    TI_UINT16            temp2bytes =0, capabilities;
960    TI_UINT8             dataOffset = 0, i = 0, j = 0, curKeyMngSuite = 0;
961    ECipherSuite     curCipherSuite = TWD_CIPHER_NONE;
962
963    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: DEBUG: admCtrlWpa2_parseIe\n\n");
964
965    if ((pWpa2Data == NULL) || (pWpa2Ie == NULL))
966    {
967        return TI_NOK;
968    }
969
970    COPY_WLAN_WORD(&temp2bytes, wpa2Ie->rsnIeData);
971    dataOffset += 2;
972
973    /* Check the header fields and the version */
974    if((wpa2Ie->hdr[0] != RSN_IE_ID) || (wpa2Ie->hdr[1] < WPA2_IE_MIN_LENGTH) ||
975       (temp2bytes != WPA2_OUI_MAX_VERSION))
976    {
977        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);
978
979        return TI_NOK;
980    }
981
982
983    /* Set default values */
984    os_memoryZero(pAdmCtrl->hOs, pWpa2Data, sizeof(wpa2IeData_t));
985
986    pWpa2Data->broadcastSuite = TWD_CIPHER_AES_CCMP;
987    pWpa2Data->unicastSuiteCnt = 1;
988    pWpa2Data->unicastSuite[0] = TWD_CIPHER_AES_CCMP;
989    pWpa2Data->KeyMngSuiteCnt = 1;
990    pWpa2Data->KeyMngSuite[0] = WPA2_IE_KEY_MNG_801_1X;
991
992    /* If we've reached the end of the received RSN IE */
993    if(wpa2Ie->hdr[1] < WPA2_IE_GROUP_SUITE_LENGTH)
994        return TI_OK;
995
996    /* Processing of Group Suite field - 4 bytes*/
997    pWpa2Data->broadcastSuite = (ECipherSuite)admCtrlWpa2_parseSuiteVal(pAdmCtrl, (TI_UINT8 *)wpa2Ie->rsnIeData + dataOffset,
998                                                          TWD_CIPHER_WEP104, TWD_CIPHER_UNKNOWN);
999    dataOffset +=4;
1000    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: GroupSuite %x \n", pWpa2Data->broadcastSuite);
1001
1002
1003    /* Processing of Pairwise (Unicast) Cipher Suite - 2 bytes counter and list of 4-byte entries */
1004    if(wpa2Ie->hdr[1] < WPA2_IE_MIN_PAIRWISE_SUITE_LENGTH)
1005        return TI_OK;
1006
1007    COPY_WLAN_WORD(&pWpa2Data->unicastSuiteCnt, wpa2Ie->rsnIeData + dataOffset);
1008    dataOffset += 2;
1009
1010    if(pWpa2Data->unicastSuiteCnt > UNICAST_CIPHER_MAXNO_IN_RSNIE)
1011    {
1012        /* something wrong in the RSN IE */
1013        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "Wpa2_ParseIe Error: Pairwise cipher suite count is  %d \n", pWpa2Data->unicastSuiteCnt);
1014        return TI_NOK;
1015    }
1016
1017    /* Get unicast cipher suites */
1018    for(i = 0; i < pWpa2Data->unicastSuiteCnt; i++)
1019    {
1020        curCipherSuite = (ECipherSuite)admCtrlWpa2_parseSuiteVal(pAdmCtrl, (TI_UINT8 *)wpa2Ie->rsnIeData + dataOffset,
1021                                                   TWD_CIPHER_WEP104, TWD_CIPHER_UNKNOWN);
1022        if(curCipherSuite == TWD_CIPHER_NONE)
1023            curCipherSuite = pWpa2Data->broadcastSuite;
1024
1025        pWpa2Data->unicastSuite[i] = curCipherSuite;
1026        dataOffset +=4;
1027
1028        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa_IE: unicast suite %x \n", curCipherSuite);
1029    }
1030
1031    /* Sort all the unicast suites supported by the AP in the decreasing order */
1032    /* (so the best cipher suite will be the first)                            */
1033    if(pWpa2Data->unicastSuiteCnt > 1)
1034    {
1035       for(i = 0; i < (pWpa2Data->unicastSuiteCnt -1); i ++)
1036       {
1037           for(j = 0; j < i; j ++)
1038           {
1039               if(pWpa2Data->unicastSuite[j] > pWpa2Data->unicastSuite[j + 1])
1040               {
1041                   curCipherSuite               = pWpa2Data->unicastSuite[j];
1042                   pWpa2Data->unicastSuite[j]   = pWpa2Data->unicastSuite[j+1];
1043                   pWpa2Data->unicastSuite[j+1] = curCipherSuite;
1044               }
1045           }
1046       }
1047    }
1048
1049    /* If we've reached the end of the received RSN IE */
1050    if (wpa2Ie->hdr[1] == dataOffset)
1051        return TI_OK;
1052
1053     /* KeyMng Suite */
1054    COPY_WLAN_WORD(&(pWpa2Data->KeyMngSuiteCnt), wpa2Ie->rsnIeData + dataOffset);
1055
1056     dataOffset += 2;
1057     pAdmCtrl->wpaAkmExists = TI_FALSE;
1058     for(i = 0; i < pWpa2Data->KeyMngSuiteCnt; i++)
1059     {
1060#ifdef XCC_MODULE_INCLUDED
1061            curKeyMngSuite = admCtrlXCC_parseCckmSuiteVal4Wpa2(pAdmCtrl, (TI_UINT8 *)(wpa2Ie->rsnIeData + dataOffset));
1062            if (curKeyMngSuite == WPA2_IE_KEY_MNG_CCKM)
1063            {  /* CCKM is the maximum AKM */
1064                pWpa2Data->KeyMngSuite[i] = curKeyMngSuite;
1065            }
1066            else
1067#endif
1068            {
1069                curKeyMngSuite = admCtrlWpa2_parseSuiteVal(pAdmCtrl, (TI_UINT8 *)wpa2Ie->rsnIeData + dataOffset,
1070                            WPA2_IE_KEY_MNG_PSK_801_1X, WPA2_IE_KEY_MNG_NA);
1071            }
1072
1073
1074        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "Wpa2_IE: authKeyMng %x  \n", curKeyMngSuite);
1075
1076         if ((curKeyMngSuite != WPA2_IE_KEY_MNG_NA) &&
1077             (curKeyMngSuite != WPA2_IE_KEY_MNG_CCKM))
1078         {
1079             pWpa2Data->KeyMngSuite[i] = curKeyMngSuite;
1080         }
1081
1082         if (curKeyMngSuite==WPA2_IE_KEY_MNG_801_1X)
1083         {   /* If 2 AKM exist, save also the second priority */
1084             pAdmCtrl->wpaAkmExists = TI_TRUE;
1085         }
1086
1087         dataOffset += 4;
1088
1089		 /* Include all AP key management supported suites in the wpaData structure */
1090            pWpa2Data->KeyMngSuite[i+1] = curKeyMngSuite;
1091     }
1092
1093    /* If we've reached the end of the received RSN IE */
1094    if (wpa2Ie->hdr[1] == dataOffset)
1095        return TI_OK;
1096
1097    /* Parse capabilities */
1098    COPY_WLAN_WORD(&capabilities, wpa2Ie->rsnIeData + dataOffset);
1099    pWpa2Data->bcastForUnicatst  = (TI_UINT8)(capabilities & WPA2_GROUP_4_UNICAST_CAPABILITY_MASK)>>
1100                                           WPA2_GROUP_4_UNICAST_CAPABILITY_SHIFT;
1101    pWpa2Data->ptkReplayCounters = (TI_UINT8)(capabilities &  WPA2_PTK_REPLAY_COUNTERS_CAPABILITY_MASK)>>
1102                                           WPA2_PTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1103
1104    switch (pWpa2Data->ptkReplayCounters)
1105    {
1106    case 0: pWpa2Data->ptkReplayCounters=1;
1107            break;
1108    case 1: pWpa2Data->ptkReplayCounters=2;
1109            break;
1110    case 2: pWpa2Data->ptkReplayCounters=4;
1111            break;
1112    case 3: pWpa2Data->ptkReplayCounters=16;
1113            break;
1114    default: pWpa2Data->ptkReplayCounters=1;
1115            break;
1116   }
1117   pWpa2Data->gtkReplayCounters = (TI_UINT8)(capabilities &
1118                                        WPA2_GTK_REPLAY_COUNTERS_CAPABILITY_MASK) >>
1119                                        WPA2_GTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1120   switch (pWpa2Data->gtkReplayCounters)
1121   {
1122   case 0: pWpa2Data->gtkReplayCounters=1;
1123            break;
1124   case 1: pWpa2Data->gtkReplayCounters=2;
1125            break;
1126   case 2: pWpa2Data->gtkReplayCounters=4;
1127            break;
1128   case 3: pWpa2Data->gtkReplayCounters=16;
1129            break;
1130   default: pWpa2Data->gtkReplayCounters=1;
1131            break;
1132   }
1133
1134   pWpa2Data->preAuthentication = (TI_UINT8)(capabilities & WPA2_PRE_AUTH_CAPABILITY_MASK);
1135
1136   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);
1137
1138    return TI_OK;
1139
1140}
1141
1142
1143TI_UINT16 admCtrlWpa2_buildCapabilities(admCtrl_t *pAdmCtrl)
1144{
1145   TI_UINT16 capabilities = 0;
1146   TI_UINT16 replayCnt;
1147
1148
1149   /* Bit 0 - Pre-authentication is set to 0             */
1150   /* when RSN IE is sent from a STA (in assoc request)  */
1151
1152   /* Bit1: group key for unicast is set to 0*/
1153
1154   /* Bits 2&3: PTKSA Replay counter; bits 4&5 GTKSA replay Counters */
1155   switch (pAdmCtrl->replayCnt)
1156   {
1157   case 1:  replayCnt=0;
1158       break;
1159   case 2:  replayCnt=1;
1160       break;
1161   case 4:  replayCnt=2;
1162       break;
1163   case 16: replayCnt=3;
1164       break;
1165   default: replayCnt=0;
1166       break;
1167   }
1168
1169   capabilities |= replayCnt << WPA2_PTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1170   capabilities |= replayCnt << WPA2_GTK_REPLAY_COUNTERS_CAPABILITY_SHIFT;
1171
1172   return   capabilities;
1173
1174}
1175
1176
1177TI_UINT32  admCtrlWpa2_parseSuiteVal(admCtrl_t *pAdmCtrl, TI_UINT8* suiteVal, TI_UINT32 maxVal, TI_UINT32 unknownVal)
1178{
1179    TI_UINT32  suite;
1180
1181    if ((pAdmCtrl==NULL) || (suiteVal==NULL))
1182    {
1183        return TWD_CIPHER_UNKNOWN;
1184    }
1185    if (!os_memoryCompare(pAdmCtrl->hOs, suiteVal, wpa2IeOuiIe, 3))
1186    {
1187        suite =  (ECipherSuite)((suiteVal[3]<=maxVal) ? suiteVal[3] : unknownVal);
1188    } else
1189    {
1190        suite = unknownVal;
1191    }
1192    return  suite;
1193
1194}
1195
1196
1197TI_STATUS admCtrlWpa2_checkCipherSuiteValidity (ECipherSuite unicastSuite, ECipherSuite broadcastSuite, ECipherSuite encryptionStatus)
1198{
1199    ECipherSuite maxCipher;
1200
1201    maxCipher = (unicastSuite>=broadcastSuite) ? unicastSuite : broadcastSuite ;
1202    if (maxCipher != encryptionStatus)
1203    {
1204        return TI_NOK;
1205    }
1206    if ((unicastSuite != TWD_CIPHER_NONE) && (broadcastSuite>unicastSuite))
1207    {
1208        return TI_NOK;
1209    }
1210    return TI_OK;
1211}
1212
1213TI_STATUS admCtrlWpa2_getCipherSuiteMetric (admCtrl_t *pAdmCtrl, wpa2IeData_t *pWpa2Data, TI_UINT32 *metric,
1214                                            ECipherSuite *uSuite, ECipherSuite  *bSuite)
1215{
1216   ECipherSuite   encryption   = TWD_CIPHER_NONE;
1217   ECipherSuite   unicastSuite = TWD_CIPHER_NONE, brdcstSuite = TWD_CIPHER_NONE;
1218   admCtrlWpa2_validity_t  admCtrlWpa2_validity;
1219   TI_UINT32     maxMetric = 0, index = 0;
1220   TI_STATUS  status = TI_NOK;
1221
1222   /* Set admCtrlWpa2_validity initial values */
1223   admCtrlWpa2_validity = admCtrlWpa2_validityTable[TWD_CIPHER_NONE][TWD_CIPHER_NONE][TWD_CIPHER_NONE];
1224
1225   /* Check validity of configured encryption (cipher) and validity of */
1226   /* promoted cipher (in case of AnyWPA (WPAmixed mode))              */
1227   pAdmCtrl->getCipherSuite(pAdmCtrl, &encryption);
1228   TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_getCipherSuiteMetric, encryption=%d\n", encryption);
1229
1230   while(encryption != TWD_CIPHER_NONE)
1231   {
1232      for (index=0; index<pWpa2Data->unicastSuiteCnt; index++)
1233      {
1234          admCtrlWpa2_validity =
1235          admCtrlWpa2_validityTable[pWpa2Data->unicastSuite[index]][pWpa2Data->broadcastSuite][encryption];
1236          if (admCtrlWpa2_validity.status == TI_OK)
1237          {
1238              TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_getCipherSuiteMetric, break: validity.evaluation=%d\n", admCtrlWpa2_validity.evaluation);
1239              break;
1240          }
1241      }
1242
1243      if ((admCtrlWpa2_validity.status == TI_OK) && (admCtrlWpa2_validity.evaluation > maxMetric))
1244      {
1245          TRACE2(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_getCipherSuiteMetric, validity.evaluation=%d, maxMetric=%d\n", admCtrlWpa2_validity.evaluation, maxMetric);
1246
1247          maxMetric       = admCtrlWpa2_validity.evaluation;
1248          status          = admCtrlWpa2_validity.status;
1249          unicastSuite    = admCtrlWpa2_validity.unicast;
1250          brdcstSuite     = admCtrlWpa2_validity.broadcast;
1251      }
1252
1253      if((pAdmCtrl->WPAPromoteFlags & ADMCTRL_WPA_OPTION_ENABLE_PROMOTE_CIPHER) &&
1254         (encryption != TWD_CIPHER_AES_CCMP))
1255         encryption = TWD_CIPHER_AES_CCMP;
1256      else
1257         encryption = TWD_CIPHER_NONE;
1258
1259    }  /* End of "while encryption" stmt */
1260
1261   if(metric)
1262      *metric = maxMetric;
1263
1264   if(uSuite)
1265      *uSuite = unicastSuite;
1266
1267   if(bSuite)
1268      *bSuite = brdcstSuite;
1269
1270    return status;
1271}
1272
1273
1274/**
1275*
1276* admCtrlWpa2_DynamicConfig  - Dynamic setting of WPA2 config parameters.
1277*
1278* \b Description:
1279*
1280*   Sets  WPA2 callback procedures and PAE configuration parameters.
1281*   This procedure is similar to admCtrlWpa2_Config procedure.
1282*   The main difference is that admCtrlWpa2_Config sets the DEFAULT VALUES
1283*   of the configuration parameters and so it should be called during
1284*   initialization of the driver code or when Auth mode or Encryption status
1285*   parameters are beeing set.
1286*   admCtrlWpa2_DynamicConfig set the updated values of WPA2 configuration
1287*   parameters which gets after negotiation with an AP. So the procedure
1288*   should be called during setSite stage.
1289*
1290* \b ARGS:
1291*
1292*  I   - pAdmCtrl    - pointer to admCtrl context
1293*  I   - pPaeConfig  - pointer to PAE structure
1294*
1295* \b RETURNS:
1296*
1297* TI_OK on success, TI_NOK on failure.
1298*
1299* \sa
1300*/
1301
1302TI_STATUS admCtrlWpa2_DynamicConfig(admCtrl_t *pAdmCtrl, TRsnPaeConfig *pPaeConfig)
1303{
1304    TI_STATUS status = TI_OK;
1305
1306    /* Set those WPA2 params and callback procedures used after setSite stage */
1307    pAdmCtrl->getInfoElement = admCtrlWpa2_getInfoElement;
1308
1309    pAdmCtrl->getPmkidList      = admCtrlWpa2_getPMKIDList;
1310    pAdmCtrl->setPmkidList      = admCtrlWpa2_setPMKIDList;
1311    pAdmCtrl->resetPmkidList    = admCtrlWpa2_resetPMKIDCache;
1312    pAdmCtrl->getPreAuthStatus = admCtrlWpa2_getPreAuthStatus;
1313    pAdmCtrl->startPreAuth = admCtrlWpa2_startPreAuth;
1314
1315    /* set key management suite */
1316    switch (pAdmCtrl->externalAuthMode)
1317    {
1318    case RSN_EXT_AUTH_MODE_WPA2:
1319    case RSN_EXT_AUTH_MODE_WPA2PSK:
1320        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_802_1X;
1321        break;
1322    case RSN_EXT_AUTH_MODE_WPA:  /* It is any-WPA (WPA-mixed mode ) */
1323    case RSN_EXT_AUTH_MODE_WPAPSK:
1324        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_802_1X;
1325        break;
1326    case RSN_EXT_AUTH_MODE_WPANONE:
1327        pAdmCtrl->keyMngSuite = RSN_KEY_MNG_NONE;
1328        /* Not supported */
1329    default:
1330        return TI_NOK;
1331    }
1332
1333    /* Config PAE (if needed) */
1334    if(pPaeConfig)
1335       status = pAdmCtrl->pRsn->setPaeConfig(pAdmCtrl->pRsn, pPaeConfig);
1336
1337    return status;
1338}
1339
1340
1341
1342
1343/**
1344*
1345* admCtrlWpa2_findPMKID
1346*
1347* \b Description:
1348*
1349* Retrieve an AP's PMKID (if exist)
1350
1351* \b ARGS:
1352*
1353*  I   - pAdmCtrl - pointer to admCtrl context
1354*  I   - pBSSID   - pointer to AP's BSSID address
1355*  O   - pmkID    - pointer to AP's PMKID (if it is NULL ptr, only
1356*                   cache index will be returned to the caller)
1357*  O   - cacheIndex  - index of the cache table entry containing the
1358                       bssid
1359*
1360* \b RETURNS:
1361*
1362* TI_OK on success, TI_NOK on failure.
1363*
1364* \sa
1365*/
1366TI_STATUS admCtrlWpa2_findPMKID (admCtrl_t * pAdmCtrl, TMacAddr *pBSSID,
1367                                 pmkidValue_t *pPMKID, TI_UINT8  *cacheIndex)
1368{
1369
1370    TI_UINT8           i     = 0;
1371    TI_BOOL            found = TI_FALSE;
1372    TMacAddr    entryMac;
1373    TI_STATUS       status = TI_NOK;
1374
1375    while(!found && (i < ADMCTRL_PMKID_CACHE_SIZE) &&
1376                    (i <= pAdmCtrl->pmkid_cache.entriesNumber))
1377    {
1378		MAC_COPY (entryMac, pAdmCtrl->pmkid_cache.pmkidTbl[i].bssId);
1379        if (MAC_EQUAL (entryMac, *pBSSID))
1380        {
1381            found       = TI_TRUE;
1382            *cacheIndex = i;
1383            if(pPMKID)
1384            {
1385               os_memoryCopy(pAdmCtrl->hOs, (void*)pPMKID,
1386                             pAdmCtrl->pmkid_cache.pmkidTbl[i].pmkId,
1387                             PMKID_VALUE_SIZE);
1388            }
1389        }
1390        i++;
1391    }
1392
1393    if(found)
1394        status = TI_OK;
1395
1396    return status;
1397
1398}
1399
1400
1401/**
1402*
1403* admCtrlWpa2_getPMKIDList
1404*
1405* \b Description:
1406*
1407* Returns content of the PMKID cache
1408*
1409* \b ARGS:
1410*
1411*  I   - pAdmCtrl        - pointer to admCtrl context
1412*  O   - pmkidList       - memory buffer where the procedure writes the PMKIDs
1413*                          Supplied by the caller procedure. .
1414*
1415* \b RETURNS:
1416*
1417* TI_OK on success, TI_NOK on failure.
1418*
1419* \sa
1420*/
1421TI_STATUS admCtrlWpa2_getPMKIDList (admCtrl_t * pAdmCtrl,OS_802_11_PMKID *pmkidList)
1422{
1423
1424    TI_UINT8   neededLength, i = 0;
1425    TI_UINT8   NumOfEntries = pAdmCtrl->pmkid_cache.entriesNumber;
1426    TI_UINT8   *bssid, *pmkid;
1427
1428    if(!pAdmCtrl->preAuthSupport)
1429        return PARAM_NOT_SUPPORTED;
1430
1431    /* Check the buffer length */
1432    if(NumOfEntries > 1)
1433       neededLength = 30 + ((NumOfEntries - 1) * (MAC_ADDR_LEN + PMKID_VALUE_SIZE));
1434    else
1435       neededLength = 30;
1436
1437    if(neededLength > pmkidList->Length)
1438    {
1439        /* The buffer length is not enough */
1440        pmkidList->Length = neededLength;
1441        return TI_NOK;
1442    }
1443
1444    /* The buffer is big enough. Fill the info */
1445    pmkidList->Length         = neededLength;
1446    pmkidList->BSSIDInfoCount = NumOfEntries;
1447
1448    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  Get PMKID cache.  Number of entries  = %d \n", NumOfEntries);
1449
1450    for (i = 0; i < NumOfEntries; i++ )
1451    {
1452        bssid = (TI_UINT8 *) pAdmCtrl->pmkid_cache.pmkidTbl[i].bssId;
1453        pmkid = (TI_UINT8 *)pAdmCtrl->pmkid_cache.pmkidTbl[i].pmkId;
1454
1455        MAC_COPY(pmkidList->osBSSIDInfo[i].BSSID, bssid);
1456
1457        os_memoryCopy(pAdmCtrl->hOs,
1458                      (void *)pmkidList->osBSSIDInfo[i].PMKID,
1459                      &pmkid,
1460                      PMKID_VALUE_SIZE);
1461
1462        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]);
1463    }
1464
1465    return TI_OK;
1466
1467}
1468
1469/**
1470*
1471* admCtrlWpa2_addPMKID
1472*
1473* \b Description:
1474*
1475* Add/Set an AP's PMKID received from the Supplicant
1476*
1477* \b ARGS:
1478*
1479*  I   - pAdmCtrl - pointer to admCtrl context
1480*  I   - pBSSID   - pointer to AP's BSSID address
1481*  I   - pmkID    - AP's PMKID
1482*
1483* \b RETURNS:
1484*
1485* TI_OK on success, TI_NOK on failure.
1486*
1487* \sa
1488*/
1489TI_STATUS admCtrlWpa2_addPMKID (admCtrl_t * pAdmCtrl, TMacAddr *pBSSID, pmkidValue_t pmkID)
1490{
1491   TI_UINT8         cacheIndex;
1492   TI_STATUS     status = TI_NOK;
1493
1494   /* Try to find the pBSSId in the PMKID cache */
1495   status = admCtrlWpa2_findPMKID (pAdmCtrl, pBSSID, NULL, &cacheIndex);
1496
1497   if(status == TI_OK)
1498   {
1499       /* Entry for the bssid has been found; Update PMKID */
1500       os_memoryCopy(pAdmCtrl->hOs,
1501                    (void*)&pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].pmkId,
1502                    pmkID, PMKID_VALUE_SIZE);
1503       /*pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].generationTs = os_timeStampMs(pAdmCtrl->hOs); */
1504   }
1505   else
1506   {
1507       /* The new entry is added to the next free entry. */
1508       /* Copy the new entry to the next free place.     */
1509       cacheIndex = pAdmCtrl->pmkid_cache.nextFreeEntry;
1510       MAC_COPY (pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].bssId, *pBSSID);
1511       os_memoryCopy(pAdmCtrl->hOs,
1512                     (void*)&pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].pmkId,
1513                     (void*)pmkID,
1514                     PMKID_VALUE_SIZE);
1515
1516       /* Update the next free entry index. (If the table is full, a new entry */
1517       /* will override the oldest entries from the beginning of the table)    */
1518       /* Update the number of entries. (it cannot be more than max cach size) */
1519       pAdmCtrl->pmkid_cache.nextFreeEntry  = (cacheIndex + 1) % ADMCTRL_PMKID_CACHE_SIZE;
1520
1521       if(pAdmCtrl->pmkid_cache.entriesNumber < ADMCTRL_PMKID_CACHE_SIZE)
1522          pAdmCtrl->pmkid_cache.entriesNumber ++;
1523   }
1524
1525        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN   Add PMKID   Entry index is %d \n", cacheIndex);
1526        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]);
1527
1528
1529
1530   return TI_OK;
1531}
1532
1533/**
1534*
1535* admCtrlWpa2_setPMKIDList
1536*
1537* \b Description:
1538*
1539* Set PMKID cache
1540*
1541* \b ARGS:
1542*
1543*  I   - pAdmCtrl        - pointer to admCtrl context
1544*  O   - pmkidList       - memory buffer where the procedure reads the PMKIDs from
1545*                          Supplied by the caller procedure.
1546* \b RETURNS:
1547*
1548* TI_OK on success, TI_NOK on failure.
1549*
1550* \sa
1551*/
1552TI_STATUS admCtrlWpa2_setPMKIDList (admCtrl_t * pAdmCtrl, OS_802_11_PMKID *pmkidList)
1553{
1554    TI_UINT8          neededLength, i = 0;
1555    TI_UINT8          NumOfEntries;
1556    TMacAddr   macAddr;
1557
1558    /* Check the minimal buffer length */
1559    if (pmkidList->Length < 2*sizeof(TI_UINT32))
1560    {
1561        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN: Set PMKID list - Buffer size < min length (8 bytes). Supplied length is %d .\n", pmkidList->Length);
1562        return TI_NOK;
1563    }
1564
1565    /* Check the num of entries in the buffer: if 0 it means that */
1566    /* PMKID cache has to be cleaned                              */
1567    if(pmkidList->BSSIDInfoCount == 0)
1568    {
1569        admCtrlWpa2_resetPMKIDCache(pAdmCtrl);
1570        return TI_OK;
1571    }
1572
1573    /* Check the buffer length */
1574    NumOfEntries = (TI_UINT8)pmkidList->BSSIDInfoCount;
1575    neededLength =  2*sizeof(TI_UINT32) + (NumOfEntries  *(MAC_ADDR_LEN + PMKID_VALUE_SIZE));
1576
1577    if(pmkidList->Length < neededLength)
1578    {
1579        /* Something wrong goes with the buffer */
1580        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);
1581        return TI_NOK;
1582    }
1583
1584    /*  Write  the PMKID to the PMKID cashe */
1585    pmkidList->BSSIDInfoCount = NumOfEntries;
1586    for (i = 0; i < NumOfEntries; i++ )
1587    {
1588         MAC_COPY (macAddr, pmkidList->osBSSIDInfo[i].BSSID);
1589
1590         TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_setPMKIDList: Received new pre-auth AP\n");
1591         if (pAdmCtrl->numberOfPreAuthCandidates)
1592         {
1593            pAdmCtrl->numberOfPreAuthCandidates--;
1594            if (pAdmCtrl->numberOfPreAuthCandidates == 0)
1595            {
1596               TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "Stopping the Pre-Auth timer since Pre-auth is finished\n");
1597               tmr_StopTimer (pAdmCtrl->hPreAuthTimerWpa2);
1598               /* Send PRE-AUTH end event to External Application */
1599               admCtrl_notifyPreAuthStatus (pAdmCtrl, RSN_PRE_AUTH_END);
1600            }
1601
1602            TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "admCtrlWpa2_setPMKIDList: %d APs left in candidate list\n",pAdmCtrl->numberOfPreAuthCandidates);
1603
1604         }
1605        else
1606        {
1607           TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_WARNING , "admCtrlWpa2_setPMKIDList: number of candidates was already zero...\n");
1608        }
1609        admCtrlWpa2_addPMKID(pAdmCtrl,&macAddr, (TI_UINT8 *)pmkidList->osBSSIDInfo[i].PMKID);
1610    }
1611
1612    return TI_OK;
1613
1614}
1615
1616/**
1617*
1618* admCtrlWpa2_resetPMKIDCache
1619*
1620* \b Description:
1621*
1622* Reset PMKID Table
1623*
1624* \b ARGS:
1625*
1626*  I   - pAdmCtrl - pointer to admCtrl context
1627*
1628* \b RETURNS:
1629*
1630* TI_OK on success, TI_NOK on failure.
1631*
1632* \sa
1633*/
1634TI_STATUS admCtrlWpa2_resetPMKIDCache (admCtrl_t *pAdmCtrl)
1635{
1636
1637    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  Reset PMKID cache.  %d entries are deleted. \n", pAdmCtrl->pmkid_cache.entriesNumber);
1638
1639   os_memoryZero(pAdmCtrl->hOs, (void*)&pAdmCtrl->pmkid_cache, sizeof(pmkid_cache_t));
1640
1641   return TI_OK;
1642}
1643
1644
1645/**
1646*
1647* admCtrlWpa2_sendPMKIDCandidateListAfterDelay
1648*
1649* \b Description:
1650*
1651* New Candidate List of APs with the same SSID as the STA is connected to
1652* is generated and sent after the delay to the supplicant
1653* in order to retrieve the new PMKIDs for the APs.
1654*
1655* \b ARGS:
1656*  I   - pAdmCtrl - pointer to admCtrl context
1657*
1658* \b RETURNS:
1659*
1660* TI_OK on success, TI_NOK on failure.
1661*
1662* \sa
1663*/
1664
1665static void admCtrlWpa2_buildAndSendPMKIDCandList (TI_HANDLE hHandle, TBssidList4PreAuth *apList)
1666{
1667
1668    admCtrl_t         *pAdmCtrl = (admCtrl_t *)hHandle;
1669    TI_UINT8          candIndex =0, apIndex = 0, size =0;
1670    paramInfo_t       *pParam;
1671    OS_802_11_PMKID_CANDIDATELIST  *pCandList;
1672    TI_UINT8           memBuff[PMKID_CAND_LIST_MEMBUFF_SIZE + sizeof(TI_UINT32)];
1673    dot11_RSN_t       *rsnIE = 0;
1674    wpa2IeData_t      wpa2Data;
1675    TI_STATUS         status = TI_NOK;
1676
1677    pParam = (paramInfo_t *)os_memoryAlloc(pAdmCtrl->hOs, sizeof(paramInfo_t));
1678    if (!pParam)
1679    {
1680        return;
1681    }
1682
1683    /* Get SSID that the STA is accociated with    */
1684    pParam->paramType = SME_DESIRED_SSID_ACT_PARAM;
1685    status          = sme_GetParam (pAdmCtrl->pRsn->hSmeSm, pParam);
1686    if(status != TI_OK) {
1687        os_memoryFree(pAdmCtrl->hOs, pParam, sizeof(paramInfo_t));
1688        return;
1689    }
1690
1691    /* If the existing PMKID cache contains information for not relevant */
1692    /* ssid (i.e. ssid was changed), clean up the PMKID cache and update */
1693    /* the ssid in the PMKID cache */
1694    if ((pAdmCtrl->pmkid_cache.ssid.len != pParam->content.smeDesiredSSID.len) ||
1695         (os_memoryCompare(pAdmCtrl->hOs, (TI_UINT8 *)pAdmCtrl->pmkid_cache.ssid.str,
1696          (TI_UINT8 *)pParam->content.smeDesiredSSID.str,
1697                          pAdmCtrl->pmkid_cache.ssid.len) != 0))
1698    {
1699        admCtrlWpa2_resetPMKIDCache(pAdmCtrl);
1700
1701        os_memoryCopy(pAdmCtrl->hOs, (void *)pAdmCtrl->pmkid_cache.ssid.str,
1702                      (void *)pParam->content.smeDesiredSSID.str,
1703                      pParam->content.siteMgrCurrentSSID.len);
1704        pAdmCtrl->pmkid_cache.ssid.len = pParam->content.smeDesiredSSID.len;
1705    }
1706
1707    /* Get list of APs of the SSID that the STA is associated with*/
1708    /*os_memoryZero(pAdmCtrl->hOs, (void*)&apList, sizeof(bssidListBySsid_t));
1709    status = siteMgr_GetApListBySsid (pAdmCtrl->pRsn->hSiteMgr,
1710                                      &param.content.siteMgrCurrentSSID,
1711                                      &apList);
1712    */
1713    os_memoryFree(pAdmCtrl->hOs, pParam, sizeof(paramInfo_t));
1714    if((apList == NULL) || (apList->NumOfItems == 0))
1715        return;
1716
1717    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList - Entry \n");
1718
1719    /* fill the PMKID candidate list */
1720    pCandList = (OS_802_11_PMKID_CANDIDATELIST *)(memBuff + sizeof(TI_UINT32));
1721    pCandList->Version = 1;
1722    for (apIndex=0; apIndex<pAdmCtrl->pmkid_cache.entriesNumber; apIndex++)
1723    {
1724        pAdmCtrl->pmkid_cache.pmkidTbl[apIndex].preAuthenticate = TI_FALSE;
1725    }
1726
1727    /* Go over AP list and find APs supporting pre-authentication */
1728    for(apIndex = 0; apIndex < apList->NumOfItems; apIndex++)
1729    {
1730        TI_UINT8 *bssidMac, i = 0;
1731
1732        status = TI_NOK;
1733
1734        if (apList->bssidList[apIndex].pRsnIEs==NULL)
1735        {
1736            continue;
1737        }
1738        /* Check is there RSN IE in this site */
1739        rsnIE = 0;
1740        while( !rsnIE && (i < MAX_RSN_IE))
1741        {
1742            if(apList->bssidList[apIndex].pRsnIEs[i].hdr[0] == RSN_IE_ID)
1743            {
1744                rsnIE  = &apList->bssidList[apIndex].pRsnIEs[i];
1745                status = TI_OK;
1746            }
1747            i ++;
1748        }
1749		if (rsnIE)
1750		{
1751			TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList - rsnIE-hdr.eleId = %x \n", rsnIE->hdr[0]);
1752		}
1753
1754        if(status == TI_OK)
1755           status = admCtrlWpa2_parseIe(pAdmCtrl, (TI_UINT8 *)rsnIE, &wpa2Data);
1756
1757        TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList - parseIe status = %d \n", status);
1758        if(status == TI_OK)
1759        {
1760            TI_BOOL        preAuthStatus;
1761            TI_UINT8               cacheIndex;
1762
1763            preAuthStatus = admCtrlWpa2_getPreAuthStatus(pAdmCtrl, &apList->bssidList[apIndex].bssId, &cacheIndex);
1764
1765            TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlWpa2_buildAndSendPMKIDCandList, preAuthStatus=%d \n", preAuthStatus);
1766
1767            if (preAuthStatus)
1768            {
1769                pAdmCtrl->pmkid_cache.pmkidTbl[cacheIndex].preAuthenticate = TI_TRUE;
1770            }
1771
1772            bssidMac = (TI_UINT8 *)apList->bssidList[apIndex].bssId;
1773            MAC_COPY (pCandList->CandidateList[candIndex].BSSID, bssidMac);
1774
1775            if(pAdmCtrl->preAuthSupport && (wpa2Data.preAuthentication))
1776            {
1777               pCandList->CandidateList[candIndex].Flags =
1778                                 OS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLE;
1779            }
1780            else
1781            {
1782                pCandList->CandidateList[candIndex].Flags = 0;
1783
1784            }
1785
1786            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);
1787
1788            candIndex ++;
1789        }
1790
1791    }
1792    /* Add candidates that have valid PMKID, but were not in the list */
1793    for (apIndex=0; apIndex<pAdmCtrl->pmkid_cache.entriesNumber; apIndex++)
1794    {
1795        if (!pAdmCtrl->pmkid_cache.pmkidTbl[apIndex].preAuthenticate)
1796        {
1797            MAC_COPY (pCandList->CandidateList[candIndex].BSSID,
1798                      pAdmCtrl->pmkid_cache.pmkidTbl[apIndex].bssId);
1799            pCandList->CandidateList[apIndex].Flags =
1800                OS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLE;
1801            candIndex++;
1802        }
1803    }
1804
1805
1806    pCandList->NumCandidates = candIndex;
1807
1808
1809    /* Send Status Media specific indication to OS */
1810    size = sizeof(OS_802_11_PMKID_CANDIDATELIST) +
1811           (candIndex - 1) * sizeof(OS_802_11_PMKID_CANDIDATE) + sizeof(TI_UINT32);
1812
1813     /* Fill type of indication */
1814    *(TI_UINT32*)memBuff = os802_11StatusType_PMKID_CandidateList;
1815
1816    pCandList->NumCandidates = candIndex;
1817
1818    /* Store the number of candidates sent - needed for pre-auth finish event */
1819    pAdmCtrl->numberOfPreAuthCandidates = candIndex;
1820    /* Start the pre-authentication finish event timer */
1821    /* If the pre-authentication process is not over by the time it expires - we send an event */
1822    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION , "Starting PREAUTH timer (%d mSec)\n",pAdmCtrl->preAuthTimeout*candIndex);
1823    tmr_StartTimer (pAdmCtrl->hPreAuthTimerWpa2,
1824                    admCtrlWpa2_preAuthTimerExpire,
1825                    (TI_HANDLE)pAdmCtrl,
1826                    pAdmCtrl->preAuthTimeout * candIndex,
1827                    TI_FALSE);
1828
1829    EvHandlerSendEvent(pAdmCtrl->hEvHandler, IPC_EVENT_MEDIA_SPECIFIC,
1830                        memBuff, size);
1831
1832    /* Send PRE-AUTH start event to External Application */
1833    admCtrl_notifyPreAuthStatus (pAdmCtrl, RSN_PRE_AUTH_START);
1834    TRACE1(pAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "RSN:  PMKID Candidate List with %d entries has been built and sent for ssid  \n", candIndex);
1835    return;
1836}
1837
1838/**
1839*
1840* admCtrlWpa2_getPreAuthStatus
1841*
1842* \b Description:
1843*
1844* Returns the status of the Pre Auth for the BSSID. If the authentictaion mode
1845 * is not WPA2, then TI_FALSE will be returned.
1846 * For WPA2 mode, if PMKID exists fro the BSSID and its liftime is valid
1847 * TI_TRUE will be returned.
1848 * Otherwise TI_FALSE.
1849*
1850*
1851*
1852* \b ARGS:
1853*  I   - pAdmCtrl - pointer to admCtrl context
1854 * I   - givenAP  - required BSSID
1855*
1856* \b RETURNS:
1857*
1858* TI_OK on success, TI_NOK on failure.
1859*
1860* \sa
1861*/
1862static TI_BOOL admCtrlWpa2_getPreAuthStatus(admCtrl_t *pAdmCtrl, TMacAddr *givenAP, TI_UINT8  *cacheIndex)
1863{
1864    pmkidValue_t    PMKID;
1865
1866    if (admCtrlWpa2_findPMKID (pAdmCtrl, givenAP,
1867                                 &PMKID, cacheIndex)!=TI_OK)
1868    {
1869        return TI_FALSE;
1870    }
1871    return TI_TRUE;
1872
1873}
1874
1875static TI_STATUS admCtrlWpa2_startPreAuth(admCtrl_t *pAdmCtrl, TBssidList4PreAuth *pBssidList)
1876{
1877
1878    admCtrlWpa2_buildAndSendPMKIDCandList (pAdmCtrl, pBssidList);
1879    return TI_OK;
1880}
1881
1882static TI_STATUS admCtrlWpa2_get802_1x_AkmExists (admCtrl_t *pAdmCtrl, TI_BOOL *wpa_802_1x_AkmExists)
1883{
1884    *wpa_802_1x_AkmExists = pAdmCtrl->wpaAkmExists;
1885    return TI_OK;
1886}
1887
1888
1889
1890/*-----------------------------------------------------------------------------
1891Routine Name: admCtrlWpa2_preAuthTimerExpire
1892Routine Description: updates the preAuthStatus
1893Arguments:
1894Return Value:
1895-----------------------------------------------------------------------------*/
1896void admCtrlWpa2_preAuthTimerExpire(TI_HANDLE hAdmCtrl, TI_BOOL bTwdInitOccured)
1897{
1898    admCtrl_t         *pAdmCtrl = (admCtrl_t *)hAdmCtrl;
1899    TRACE0(pAdmCtrl->hReport, REPORT_SEVERITY_WARNING , "admCtrlWpa2_preAuthTimerExpire: PREAUTH EXPIRED !!!!!!!!");
1900    /* Send PRE-AUTH end event to External Application */
1901    admCtrl_notifyPreAuthStatus (pAdmCtrl, RSN_PRE_AUTH_END);
1902    pAdmCtrl->numberOfPreAuthCandidates = 0;
1903   return;
1904}
1905
1906