/* * authSm.c * * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name Texas Instruments nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** \file authSM.c * \brief 802.11 authentication SM source * * \see authSM.h */ /***************************************************************************/ /* */ /* MODULE: authSM.c */ /* PURPOSE: 802.11 authentication SM source */ /* */ /***************************************************************************/ #define __FILE_ID__ FILE_ID_64 #include "osApi.h" #include "paramOut.h" #include "fsm.h" #include "report.h" #include "timer.h" #include "mlmeApi.h" #include "mlmeBuilder.h" #include "authSm.h" #include "openAuthSm.h" #include "sharedKeyAuthSm.h" #include "DrvMainModules.h" /* Constants */ /** number of states in the state machine */ #define AUTH_SM_MAX_NUM_STATES 4 /** number of events in the state machine */ #define AUTH_SM_MAX_NUM_EVENTS 8 /* Enumerations */ /* Typedefs */ /* Structures */ /* External data definitions */ /* External functions definitions */ /* Global variables */ /* Local function prototypes */ /* functions */ /** * * auth_create - allocate memory for authentication SM * * \b Description: * * Allocate memory for authentication SM. \n * Allocates memory for Association context. \n * Allocates memory for authentication timer. \n * Allocates memory for authentication SM matrix. \n * * \b ARGS: * * I - hOs - OS context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa rsn_mainSecSmKeysOnlyStop() */ TI_HANDLE auth_create(TI_HANDLE hOs) { auth_t *pHandle; TI_STATUS status; /* allocate authentication context memory */ pHandle = (auth_t*)os_memoryAlloc(hOs, sizeof(auth_t)); if (pHandle == NULL) { return NULL; } os_memoryZero(hOs, pHandle, sizeof(auth_t)); pHandle->hOs = hOs; /* allocate memory for authentication state machine */ status = fsm_Create(hOs, &pHandle->pAuthSm, AUTH_SM_MAX_NUM_STATES, AUTH_SM_MAX_NUM_EVENTS); if (status != TI_OK) { os_memoryFree(hOs, pHandle, sizeof(auth_t)); return NULL; } return pHandle; } /** * * auth_unload - unload authentication SM from memory * * \b Description: * * Unload authentication SM from memory * * \b ARGS: * * I - hAuth - Authentication SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa rsn_mainSecSmKeysOnlyStop() */ TI_STATUS auth_unload(TI_HANDLE hAuth) { TI_STATUS status; auth_t *pHandle; pHandle = (auth_t*)hAuth; status = fsm_Unload(pHandle->hOs, pHandle->pAuthSm); if (status != TI_OK) { /* report failure but don't stop... */ TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "AUTH_SM: Error releasing FSM memory \n"); } if (pHandle->hAuthSmTimer) { tmr_DestroyTimer (pHandle->hAuthSmTimer); } os_memoryFree(pHandle->hOs, pHandle, sizeof(auth_t)); return TI_OK; } /** * * auth_init - Init required handles and module variables, * * \b Description: * * Init required handles and module variables, * * \b ARGS: * * I - pStadHandles - The driver modules handles \n * * \b RETURNS: * * void * * \sa auth_Create, auth_Unload */ void auth_init (TStadHandlesList *pStadHandles) { auth_t *pHandle = (auth_t*)(pStadHandles->hAuth); pHandle->hMlme = pStadHandles->hMlmeSm; pHandle->hRsn = pStadHandles->hRsn; pHandle->hReport = pStadHandles->hReport; pHandle->hOs = pStadHandles->hOs; pHandle->hTimer = pStadHandles->hTimer; } TI_STATUS auth_SetDefaults (TI_HANDLE hAuth, authInitParams_t *pAuthInitParams) { auth_t *pHandle = (TI_HANDLE) hAuth; pHandle->timeout = pAuthInitParams->authResponseTimeout; pHandle->maxCount = pAuthInitParams->authMaxRetryCount; pHandle->retryCount = 0; pHandle->authRejectCount = 0; pHandle->authTimeoutCount = 0; pHandle->authType = AUTH_LEGACY_NONE; /* allocate OS timer memory */ pHandle->hAuthSmTimer = tmr_CreateTimer (pHandle->hTimer); if (pHandle->hAuthSmTimer == NULL) { TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "auth_SetDefaults(): Failed to create hAuthSmTimer!\n"); return TI_NOK; } return TI_OK; } /** * * auth_start - Start event for the authentication SM * * \b Description: * * Start event for the authentication SM * * \b ARGS: * * I - hAuth - Authentication SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Stop, auth_Recv */ TI_STATUS auth_start(TI_HANDLE hAuth) { auth_t *pHandle = (auth_t*)hAuth; if (pHandle == NULL) { return TI_NOK; } if (pHandle->authType == AUTH_LEGACY_NONE) { TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "auth_start: pHandle->authType == AUTH_LEGACY_NONE\n"); return TI_NOK; } switch (pHandle->authType) { case AUTH_LEGACY_RESERVED1: case AUTH_LEGACY_OPEN_SYSTEM: return auth_osSMEvent(&pHandle->currentState, OPEN_AUTH_SM_EVENT_START, pHandle); case AUTH_LEGACY_SHARED_KEY: return auth_skSMEvent(&pHandle->currentState, SHARED_KEY_AUTH_SM_EVENT_START, pHandle); default: TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "auth_start: pHandle->authType unknown.\n"); return TI_NOK; } } /** * * auth_stop - Stop event for the authentication SM * * \b Description: * * Stop event for the authentication SM * * \b ARGS: * * I - hAuth - Authentication SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Start, auth_Recv */ TI_STATUS auth_stop(TI_HANDLE hAuth, TI_BOOL sendDeAuth, mgmtStatus_e reason ) { auth_t *pHandle; pHandle = (auth_t*)hAuth; if (pHandle == NULL) return TI_NOK; if (pHandle->authType == AUTH_LEGACY_NONE) return TI_NOK; if( sendDeAuth == TI_TRUE ) { deAuth_t deAuth; deAuth.reason = ENDIAN_HANDLE_WORD(reason); mlmeBuilder_sendFrame(pHandle->hMlme, DE_AUTH, (TI_UINT8*)&deAuth, sizeof(deAuth_t), 0); } switch (pHandle->authType) { case AUTH_LEGACY_RESERVED1: case AUTH_LEGACY_OPEN_SYSTEM: return auth_osSMEvent(&pHandle->currentState, OPEN_AUTH_SM_EVENT_STOP, pHandle); case AUTH_LEGACY_SHARED_KEY: return auth_skSMEvent(&pHandle->currentState, SHARED_KEY_AUTH_SM_EVENT_STOP, pHandle); default: return TI_NOK; } } /** * * auth_recv - Recive a message from the AP * * \b Description: * * Parse a message form the AP and perform the appropriate event. * * \b ARGS: * * I - hAuth - Authentication SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Start, auth_Stop */ TI_STATUS auth_recv(TI_HANDLE hAuth, mlmeFrameInfo_t *pFrame) { auth_t *pHandle; pHandle = (auth_t*)hAuth; if (pHandle == NULL) return TI_NOK; if (pFrame->subType != AUTH) return TI_NOK; if (pHandle->authType == AUTH_LEGACY_NONE) return TI_NOK; if (pFrame->content.auth.status != STATUS_SUCCESSFUL) pHandle->authRejectCount++; switch (pHandle->authType) { case AUTH_LEGACY_RESERVED1: case AUTH_LEGACY_OPEN_SYSTEM: return openAuth_Recv(hAuth, pFrame); case AUTH_LEGACY_SHARED_KEY: return sharedKeyAuth_Recv(hAuth, pFrame); default: return TI_OK; } } /** * * auth_getParam - Get a specific parameter from the authentication SM * * \b Description: * * Get a specific parameter from the authentication SM. * * \b ARGS: * * I - hAuth - Authentication SM context \n * I/O - pParam - Parameter \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Start, auth_Stop */ TI_STATUS auth_getParam(TI_HANDLE hAuth, paramInfo_t *pParam) { auth_t *pHandle; pHandle = (auth_t*)hAuth; if ((pHandle == NULL) || (pParam == NULL)) { return TI_NOK; } switch (pParam->paramType) { case AUTH_RESPONSE_TIMEOUT_PARAM: pParam->content.authResponseTimeout = pHandle->timeout; break; case AUTH_COUNTERS_PARAM: pParam->content.siteMgrTiWlanCounters.AuthRejects = pHandle->authRejectCount; pParam->content.siteMgrTiWlanCounters.AuthTimeouts = pHandle->authTimeoutCount; break; case AUTH_LEGACY_TYPE_PARAM: pParam->content.authLegacyAuthType = pHandle->authType; break; default: return TI_NOK; } return TI_OK; } /** * * auth_setParam - Set a specific parameter to the authentication SM * * \b Description: * * Set a specific parameter to the authentication SM. * * \b ARGS: * * I - hAuth - Authentication SM context \n * I/O - pParam - Parameter \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Start, auth_Stop */ TI_STATUS auth_setParam(TI_HANDLE hAuth, paramInfo_t *pParam) { auth_t *pHandle; pHandle = (auth_t*)hAuth; if ((pHandle == NULL) || (pParam == NULL)) { return TI_NOK; } switch (pParam->paramType) { case AUTH_LEGACY_TYPE_PARAM: pHandle->authType = pParam->content.authLegacyAuthType; switch (pHandle->authType) { case AUTH_LEGACY_RESERVED1: case AUTH_LEGACY_OPEN_SYSTEM: openAuth_Config(hAuth, pHandle->hOs); break; case AUTH_LEGACY_SHARED_KEY: sharedKeyAuth_Config(hAuth, pHandle->hOs); break; default: return TI_NOK; } break; case AUTH_RESPONSE_TIMEOUT_PARAM: if ((pParam->content.authResponseTimeout >= AUTH_RESPONSE_TIMEOUT_MIN) && (pParam->content.authResponseTimeout <= AUTH_RESPONSE_TIMEOUT_MAX)) { pHandle->timeout = pParam->content.authResponseTimeout; } else { return TI_NOK; } break; default: return TI_NOK; } return TI_OK; } /** * * auth_smTimeout - Set a specific parameter to the authentication SM * * \b Description: * * Set a specific parameter to the authentication SM. * * \b ARGS: * * I - hAuth - authentication SM context \n * I - bTwdInitOccured - Indicates if TWDriver recovery occured since timer started \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Start, auth_Stop */ void auth_smTimeout (TI_HANDLE hAuth, TI_BOOL bTwdInitOccured) { auth_t *pHandle; pHandle = (auth_t*)hAuth; if (pHandle == NULL) return; if (pHandle->authType == AUTH_LEGACY_NONE) return; pHandle->authTimeoutCount++; switch (pHandle->authType) { case AUTH_LEGACY_RESERVED1: case AUTH_LEGACY_OPEN_SYSTEM: openAuth_Timeout(pHandle); break; case AUTH_LEGACY_SHARED_KEY: sharedKey_Timeout(pHandle); break; default: break; } } /***************************************************************************** ** ** Authentication messages builder/Parser ** *****************************************************************************/ /** * * auth_smMsgBuild - Build an authentication message and send it to the mlme builder * * \b Description: * * Build an authentication message and send it to the mlme builder. * * \b ARGS: * * I - pAssoc - Association SM context \n * I/O - pParam - Parameter \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa auth_Start, auth_Stop */ TI_STATUS auth_smMsgBuild(auth_t *pCtx, TI_UINT16 seq, TI_UINT16 statusCode, TI_UINT8* pChallange, TI_UINT8 challangeLen) { TI_STATUS status; TI_UINT8 len; TI_UINT8 authMsg[MAX_AUTH_MSG_LEN]; authMsg_t *pAuthMsg; dot11_CHALLENGE_t *pDot11Challenge; TI_UINT8 wepOpt; wepOpt = 0; pAuthMsg = (authMsg_t*)authMsg; /* insert algorithm */ pAuthMsg->authAlgo = (TI_UINT16)pCtx->authType; /* insert sequense */ pAuthMsg->seqNum = ENDIAN_HANDLE_WORD(seq); /* insert status code */ pAuthMsg->status = ENDIAN_HANDLE_WORD(statusCode); len = sizeof(pAuthMsg->authAlgo) + sizeof(pAuthMsg->seqNum) + sizeof(pAuthMsg->status); if (pChallange != NULL) { pDot11Challenge = (dot11_CHALLENGE_t*)&authMsg[len]; pDot11Challenge->hdr[0] = CHALLANGE_TEXT_IE_ID; pDot11Challenge->hdr[1] = challangeLen; os_memoryCopy(pCtx->hOs, (void *)pDot11Challenge->text, pChallange, challangeLen); len += challangeLen + 2; wepOpt = 1; } status = mlmeBuilder_sendFrame(pCtx->hMlme, AUTH, authMsg, len, wepOpt); return status; }