Home | History | Annotate | Download | only in Connection_Managment
      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 */
     93 static TI_UINT8 wpa2IeOuiIe[3] = { 0x00, 0x0f, 0xac};
     94 
     95 static 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 */
    120 typedef struct
    121 {
    122     TI_STATUS        status;
    123     ECipherSuite     unicast;
    124     ECipherSuite     broadcast;
    125     TI_UINT8            evaluation;
    126 } admCtrlWpa2_validity_t;
    127 
    128 static 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 
    398 TI_STATUS admCtrlWpa2_parseIe(admCtrl_t *pAdmCtrl, TI_UINT8 *pWpa2Ie, wpa2IeData_t *pWpa2Data);
    399 TI_UINT16 admCtrlWpa2_buildCapabilities(admCtrl_t *pAdmCtrl);
    400 TI_UINT32  admCtrlWpa2_parseSuiteVal(admCtrl_t *pAdmCtrl, TI_UINT8* suiteVal, TI_UINT32 maxVal, TI_UINT32 unknownVal);
    401 TI_STATUS admCtrlWpa2_checkCipherSuiteValidity(ECipherSuite unicastSuite, ECipherSuite broadcastSuite, ECipherSuite encryptionStatus);
    402 TI_STATUS admCtrlWpa2_getCipherSuiteMetric (admCtrl_t *pAdmCtrl, wpa2IeData_t *pWpa2Data, TI_UINT32 *metric,
    403                                             ECipherSuite *uSuite,  ECipherSuite  *bSuite);
    404 TI_STATUS admCtrlWpa2_DynamicConfig(admCtrl_t *pAdmCtrl, TRsnPaeConfig *pPaeConfig);
    405 
    406 TI_STATUS admCtrlWpa2_resetPMKIDCache(admCtrl_t *pAdmCtrl);
    407 /*TI_STATUS admCtrlWpa2_sendPMKIDCandListAfterDelay(admCtrl_t * pAdmCtrl, TI_UINT32 delay);*/
    408 TI_STATUS admCtrlWpa2_getPMKIDList(admCtrl_t * pAdmCtrl,OS_802_11_PMKID *pmkidList);
    409 TI_STATUS admCtrlWpa2_setPMKIDList(admCtrl_t * pAdmCtrl, OS_802_11_PMKID *pmkidList);
    410 
    411 TI_STATUS admCtrlWpa2_addPMKID(admCtrl_t * pAdmCtrl, TMacAddr * pBSSID, pmkidValue_t pmkID);
    412 TI_STATUS admCtrlWpa2_findPMKID(admCtrl_t * pAdmCtrl, TMacAddr *pBSSID,
    413                                 pmkidValue_t *pPMKID, TI_UINT8  *cacheIndex);
    414 
    415 static TI_BOOL admCtrlWpa2_getPreAuthStatus(admCtrl_t *pAdmCtrl, TMacAddr *givenAP, TI_UINT8  *cacheIndex);
    416 
    417 static TI_STATUS admCtrlWpa2_startPreAuth(admCtrl_t *pAdmCtrl, TBssidList4PreAuth *pBssidList);
    418 
    419 static void admCtrlWpa2_buildAndSendPMKIDCandList(TI_HANDLE hHandle, TBssidList4PreAuth *apList);
    420 
    421 static 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 */
    441 TI_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 
    516 TI_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 */
    644 TI_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);
    789 adm_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 */
    816 TI_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 */
    960 TI_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 
   1147 TI_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 
   1181 TI_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 
   1201 TI_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 
   1217 TI_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 
   1306 TI_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 */
   1370 TI_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 */
   1425 TI_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 */
   1493 TI_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 */
   1556 TI_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 */
   1638 TI_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 
   1669 static 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 */
   1864 static 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 
   1877 static TI_STATUS admCtrlWpa2_startPreAuth(admCtrl_t *pAdmCtrl, TBssidList4PreAuth *pBssidList)
   1878 {
   1879 
   1880     admCtrlWpa2_buildAndSendPMKIDCandList (pAdmCtrl, pBssidList);
   1881     return TI_OK;
   1882 }
   1883 
   1884 static 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 /*-----------------------------------------------------------------------------
   1893 Routine Name: admCtrlWpa2_preAuthTimerExpire
   1894 Routine Description: updates the preAuthStatus
   1895 Arguments:
   1896 Return Value:
   1897 -----------------------------------------------------------------------------*/
   1898 void 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