static int
gotoStatePtkInitNego(tAuthRsnFsm *fsm, void *arg)
{
    fsm->currentState = PTK_INIT_NEGO;

    // Replay counter will be automatically updated when we create a
    // new packet

    fsm->numTries = 0;
    aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);

    checkTransition(fsm, arg);

    return ANI_OK;
}
static int
gotoStateGroupKeySet(tSuppRsnFsm *fsm, 
                     tAniEapolKeyAvailEventData *data)
{
    int retVal;
    tAniEapolRsnKeyDesc txDesc;
    tAniEapolRsnKeyDesc *rxDesc;

    int groupKeyLen;
    
    fsm->currentState = GROUP_KEY_SET;
    
    do
    {
        rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc;
        if( NULL == rxDesc) 
        {
            retVal = ANI_E_NULL_VALUE;
            break;
        }

        if (rxDesc->keyDataLen == 0 || rxDesc->keyData == NULL) 
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, 
                "Supp: AP sent no group key in group EAPOL-Key message!\n" );
            retVal = ANI_E_ILLEGAL_ARG;
            break;
        }

        if ( rxDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES ) 
        {
            groupKeyLen = rxDesc->keyDataLen - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
            if( groupKeyLen <= 0 )
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, 
                    "Supp: AP sent GTK too short\n" );
                retVal = ANI_E_ILLEGAL_ARG;
                break;
            }
        } 
        else
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, 
                "Supp: AP sent unsupported keyDescVer %d!\n", rxDesc->info.keyDescVers );
            retVal = ANI_E_ILLEGAL_ARG;
            break;
        }

        // Always create a new EAPOL frame

        aniAsfPacketEmptyExplicit( fsm->lastEapol, 
                                  EAPOL_TX_HEADER_SIZE );
        
        vos_mem_zero( &txDesc, sizeof(txDesc) );

        // The Key Information bits...
        if (fsm->suppCtx->grpCipherType == eCSR_ENCRYPT_TYPE_AES) 
        {
            txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
        }

        txDesc.info.unicastFlag = eANI_BOOLEAN_FALSE;
        txDesc.info.keyId = rxDesc->info.keyId;
        txDesc.info.micFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.secureFlag = eANI_BOOLEAN_TRUE;
        txDesc.keyLen = RSN_80211_KEY_LEN;

        // Send back the same replayCtr that the authenticator sent
        vos_mem_copy(txDesc.replayCounter, 
               rxDesc->replayCounter, 
               sizeof(txDesc.replayCounter));

        retVal = aniEapolWriteKey(fsm->cryptHandle,
                                  fsm->lastEapol,
                                  fsm->suppCtx->authMac,
                                  fsm->suppCtx->suppMac,
                                  ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                  &txDesc,
                                  fsm->suppCtx->ptk,
                                  CSR_AES_KEY_LEN);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;    

        if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
        {
            retVal = ANI_ERROR;
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp could not send eapol. Disconnect\n" );
            break;
        }

        //FIX_RSN there is no need to set GTK retVal = setGtk(fsm->suppCtx, rxDesc->keyRecvSeqCounter);

        // This is never retransmitted
        aniAsfPacketEmptyExplicit( fsm->lastEapol, 
                                  EAPOL_TX_HEADER_SIZE );

        checkTransition(fsm, NULL); // UCT rule
    }while( 0 );

    return retVal;
}
static int
gotoStateStaKeySet(tSuppRsnFsm *fsm, 
                   tAniEapolKeyAvailEventData *data,
                   v_BOOL_t retransmit)
{
    int retVal=0;
    tAniEapolRsnKeyDesc txDesc;
    tAniEapolRsnKeyDesc *rxDesc = NULL;
    
    fsm->currentState = STA_KEY_SET;

    if (data == NULL) 
    {
        // We don't need to do anything
        return ANI_OK;
    }
    
    // Create a new EAPOL frame if we don't have to retransmit
    if (!retransmit) 
    {
        // First check the IE that the AP sent
        retVal = checkInfoElement(fsm, data);
        if (retVal != ANI_OK) 
        {
            //FIX_RSN aagSetSuppFailureAndCleanup(fsm->suppCtx);

            // FSM does not exist after this...

            return retVal;
        }

        // Create a new EAPOL frame

        rxDesc = data->keyDesc;
        if( NULL == rxDesc )
            return ANI_E_NULL_VALUE;

        aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                                  EAPOL_TX_HEADER_SIZE );

        vos_mem_zero( &txDesc, sizeof(txDesc) );

        // The Key Information bits...
        if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
        {
            txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
        }

        txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.micFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.secureFlag = eANI_BOOLEAN_TRUE;
        txDesc.keyLen = 0; //RSN_80211_KEY_LEN;

        // Send back the same replayCtr that the authenticator sent
        vos_mem_copy(txDesc.replayCounter, 
               rxDesc->replayCounter, 
               sizeof(txDesc.replayCounter));

        retVal = aniEapolWriteKey(fsm->cryptHandle,
                                  fsm->lastEapol,
                                  fsm->suppCtx->authMac,
                                  fsm->suppCtx->suppMac,
                                  ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                  &txDesc,
                                  fsm->suppCtx->ptk,
                                  CSR_AES_KEY_LEN);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
    }
    gReadToSetKey = BAP_SET_RSN_KEY;
    if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
    {
        /* making it global to access in bapTxRx file */
#if 0
        tCsrRoamSetKey setKeyInfo;


        vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) );
        setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES;
        setKeyInfo.keyDirection = eSIR_TX_RX;
        vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, sizeof( tAniMacAddr ) );
        setKeyInfo.paeRole = 0; //this is a supplicant
        setKeyInfo.keyId = 0;   //always
        setKeyInfo.keyLength = CSR_AES_KEY_LEN; 
        vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN );
        //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one.
        /*
          We will move the Set key to EAPOL Completion handler. We found a race condition betweem
          sending EAPOL frame and setting Key */


        if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" );
            retVal = ANI_ERROR;
        }
