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 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 VOS_STATUS bapRsnTxCompleteCallback( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) { int retVal; ptBtampContext btampContext; // use btampContext value tCsrRoamSetKey setKeyInfo; tSuppRsnFsm *fsm; if (NULL == pvosGCtx) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "pvosGCtx is NULL in %s", __func__); return VOS_STATUS_E_FAULT; } btampContext = VOS_GET_BAP_CB(pvosGCtx); if (NULL == btampContext) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "btampContext is NULL in %s", __func__); return VOS_STATUS_E_FAULT; } fsm = &btampContext->uFsm.suppFsm; if (NULL == fsm) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "fsm is NULL in %s", __func__); return VOS_STATUS_E_FAULT; } //If we get a disconect from upper layer before getting the pkt from TL the //bapRsnFsmTxCmpHandler could be NULL //VOS_ASSERT( bapRsnFsmTxCmpHandler ); if( bapRsnFsmTxCmpHandler ) { //Change the state //Call auth or supp FSM's handler bapRsnFsmTxCmpHandler( pvosGCtx, pPacket, retStatus ); } else { vos_pkt_return_packet( pPacket ); return (VOS_STATUS_SUCCESS ); } //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 (BAP_SET_RSN_KEY == gReadToSetKey) { 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 ); 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; } gReadToSetKey = BAP_RESET_RSN_KEY; } return (VOS_STATUS_SUCCESS ); }
static VOS_STATUS bapRsnTxCompleteCallback( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) { int retVal; ptBtampContext btampContext; // tCsrRoamSetKey setKeyInfo; tSuppRsnFsm *fsm; if (NULL == pvosGCtx) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "pvosGCtx is NULL in %s", __func__); return VOS_STATUS_E_FAULT; } btampContext = VOS_GET_BAP_CB(pvosGCtx); if (NULL == btampContext) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "btampContext is NULL in %s", __func__); return VOS_STATUS_E_FAULT; } fsm = &btampContext->uFsm.suppFsm; if (NULL == fsm) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "fsm is NULL in %s", __func__); return VOS_STATUS_E_FAULT; } // // // if( bapRsnFsmTxCmpHandler ) { // // bapRsnFsmTxCmpHandler( pvosGCtx, pPacket, retStatus ); } else { vos_pkt_return_packet( pPacket ); return (VOS_STATUS_SUCCESS ); } // /* */ if (BAP_SET_RSN_KEY == gReadToSetKey) { 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; // setKeyInfo.keyId = 0; // 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 ); 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; } gReadToSetKey = BAP_RESET_RSN_KEY; } return (VOS_STATUS_SUCCESS ); }