static int gotoStateUpdateKeysReq(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) { tAniEapolRsnKeyDesc *rxDesc; fsm->currentState = UPDATE_KEYS_REQ; rxDesc = data->keyDesc; aniSsmReplayCtrUpdate(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter); checkTransition(fsm, data); return ANI_OK; }
static int checkTransition(tSuppRsnFsm *fsm, void *arg) { tAniEapolKeyAvailEventData *data; tAniEapolRsnKeyDesc *rxDesc; v_BOOL_t retransmit; int retVal; if (fsm->authReq) { gotoStateAuthentication(fsm); return ANI_OK; } switch (fsm->currentState) { case INITIALIZE: break; case AUTHENTICATION: gotoStateGotPmk(fsm); checkTransition(fsm, arg); break; case GOT_PMK: if (fsm->eapolAvail) { fsm->eapolAvail = eANI_BOOLEAN_FALSE; data = (tAniEapolKeyAvailEventData *) arg; rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; if (rxDesc->info.ackFlag) { aniSsmReplayCtrUpdate(fsm->peerReplayCtr, rxDesc->replayCounter); // Going from one state to another cannot be a retransmit retVal = gotoStateStaKeyStart(fsm, data, eANI_BOOLEAN_FALSE); } } break; case STA_KEY_START: if (fsm->eapolAvail) { fsm->eapolAvail = eANI_BOOLEAN_FALSE; data = (tAniEapolKeyAvailEventData *) arg; rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; if (rxDesc->info.ackFlag) { retVal = checkPeerReplayCounter( fsm, data, &retransmit, rxDesc->info.micFlag, 0); // MIC not set means check for re-Tx M1. if (retVal != ANI_OK) return ANI_OK; // Caller should not fail if (retransmit) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Resending EAPOL-Key Msg2 from " "supplicant to AP" ); retVal = gotoStateStaKeyStart(fsm, data, eANI_BOOLEAN_TRUE); } else { retVal = checkMic(fsm, data, rxDesc->info.unicastFlag); if (retVal != ANI_OK) { bapSuppDisconnect( fsm->ctx ); return retVal; } aniSsmReplayCtrUpdate(fsm->peerReplayCtr, rxDesc->replayCounter); gotoStateStaKeySet(fsm, data, eANI_BOOLEAN_FALSE); } } } break; case STA_KEY_SET: if (fsm->eapolAvail) { fsm->eapolAvail = eANI_BOOLEAN_FALSE; data = (tAniEapolKeyAvailEventData *) arg; rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; retVal = checkPeerReplayCounter( fsm, data, &retransmit, rxDesc->info.micFlag, 1); // MIC set means check for re-Tx M3. if (retVal != ANI_OK) return ANI_OK; // Caller should not fail if (!retransmit) { retVal = checkMic(fsm, data, rxDesc->info.unicastFlag); if (retVal != ANI_OK) { bapSuppDisconnect( fsm->ctx ); return retVal; } aniSsmReplayCtrUpdate(fsm->peerReplayCtr, rxDesc->replayCounter); } if (rxDesc->info.unicastFlag) { /* * Handle pairwise key message...in this state * pairwise key messages can only be for retransmissions. */ if (retransmit) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Resending EAPOL-Key Msg4 from " "supplicant \n" ); retVal = gotoStateStaKeySet(fsm, data, eANI_BOOLEAN_TRUE); } } else { /* * Handle group key message...with group key messages, * the replay counter has to change on * retransmissions. */ if (!retransmit) { retVal = gotoStateGroupKeySet(fsm, data); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) { bapSuppDisconnect( fsm->ctx ); return retVal; } } } } else { if (fsm->integFailed) { gotoStateKeyUpdate(fsm, arg); } } break; case GROUP_KEY_SET: gotoStateStaKeySet(fsm, NULL, eANI_BOOLEAN_FALSE); break; case KEY_UPDATE: gotoStateRekeyMsg(fsm, arg); break; default: VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Illegal state for SuppRsnFsm: %d", fsm->currentState); VOS_ASSERT( 0 ); return ANI_E_FAILED; } return ANI_OK; }