#endif
        gReadToSetKey = BAP_RESET_RSN_KEY;
        retVal = ANI_ERROR;
    }

    return retVal;
}
static int
gotoStateStaKeyStart(tSuppRsnFsm *fsm, 
                     tAniEapolKeyAvailEventData *data,
                     v_BOOL_t retransmit)
{
    int retVal;
    tAniEapolRsnKeyDesc txDesc;
    tAniEapolRsnKeyDesc *rxDesc;
    static v_U8_t btampRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 
        0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 };

    fsm->currentState = STA_KEY_START;

    // Create a new EAPOL frame if we don't have to retransmit
   // if (!retransmit) 
    //{

        rxDesc = data->keyDesc;
        if( NULL == rxDesc)
        {
            return ANI_E_NULL_VALUE;
        }
        aniAsfPacketEmptyExplicit( fsm->lastEapol, EAPOL_TX_HEADER_SIZE );
        retVal = derivePtk(fsm, data);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "Supp derivePtk failed with code %d!\n", retVal);
            return retVal;
        }

        vos_mem_zero( &txDesc, sizeof(txDesc) );

        // The Key Information bits...
        if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
        {
            txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
        }
        txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.micFlag = eANI_BOOLEAN_TRUE;
        txDesc.keyLen = 0; //RSN_80211_KEY_LEN;

        // Send back the same replayCtr that the authenticator sent
        vos_mem_copy(txDesc.replayCounter, 
               rxDesc->replayCounter, 
               sizeof(txDesc.replayCounter));

        vos_mem_copy(txDesc.keyNonce, fsm->sNonce, sizeof(txDesc.keyNonce));
        txDesc.keyDataLen = sizeof(btampRSNIE);//aniAsfPacketGetBytes(fsm->suppCtx->ieBp,
                                               //&txDesc.keyData);    
        txDesc.keyData = btampRSNIE;
        retVal = aniEapolWriteKey(fsm->cryptHandle,
                                  fsm->lastEapol,
                                  fsm->suppCtx->authMac,
                                  fsm->suppCtx->suppMac,
                                  ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                  &txDesc,
                                  fsm->suppCtx->ptk, 
                                  CSR_AES_KEY_LEN);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp gotoStateStaKeyStart fail to write key %d\n",
                      retVal);
            return retVal;
        }
    //}
 
    if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
    {
        retVal = ANI_OK;
    }
    else
    {
        retVal = ANI_ERROR;
    }

    return retVal;
}
/**
 * aniAsfPacketEmpty
 *
 * FUNCTION:
 * Re-initializes the packet by positioning the head to the middle and
 * setting the length to zero.
 *
 * @param packet the packet to empty
 *
 * @return ANI_OK if the operation succeeded
 */
