int authRsnAuthStartEventHandler(tAuthRsnFsm *fsm) { static v_U8_t btampStaRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 }; // Copy required info vos_mem_copy( &fsm->staCtx->authMac, fsm->ctx->self_mac_addr, 6); vos_mem_copy( &fsm->staCtx->suppMac, fsm->ctx->peer_mac_addr, 6); aniAsfPacketAppendBuffer( fsm->staCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length); aniAsfPacketAppendBuffer( fsm->staCtx->ieSta, btampStaRSNIE, sizeof(btampStaRSNIE)); return ANI_OK; }
/** * aniAsfPacketDuplicate * * Duplicates a given packet exactly. That is, the contents, the size * of the packet, and the positions of the pointers are maintained in * the new copy. * * @param newPacketPtr is set to a newly allocated packet that is a * duplicate of oldPacket * @param oldPacket the original packet that should be duplicated * * @return ANI_OK if the operation succeeds; ANI_E_NULL if oldPacket * is NULL; */ int aniAsfPacketDuplicate(tAniPacket **newPacketPtr, tAniPacket *oldPacket) { int retVal; int recordPos; tAniPacket *packet = NULL; if (oldPacket == NULL) return ANI_E_NULL_VALUE; retVal = aniAsfPacketAllocateExplicit(&packet, oldPacket->size, oldPacket->head - oldPacket->buf); if (retVal != ANI_OK) return retVal; retVal = aniAsfPacketAppendBuffer(packet, oldPacket->head, oldPacket->len); if (retVal != ANI_OK) { VOS_ASSERT( 0 ); aniAsfPacketFree(packet); return ANI_E_FAILED; } if (oldPacket->recordHeader != NULL) { recordPos = oldPacket->recordHeader - oldPacket->buf; packet->recordHeader = packet->buf + recordPos; } *newPacketPtr = packet; return ANI_OK; }
int suppRsnAuthStartEventHandler(tSuppRsnFsm *fsm) { // Copy required info vos_mem_copy( &fsm->suppCtx->authMac, fsm->ctx->peer_mac_addr, 6); vos_mem_copy( &fsm->suppCtx->suppMac, fsm->ctx->self_mac_addr, 6); aniAsfPacketAppendBuffer( fsm->suppCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length); return ANI_OK; }
static int writeRsnKeyDesc(tAniPacket *packet, tAniEapolRsnKeyDesc *rsnDesc, v_U8_t keyDescType) { int retVal; do { // This can be either ANI_EAPOL_KEY_DESC_TYPE_RSN // or ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW retVal = aniAsfPacketAppend8(packet, keyDescType); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = writeRsnKeyInfo(packet, &rsnDesc->info); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppend16(packet, rsnDesc->keyLen); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->replayCounter, sizeof(rsnDesc->replayCounter)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyNonce, sizeof(rsnDesc->keyNonce)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyIv, sizeof(rsnDesc->keyIv)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyRecvSeqCounter, sizeof(rsnDesc->keyRecvSeqCounter)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyId, sizeof(rsnDesc->keyId)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; // Zero out the key MIC retVal = aniAsfPacketAppendBuffer(packet, ZERO_BYTES, sizeof(rsnDesc->keyMic)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppend16(packet, rsnDesc->keyDataLen); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; if (rsnDesc->keyDataLen != 0) { retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyData, rsnDesc->keyDataLen); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; } }while( 0 ); return retVal; }
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; }
int aagAppendGroupKeyForRsn(tAniPacket *packet) { #if 0 tAniPacket *groupKey = NULL; #else tANI_U8 groupKey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; #endif tANI_U8 *groupKeyBytes = NULL; tANI_U8 *lenPtr = NULL; tANI_U8 *endPtr = NULL; int groupKeyLen; int retVal; #if 0 groupKey = AAG_GROUP_KEY(radioId); if (groupKey == NULL) { ANI_AAG_LOG_E("Group key is not yet set on radio %d, id %d!", radioId, AAG_GROUP_KEY_ID(radioId)); assert(0 && "Group key is still NULL!"); return ANI_E_FAILED; } groupKeyLen = aniAsfPacketGetBytes(groupKey, &groupKeyBytes); CHECK_NO_ERROR(groupKeyLen); if (aagConfig.logLevel >= LOG_INFO) { ANI_AAG_LOG_D("Will encapsulate group key bytes %s", aniAsfHexStr(groupKeyBytes, groupKeyLen)); } #else groupKeyBytes = groupKey; groupKeyLen = STATIC_WEP_KEY_LEN; #endif /* * Add the key data encapsulation needed for RSN/WPA2 */ // The IE ID retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID); //CHECK_NO_ERROR(retVal); // Obtain the position for the length aniAsfPacketGetBytesFromTail(packet, &lenPtr); // Write out a dummy length - we'll fill this in later. It will be // 6 bytes more than the length of the GTK retVal = aniAsfPacketAppend8(packet, 0); //CHECK_NO_ERROR(retVal); // Copy the RSN OUI retVal = aniAsfPacketAppendBuffer(packet, aniSsmIeRsnOui, sizeof(aniSsmIeRsnOui)); //CHECK_NO_ERROR(retVal); // Indicate that the key type is group key retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID); //CHECK_NO_ERROR(retVal); // Copy the key-id to the first two bits of the next byte // Copy the Tx bit the third bit of the same byte // (Here, I assume the Group Key is to be used for both STA Tx and Rx) retVal = aniAsfPacketAppend8( packet, GROUP_KEY_ID ); //AAG_GROUP_KEY_ID(radioId) ); //CHECK_NO_ERROR(retVal); retVal = aniAsfPacketMoveRight(packet, 1); // Reserved bits (1 byte) //CHECK_NO_ERROR(retVal); // Copy the real key bytes retVal = aniAsfPacketAppendBuffer(packet, groupKeyBytes, groupKeyLen); //CHECK_NO_ERROR(retVal); // Calculate and enter the length of the entire encoding aniAsfPacketGetBytesFromTail(packet, &endPtr); *lenPtr = endPtr - (lenPtr + 1) ; // subtract one to avoid tail return retVal; }
static int writeRsnKeyDesc(tAniPacket *packet, tAniEapolRsnKeyDesc *rsnDesc, v_U8_t keyDescType) { int retVal; do { retVal = aniAsfPacketAppend8(packet, keyDescType); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = writeRsnKeyInfo(packet, &rsnDesc->info); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppend16(packet, rsnDesc->keyLen); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->replayCounter, sizeof(rsnDesc->replayCounter)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyNonce, sizeof(rsnDesc->keyNonce)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyIv, sizeof(rsnDesc->keyIv)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyRecvSeqCounter, sizeof(rsnDesc->keyRecvSeqCounter)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyId, sizeof(rsnDesc->keyId)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppendBuffer(packet, ZERO_BYTES, sizeof(rsnDesc->keyMic)); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; retVal = aniAsfPacketAppend16(packet, rsnDesc->keyDataLen); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; if (rsnDesc->keyDataLen != 0) { retVal = aniAsfPacketAppendBuffer(packet, rsnDesc->keyData, rsnDesc->keyDataLen); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; } }while( 0 ); return retVal; }