static int checkInfoElement(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) { tAniEapolRsnKeyDesc *desc; v_U8_t *ieStaBytes; int ieStaLen; desc = (tAniEapolRsnKeyDesc *) data->keyDesc; if( desc ) { ieStaLen = aniAsfPacketGetBytes(fsm->staCtx->ieSta, &ieStaBytes); if( !ANI_IS_STATUS_SUCCESS( ieStaLen ) ) { return ieStaLen; } if ((desc->keyDataLen != ieStaLen) || ( !vos_mem_compare(desc->keyData, ieStaBytes, ieStaLen-2) )) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Auth STA sent inconsistent RSN IE!\n"); return ANI_E_FAILED; } // Copy RSN IE //vos_mem_copy(fsm->advertizedRsnIe, desc->keyData, ieStaLen); vos_mem_copy(fsm->advertizedRsnIe, ieStaBytes, ieStaLen); return ANI_OK; } else { return ANI_E_NULL_VALUE; } }
static int checkInfoElement(tSuppRsnFsm *fsm, tAniEapolKeyAvailEventData *data) { tAniEapolRsnKeyDesc *desc; v_U8_t *ieApBytes; int ieApLen; desc = (tAniEapolRsnKeyDesc *) data->keyDesc; if( NULL == desc ) { return ANI_E_NULL_VALUE; } ieApLen = aniAsfPacketGetBytes(fsm->suppCtx->ieAp, &ieApBytes); if( ANI_IS_STATUS_SUCCESS( ieApLen ) ) { if ((desc->keyDataLen != ieApLen) || ( vos_mem_compare(desc->keyData, ieApBytes, ieApLen) )) { // TODO: Send a fault here VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp AP sent inconsistent RSN IE!\n" ); return ANI_E_FAILED; } } return ANI_OK; }
/* \brief bapRsnSendEapolFrame To push an eapol frame to TL. \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format */ VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt ) { VOS_STATUS status; vos_pkt_t *pPacket = NULL; v_U8_t *pData, *pSrc; int pktLen = aniAsfPacketGetBytes( pAniPkt, &pSrc ); if( pktLen <= 0 ) { return VOS_STATUS_E_EMPTY; } status = bapRsnAcquirePacket( &pPacket, &pData, pktLen ); if( VOS_IS_STATUS_SUCCESS( status ) && ( NULL != pPacket )) { vos_mem_copy( pData, pSrc, pktLen ); //Send the packet, need to check whether we have an outstanding packet first. status = bapRsnTxFrame( pvosGCtx, pPacket ); if( !VOS_IS_STATUS_SUCCESS( status ) ) { vos_pkt_return_packet( pPacket ); } } return ( status ); }
static int checkRsnKeyMic(v_U32_t cryptHandle, tAniPacket *eapolFrame, tAniEapolRsnKeyDesc *rsnDesc, v_U8_t *micKey, v_U32_t micKeyLen) { int retVal = ANI_ERROR; int len; v_U8_t *ptr = NULL; v_U8_t *micPos = NULL; v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two v_U8_t incomingMic[ANI_EAPOL_KEY_RSN_MIC_SIZE]; if (!rsnDesc->info.micFlag) { VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } len = aniAsfPacketGetBytes(eapolFrame, &ptr); if( ANI_IS_STATUS_SUCCESS( len ) ) { micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET; // Skip to the EAPOL version field for MIC computation ptr += EAPOL_VERSION_POS; len -= EAPOL_VERSION_POS; // Copy existing MIC to temporary location and zero it out vos_mem_copy( incomingMic, micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE ); vos_mem_zero( micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE ); if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) { if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) { retVal = ANI_OK; } } else { VOS_ASSERT( 0 ); retVal = ANI_E_ILLEGAL_ARG; } if (retVal == ANI_OK) { if ( !vos_mem_compare(incomingMic, result, ANI_EAPOL_KEY_RSN_MIC_SIZE)) { retVal = ANI_E_MIC_FAILED; } } } return retVal; }
int aagPtkPrf(v_U32_t cryptHandle, v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], v_U32_t prfLen, tAniPacket *pmk, tAniMacAddr authAddr, tAniMacAddr suppAddr, v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE], v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]) { v_U8_t *lowMac; v_U8_t *highMac; v_U8_t *lowNonce; v_U8_t *highNonce; v_U8_t *keyBytes; int keyLen; v_U8_t text[AAG_PTK_PRF_TEXT_LEN]; if (vos_mem_compare2(authAddr, suppAddr, sizeof(tAniMacAddr)) < 0) { lowMac = authAddr; highMac = suppAddr; } else { lowMac = suppAddr; highMac = authAddr; } if (vos_mem_compare2(aNonce, sNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) < 0) { lowNonce = aNonce; highNonce = sNonce; } else { lowNonce = sNonce; highNonce = aNonce; } vos_mem_copy(text + AAG_PTK_PRF_LM_POS, lowMac, sizeof(tAniMacAddr)); vos_mem_copy(text + AAG_PTK_PRF_HM_POS, highMac, sizeof(tAniMacAddr)); vos_mem_copy(text + AAG_PTK_PRF_LN_POS, lowNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); vos_mem_copy(text + AAG_PTK_PRF_HN_POS, highNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); keyLen = aniAsfPacketGetBytes(pmk, &keyBytes); if( !ANI_IS_STATUS_SUCCESS( keyLen ) ) { return keyLen; } return aagPrf(cryptHandle, result, keyBytes, keyLen, (v_U8_t *)AAG_PTK_PRF_CONST, AAG_PTK_PRF_CONST_LEN, text, sizeof(text), prfLen); }
int aniEapolParse(tAniPacket *packet, v_U8_t **dstMac, v_U8_t **srcMac, v_U8_t **type) { v_U16_t frameType; v_U8_t *ptr; int retVal; int tmp; if (aniAsfPacketGetLen(packet) < EAPOL_BODY_POS) return ANI_E_ILLEGAL_ARG; retVal = aniAsfPacketGetBytes(packet, &ptr); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) { return retVal; } VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Supp parsing EAPOL packet of len %d: \n", retVal); frameType = (ptr[ETHER_PROTO_POS] << 8) + ptr[ETHER_PROTO_POS+1]; if (frameType != ANI_ETH_P_EAPOL) return ANI_E_ILLEGAL_ARG; *dstMac = ptr + DST_MAC_POS; *srcMac = ptr + SRC_MAC_POS; *type = ptr + ANI_EAPOL_TYPE_POS; retVal = (ptr[EAPOL_BODY_LEN_POS] << 8) + ptr[EAPOL_BODY_LEN_POS + 1]; tmp = aniAsfPacketGetLen(packet) - EAPOL_RX_HEADER_SIZE; if (retVal > tmp) { retVal = ANI_E_ILLEGAL_ARG; } else { if (retVal < tmp) { retVal = aniAsfPacketTruncateFromRear(packet, tmp - retVal); } } return retVal; }
/** * aniEapolParseKey * * Parses and verifies a complete EAPOL-Key frame. The key descriptor * type is returned and so is a newly allocated key descriptor structure * that is appropriate for the type. * * NOTE: This is a non-destructive read. That is, the packet headers * will be unchanged at the end of this read operation. This is so * that a followup MIC check may be done on the complete packet. If * the packet parsing fails, the packet headers are not guaranteed to * be unchanged. * * @param packet the packet to read from. Note that the frame is not * expected to contain any additional padding at the end other than * the exact number of key bytes. (The aniEapolParse function will * ensure this.) * @param descType is set to the key descriptor type * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or * ANI_EAPOL_KEY_DESC_TYPE_RSN). * @param keyDescData is set to a newly allocated key descriptor * corresponding to the above descType. The signature field is * verified. The key bytes will be returned encrypted. It is the * responsibility of the caller to free this structure and the data * contained therein. * * @return ANI_OK if the operation succeeds */ int aniEapolParseKey(tAniPacket *packet, int *descType, void **keyDescData) { int retVal; v_U8_t *bytes; v_U32_t eapolFrameLen; if (packet == NULL) return ANI_E_NULL_VALUE; do { eapolFrameLen = aniAsfPacketGetLen(packet); VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Supp parsing EAPOL-Key frame of len %d\n", eapolFrameLen); retVal = aniAsfPacketTruncateFromFront(packet, EAPOL_RX_HEADER_SIZE); if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; retVal = aniAsfPacketGetBytes(packet, &bytes); if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; if (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN || *bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) { tAniEapolRsnKeyDesc *rsnDesc = NULL; //*descType = ANI_EAPOL_KEY_DESC_TYPE_RSN; *descType = (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW ? ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW : ANI_EAPOL_KEY_DESC_TYPE_RSN) ; retVal = parseRsnKeyDesc(packet, &rsnDesc); if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; *keyDescData = rsnDesc; } else { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp received unknown EAPOL-Key descriptor: %d\n", *bytes); retVal = ANI_E_ILLEGAL_ARG; break; } aniAsfPacketMoveLeft(packet, eapolFrameLen); }while( 0 ); return retVal; }
/** * aniAsfPacketGetN * * Returns N bytes from the packet and moves the head of the packet * beyond those bytes. * * @param packet the packet to read from * @param n the number of bytes to read * @param bytesPtr is set to the start of the octets * * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the * packet does not have n bytes. */ int aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr) { int retVal; v_U8_t *bytes = NULL; if (packet == NULL) return ANI_E_NULL_VALUE; retVal = aniAsfPacketGetBytes(packet, &bytes); if (retVal < n) return ANI_E_SHORT_PACKET; aniAsfPacketTruncateFromFront(packet, n); *bytesPtr = bytes; return ANI_OK; }
static int writeRsnKeyMic(v_U32_t cryptHandle, tAniPacket *eapolFrame, tAniEapolRsnKeyDesc *rsnDesc, v_U8_t *micKey, v_U32_t micKeyLen) { int retVal = ANI_OK; int len; v_U8_t *ptr = NULL; v_U8_t *micPos = NULL; v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two // Sanity check the arguments and return if no MIC generation is // needed if (micKey != NULL) { if (micKeyLen == 0 || !rsnDesc->info.micFlag) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp MIC key provided but micKeyLen or micFlag is not set!\n"); VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } } else { if (rsnDesc->info.micFlag) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp micFlag is set but MIC key not provided!\n"); VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } // Normal condition where MIC is not desired by the caller return ANI_OK; } len = aniAsfPacketGetBytes(eapolFrame, &ptr); if( !ANI_IS_STATUS_SUCCESS( len ) ) { return len; } micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE; // Clear the MIC field in the packet before the MIC computation vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE); // Skip to the EAPOL version field for MIC computation ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE; len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE); if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) { if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) { retVal = ANI_OK; } else { retVal = ANI_ERROR; } } else { VOS_ASSERT( 0 ); retVal = ANI_E_ILLEGAL_ARG; } if (retVal == ANI_OK) { // Copy only 16B which is the smaller of the two and the same as // ANI_EAPOL_KEY_RSN_MIC_SIZE vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE); } return retVal; }
/** * aniEapolParse * * FUNCTION: * Parses an EAPoL frame to the first level of headers (no EAP * headers are parsed). * * NOTE: This is a non-destructive read, that is the * headers are not stripped off the packet. However, any additional * data at the end of the packet, beyond what the EAPoL headers encode * will be stripped off. * * @param packet the packet containing the EAPoL frame to parse * @param dstMac a pointer to set to the location of the destination * MAC address * @param srcMac a pointer to set to the location of the source * MAC address * @param type a pointer to set to the location of the EAPOL type * field. * * @return the non-negative length of the EAPOL payload if the operation * succeeds */ int aniEapolParse(tAniPacket *packet, v_U8_t **dstMac, v_U8_t **srcMac, v_U8_t **type) { v_U16_t frameType; v_U8_t *ptr; int retVal; int tmp; if (aniAsfPacketGetLen(packet) < EAPOL_BODY_POS) return ANI_E_ILLEGAL_ARG; retVal = aniAsfPacketGetBytes(packet, &ptr); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) { return retVal; } VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Supp parsing EAPOL packet of len %d: \n", retVal); frameType = (ptr[ETHER_PROTO_POS] << 8) + ptr[ETHER_PROTO_POS+1]; /* * Validate the EAPOL-FRAME */ if (frameType != ANI_ETH_P_EAPOL) return ANI_E_ILLEGAL_ARG; *dstMac = ptr + DST_MAC_POS; *srcMac = ptr + SRC_MAC_POS; // if (ptr[EAPOL_VERSION_POS] != EAPOL_VERSION_1) // return ANI_E_ILLEGAL_ARG; *type = ptr + ANI_EAPOL_TYPE_POS; retVal = (ptr[EAPOL_BODY_LEN_POS] << 8) + ptr[EAPOL_BODY_LEN_POS + 1]; /* * Validate the length of the body. Allow for longer * packets than encoded, but encoding should not be larger than * packet. * Note: EAPOL body len does not include headers */ tmp = aniAsfPacketGetLen(packet) - EAPOL_RX_HEADER_SIZE; if (retVal > tmp) { retVal = ANI_E_ILLEGAL_ARG; } else { if (retVal < tmp) { retVal = aniAsfPacketTruncateFromRear(packet, tmp - retVal); } } 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 writeRsnKeyMic(v_U32_t cryptHandle, tAniPacket *eapolFrame, tAniEapolRsnKeyDesc *rsnDesc, v_U8_t *micKey, v_U32_t micKeyLen) { int retVal = ANI_OK; int len; v_U8_t *ptr = NULL; v_U8_t *micPos = NULL; v_U8_t result[VOS_DIGEST_SHA1_SIZE]; if (micKey != NULL) { if (micKeyLen == 0 || !rsnDesc->info.micFlag) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp MIC key provided but micKeyLen or micFlag is not set!\n"); VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } } else { if (rsnDesc->info.micFlag) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp micFlag is set but MIC key not provided!\n"); VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } return ANI_OK; } len = aniAsfPacketGetBytes(eapolFrame, &ptr); if( !ANI_IS_STATUS_SUCCESS( len ) ) { return len; } micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE; vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE); ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE; len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE); if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) { if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) { retVal = ANI_OK; } else { retVal = ANI_ERROR; } } else { VOS_ASSERT( 0 ); retVal = ANI_E_ILLEGAL_ARG; } if (retVal == ANI_OK) { vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE); } return retVal; }