int
aniAsfPacketEmpty(tAniPacket *packet)
{
    return aniAsfPacketEmptyExplicit(packet, packet->size/2);
}
Esempio n. 6
0
int bapRsnFormPktFromVosPkt( tAniPacket **ppPacket, vos_pkt_t *pVosPacket )
{
    int retVal = ANI_ERROR;
    VOS_STATUS status;
    v_U16_t uPktLen;
#define BAP_RSN_SNAP_TYPE_OFFSET 20
#define BAP_RSN_ETHERNET_3_HEADER_LEN   22
    v_U8_t *pFrame = NULL;
    tAniPacket *pAniPacket = NULL;

    do
    {
        status = vos_pkt_get_packet_length( pVosPacket, &uPktLen );
        if( !VOS_IS_STATUS_SUCCESS(status) ) break;
        if( (uPktLen < BAP_RSN_ETHERNET_3_HEADER_LEN) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                " authRsnRxFrameHandler receive eapol packet size (%d) too small (%d)\n",
                uPktLen, BAP_RSN_ETHERNET_3_HEADER_LEN );
            break;
        }
        status = vos_pkt_peek_data( pVosPacket, 0, (v_VOID_t *)&pFrame, uPktLen );
        if( !VOS_IS_STATUS_SUCCESS(status) || (NULL == pFrame) ) break;
        retVal = aniAsfPacketAllocateExplicit(&pAniPacket, uPktLen, 0 );
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                " authRsnRxFrameHandler failed to get buffer size (%d) \n",
                uPktLen );
            break;
        }
        aniAsfPacketEmptyExplicit( pAniPacket, 0 );
        pFrame[ETHER_PROTO_POS] = pFrame[BAP_RSN_SNAP_TYPE_OFFSET];
        pFrame[ETHER_PROTO_POS + 1] = pFrame[BAP_RSN_SNAP_TYPE_OFFSET + 1];
        //push ethernet II header in
        retVal = aniAsfPacketAppendBuffer( pAniPacket, pFrame, ETHER_PROTO_POS + 2 );
        if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;
        //Get the rest of the data in
        uPktLen -= BAP_RSN_ETHERNET_3_HEADER_LEN;
        if (uPktLen <= 0){
           VOS_ASSERT(0);
           retVal = ANI_ERROR;
           break;
        }

        retVal = aniAsfPacketAppendBuffer( pAniPacket, pFrame + BAP_RSN_ETHERNET_3_HEADER_LEN,
                            uPktLen );
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                " authRsnRxFrameHandler cannot retrieve eapol payload size (%d)\n",
                uPktLen );
            break;
        }
    }while( 0 );

    if( ANI_IS_STATUS_SUCCESS( retVal ) )
    {
        *ppPacket = pAniPacket;
    }
    else if( pAniPacket )
    {
        aniAsfPacketFree( pAniPacket );
    }

    return retVal;
}
static int
gotoStatePtkInitNegoTx(tAuthRsnFsm *fsm)
{
    tAniEapolRsnKeyDesc txDesc;
    v_BOOL_t retransmit = eANI_BOOLEAN_FALSE;
    v_U8_t *rsnWpaIe = NULL;
    int rsnWpaIeLen;
    static tAniPacket *keyData;
    // The longest length...the extra 8 bytes account for RSN key data
    // encapsulation
    v_U8_t paddedGroupKeyEncaps[1024];
    int padLen = 0;
    v_U8_t *groupKeyBytes;
    int groupKeyLen;
    v_U8_t *wrappedKey = NULL;
    // Variables used for RC4 GTK wrap
    //v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE];
    //v_U32_t keyIvLsb;
    int retVal = 0;

    //invalidate this
    fsm->msg4TimeOut = VOS_FALSE;
    fsm->currentState = PTK_INIT_NEGO_TX ;

    if (keyData == NULL) 
    {
        // Allocate the packet the first time around that you enter
        retVal = aniAsfPacketAllocateExplicit(&keyData, 1024, 10);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
    } 
    else {
        // Just empty out the packet
        aniAsfPacketEmptyExplicit(keyData, 10);
    }

    do
    {
        // Create a new EAPOL frame if we don't have one to retransmit
        //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) 
#if 0
        if( fsm->lastEapol )
         {
             aniAsfPacketFree( fsm->lastEapol );
             fsm->lastEapol = NULL;

             retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol,
                                          RSN_MAX_PACKET_SIZE,
                                          EAPOL_TX_HEADER_SIZE );
#endif     
             aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);
      //  }

        if (1) 
        {

            vos_mem_zero( &txDesc, sizeof(txDesc) );

            // The Key Information bits...
            if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
            {
                txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
            } 
            else {
                txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_RC4;
            }
            txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.installFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.ackFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.micFlag = eANI_BOOLEAN_TRUE;

            txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType);
            aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter);
            vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce));

            // Add the RSN IE (but not any WPA IE)
            rsnWpaIeLen = getRsnIeFromAdvertizedIes(fsm, &rsnWpaIe);

            if( !ANI_IS_STATUS_SUCCESS( rsnWpaIeLen) ) break;

            retVal = aniAsfPacketAppendBuffer(keyData, rsnWpaIe, rsnWpaIeLen);
            if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

            // Add the RSN group key encapsulation
            retVal = aagAppendGroupKeyForRsn ( keyData );

            if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

            groupKeyLen = aniAsfPacketGetBytes(keyData, &groupKeyBytes);
            if( !ANI_IS_STATUS_SUCCESS( groupKeyLen ) ) 
            {
                retVal = ANI_E_FAILED;
                break;
            }

            txDesc.info.secureFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.encKeyDataFlag = eANI_BOOLEAN_TRUE;

            if ( fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES ) 
            {
                /*
                 * Use the AES key wrap algorithm if either one of the pairwise
                 * key or the group key is an AES key.
                 *
                 * If the key being sent is not a multiple of
                 * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then pad it with
                 * zeroes. e.g., if we are sending a WEP key of 5 or 13
                 * bytes.
                 */
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "AES Key Wrap invoked. groupKeyLen = %d", groupKeyLen);

                padLen = groupKeyLen % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                if (padLen != 0) {
                    padLen = ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - padLen;
            
                    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                               "Before AES Key Wrap: padLen = %d", padLen);

                    if (groupKeyLen + padLen > sizeof(paddedGroupKeyEncaps)) {
#if 0
                        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                                   "Cannot encode group key encapsulation of len %d and cipher type %s "
                                   "to send to %s %s (aid %d, radio %d, user %s)",
                                   groupKeyLen,
                                   aniSsmIntGetCipherStr(AAG_GROUP_CIPHER(fsm->ctx->radioId)),
                                   (fsm->ctx->bpIndicator ? "BP" : "STA"),
                                   aniAsfHexStr(fsm->ctx->suppMac, sizeof(tAniMacAddr)),
                                   fsm->ctx->aid,
                                   fsm->ctx->radioId,
                                   aagGetStaUserId(fsm->ctx));
#endif
                         retVal = ANI_E_FAILED;
                    }
                    // OK, after you compute the pad length, you need to 
                    // add the padding  - 0xdd followed by 0x00's
                    addPad( groupKeyBytes , groupKeyLen , padLen );
                    // add the padding length
                    groupKeyLen += padLen;
                    // IMMEDIATELY adjust the packet size to reflect the pad 
                    aniAsfPacketMoveRight(keyData, padLen); 
                    if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
                }
            
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "Before AES Key Wrap: padded groupKeyLen = %d", groupKeyLen);

                retVal = aniSsmAesKeyWrap(fsm->cryptHandle, groupKeyBytes, groupKeyLen,
                                          fsm->staCtx->ptk + ANI_EAPOL_KEY_RSN_MIC_SIZE,
                                          ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE,
                                          &wrappedKey);
                if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
                // This doesn't work...
                //groupKeyBytes = wrappedKey;
                //groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                // ...here is the right way to do it
                // Add the length of the prepended IV A[0]
                if (NULL == wrappedKey)
                {
                    break;
                }
                groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                memcpy( groupKeyBytes, wrappedKey, groupKeyLen);
                // Free the array used to hold the wrapped key
                if (wrappedKey) vos_mem_free( wrappedKey);
                // IMMEDIATELY adjust the packet size to reflect the IV 
                aniAsfPacketMoveRight(keyData, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE);
            } 
            else {
            
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                    "Auth RC4 Key Wrap invoked. groupKeyLen = %d", groupKeyLen);
            }
            txDesc.keyDataLen = aniAsfPacketGetBytes(keyData, &txDesc.keyData);

            retVal = aniEapolWriteKey(fsm->cryptHandle,
                                      fsm->lastEapol,
                                      fsm->staCtx->suppMac,
                                      fsm->staCtx->authMac,
                                      ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                      &txDesc,
                                      fsm->staCtx->ptk,
                                      CSR_AES_KEY_LEN);
            if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
        } 
        else {
            retransmit = eANI_BOOLEAN_TRUE;
        }

        if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
        {
            retVal = ANI_OK;
        }
        else
        {
            //we fail to send the eapol frame disconnect
            bapAuthDisconnect( fsm->ctx );
            retVal = ANI_ERROR;
        }

    }while( 0 );

    return retVal;
}

static int
gotoStatePtkInitDone(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data)
{
    int retVal;
    tAniEapolRsnKeyDesc *rxDesc;
    tCsrRoamSetKey setKeyInfo;

    fsm->currentState = PTK_INIT_DONE;

    rxDesc = data->keyDesc;

    vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) );
    setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES;
    setKeyInfo.keyDirection = eSIR_TX_RX;
    vos_mem_copy( setKeyInfo.peerMac, fsm->staCtx->suppMac, sizeof( tAniMacAddr ) );
    setKeyInfo.paeRole = 0; //this is a supplicant
    setKeyInfo.keyId = 0;   //always
    setKeyInfo.keyLength = CSR_AES_KEY_LEN; 
    vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->staCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN );
    //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one.
    if( VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) )
    {
        //Done
        aniAsfPacketEmptyExplicit(fsm->lastEapol, EAPOL_TX_HEADER_SIZE);
        retVal = ANI_OK;
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Auth: gotoStatePtkInitDone fail to set key\n" );
        retVal = ANI_ERROR;
    }

    return retVal;
}
static int
gotoStatePtkStart(tAuthRsnFsm *fsm)
{
    tAniEapolRsnKeyDesc txDesc;
    int retVal;

    fsm->msg2TimeOut = VOS_FALSE;
    fsm->currentState = PTK_START;

    // Create a new packet if we don't have one to retransmit
    //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) 
#if 0    
    if( fsm->lastEapol )
    {
        aniAsfPacketFree( fsm->lastEapol );
        fsm->lastEapol = NULL;

    retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol,
                                          RSN_MAX_PACKET_SIZE,
                                          EAPOL_TX_HEADER_SIZE );
#endif    
    aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);
    //}
   // if (1) 
    //{

        vos_mem_zero( &txDesc, sizeof(txDesc) );

        // The Key Information bits...
        if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
        {
            txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
        } 
        else {
            return ANI_E_ILLEGAL_ARG;
        }
        txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.ackFlag = eANI_BOOLEAN_TRUE;

        // The other fields...
        txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType);
        aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter);
        vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce));

        retVal = aniEapolWriteKey(fsm->cryptHandle,
                                  fsm->lastEapol,
                                  fsm->staCtx->suppMac,
                                  fsm->staCtx->authMac,
                                  ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                  &txDesc,
                                  NULL, 0);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
#if 0
    } 
    else {
        retransmit = eANI_BOOLEAN_TRUE;
    }
#endif    

    if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
    {
        retVal = ANI_OK;
    }
    else
    {
        //we fail to send the eapol frame disconnect
        bapAuthDisconnect( fsm->ctx );
        retVal = ANI_ERROR;
    }

    return retVal;
}