diff options
Diffstat (limited to 'wilink_6_1/stad/src/Connection_Managment/keyParserExternal.c')
-rw-r--r-- | wilink_6_1/stad/src/Connection_Managment/keyParserExternal.c | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/wilink_6_1/stad/src/Connection_Managment/keyParserExternal.c b/wilink_6_1/stad/src/Connection_Managment/keyParserExternal.c new file mode 100644 index 0000000..05bfb38 --- /dev/null +++ b/wilink_6_1/stad/src/Connection_Managment/keyParserExternal.c @@ -0,0 +1,395 @@ +/* + * keyParserExternal.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 keyParserExternal.c + * \brief External key parser implementation. + * + * \see keyParser.h +*/ + +/**************************************************************************** + * * + * MODULE: External Key Parser * + * PURPOSE: EAP parser implementation * + * * + ****************************************************************************/ + +#define __FILE_ID__ FILE_ID_34 +#include "tidef.h" +#include "osApi.h" +#include "report.h" + +#include "keyTypes.h" + +#include "keyParser.h" +#include "keyParserExternal.h" +#include "mainKeysSm.h" +#include "mainSecSm.h" +#include "admCtrl.h" + +#include "unicastKeySM.h" +#include "broadcastKeySM.h" +#include "DataCtrl_Api.h" + +#define CKIP_KEY_LEN 16 +#define TKIP_KEY_LEN 32 +#define AES_KEY_LEN 16 + + +/** +* +* Function - Init KEY Parser module. +* +* \b Description: +* +* Called by RSN Manager. +* Registers the function 'rsn_keyParserRecv()' at the distributor to receive KEY frames upon receiving a KEY_RECV event. +* +* \b ARGS: +* +* +* \b RETURNS: +* +* TI_STATUS - 0 on success, any other value on failure. +* +*/ + +TI_STATUS keyParserExternal_config(struct _keyParser_t *pKeyParser) +{ + pKeyParser->recv = keyParserExternal_recv; + pKeyParser->replayReset = keyParser_nop; + pKeyParser->remove = keyParserExternal_remove; + return TI_OK; +} + + +/** +* +* keyParserExternal_recv +* +* \b Description: +* +* External key Parser receive function: +* - Called by NDIS (Windows) upon receiving an External Key. +* - Filters the following keys: +* - Keys with invalid key index +* - Keys with invalid MAC address +* +* \b ARGS: +* +* I - pKeyParser - Pointer to the keyParser context \n +* I - pKeyData - A pointer to the Key Data. \n +* I - keyDataLen - The Key Data length. \n +* +* \b RETURNS: +* +* TI_OK on success, TI_NOK otherwise. +* +*/ + +TI_STATUS keyParserExternal_recv(struct _keyParser_t *pKeyParser, + TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) +{ + TI_STATUS status; + OS_802_11_KEY *pKeyDesc; + encodedKeyMaterial_t encodedKeyMaterial; + paramInfo_t macParam; + TI_BOOL macEqual2Associated=TI_FALSE; + TI_BOOL macIsBroadcast=TI_FALSE; + TI_BOOL wepKey = TI_FALSE; + TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + TI_UINT8 nullMacAddr[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; + + + if (pKeyData == NULL) + { +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n"); + return TI_NOK; + } + + pKeyDesc = (OS_802_11_KEY*)pKeyData; + + /* copy the key data, mac address and RSC */ + MAC_COPY (keyBuffer, pKeyDesc->BSSID); + /* configure keyRSC value (if needed) */ + if (pKeyDesc->KeyIndex & EXT_KEY_RSC_KEY_MASK) + { /* set key recieve sequence counter */ + os_memoryCopy(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], (TI_UINT8*)&(pKeyDesc->KeyRSC), KEY_RSC_LEN); + } + else + { + os_memoryZero(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], KEY_RSC_LEN); + } + + /* check type and validity of keys */ + /* check MAC Address validity */ + macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; + status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); + + if (status != TI_OK) + { +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n"); + return TI_NOK; + } + + /* check key length */ + if((pKeyDesc->KeyLength != WEP_KEY_LEN_40) && + (pKeyDesc->KeyLength != WEP_KEY_LEN_104) && + (pKeyDesc->KeyLength != WEP_KEY_LEN_232) && + (pKeyDesc->KeyLength != CKIP_KEY_LEN) && + (pKeyDesc->KeyLength != TKIP_KEY_LEN) && + (pKeyDesc->KeyLength != AES_KEY_LEN) ) + + { +TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Incorrect key length - %d \n", pKeyDesc->KeyLength); + return TI_NOK; + } + if (MAC_EQUAL(macParam.content.ctrlDataCurrentBSSID, pKeyDesc->BSSID)) + { + macEqual2Associated = TI_TRUE; + } + if (MAC_EQUAL (pKeyDesc->BSSID, broadcastMacAddr)) + { + macIsBroadcast = TI_TRUE; + } + if ((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || + (pKeyDesc->KeyLength == WEP_KEY_LEN_104) || + (pKeyDesc->KeyLength == WEP_KEY_LEN_232)) + { /* In Add WEP the MAC address is nulled, since it's irrelevant */ + macEqual2Associated = TI_TRUE; + wepKey = TI_TRUE; + } + + if (pKeyDesc->KeyIndex & EXT_KEY_SUPP_AUTHENTICATOR_MASK) + { /* The key is being set by an Authenticator - not allowed in IBSS mode */ + if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS) + { /* in IBSS only Broadcast MAC is allowed */ + TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Authenticator set key in IBSS mode !!!\n"); + return TI_NOK; + } + + } + + if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) + { /* the reamining bits in the key index are not 0 (when they should be) */ +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Key index bits 8-27 should be 0 !!!\n"); + return TI_NOK; + } + + encodedKeyMaterial.pData = (char *) keyBuffer; + /* Check key length according to the cipher suite - TKIP, etc...??? */ + if (wepKey) + { + if (!((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || (pKeyDesc->KeyLength == WEP_KEY_LEN_104) + || (pKeyDesc->KeyLength == WEP_KEY_LEN_232))) + { /*Invalid key length*/ + TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "WEP_KEY_PARSER: ERROR: Invalid Key length: %d !!!\n", pKeyDesc->KeyLength); + return TI_NOK; + } + + os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); + if (MAC_EQUAL (nullMacAddr, pKeyDesc->BSSID)) + { + macIsBroadcast = TI_TRUE; + } + + encodedKeyMaterial.keyLen = pKeyDesc->KeyLength; + } + else /* this is TKIP or CKIP */ + { + if ((pKeyDesc->KeyLength == CKIP_KEY_LEN) && (pKeyParser->pPaeConfig->unicastSuite == TWD_CIPHER_CKIP)) + { + os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); + encodedKeyMaterial.keyLen = pKeyDesc->KeyLength; + } + else + { + os_memoryCopy(pKeyParser->hOs, + &keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN], + pKeyDesc->KeyMaterial, + pKeyDesc->KeyLength); + + encodedKeyMaterial.keyLen = MAC_ADDR_LEN+KEY_RSC_LEN+pKeyDesc->KeyLength; + } + } + + encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; + +TRACE2(pKeyParser->hReport, REPORT_SEVERITY_INFORMATION, "EXT_KEY_PARSER: Key received keyId=%x, keyLen=%d \n", pKeyDesc->KeyIndex, pKeyDesc->KeyLength ); + + if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) + { /* Pairwise key */ + /* check that the lower 8 bits of the key index are 0 */ + if (!wepKey && (pKeyDesc->KeyIndex & 0xff)) + { +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_WARNING, "EXT_KEY_PARSER: ERROR: Pairwise key must have index 0 !!!\n"); + return TI_NOK; + } + + if (macIsBroadcast) + { + TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Broadcast MAC address for unicast !!!\n"); + return TI_NOK; + } + if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) + { /* tx only pairwase key */ + /* set unicast keys */ + if (pKeyParser->pUcastKey->recvSuccess!=NULL) + { + status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial); + } + } else { + /* recieve only pairwase keys are not allowed */ + TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: recieve only pairwase keys are not allowed !!!\n"); + return TI_NOK; + } + + } + else + { /* set broadcast keys */ + if (!macIsBroadcast) + { /* not broadcast MAC */ + if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS) + { /* in IBSS only Broadcast MAC is allowed */ + TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: not broadcast MAC in IBSS mode !!!\n"); + return TI_NOK; + } + else if (!macEqual2Associated) + { /* ESS mode and MAC is different than the associated one */ + /* save the key for later */ + status = TI_OK; /* pKeyParser->pBcastKey->saveKey(pKeyParser->pBcastKey, &encodedKey);*/ + } + else + { /* MAC is equal to the associated one - configure immediately */ + if (!wepKey) + { + MAC_COPY (keyBuffer, broadcastMacAddr); + } + if (pKeyParser->pBcastKey->recvSuccess!=NULL) + { + status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial); + } + } + } + else + { /* MAC is broadcast - configure immediately */ + if (!wepKey) + { + MAC_COPY (keyBuffer, broadcastMacAddr); + } + + /* set broadcast key */ + if (pKeyParser->pBcastKey->recvSuccess!=NULL) + { + status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial); + } + + if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) + { /* Group key used to transmit */ + /* set as unicast key as well */ + if (pKeyParser->pUcastKey->recvSuccess!=NULL) + { + status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial); + } + } + } + } + + return status; +} + + + + +TI_STATUS keyParserExternal_remove(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) +{ + TI_STATUS status; + OS_802_11_KEY *pKeyDesc; + paramInfo_t macParam; + encodedKeyMaterial_t encodedKeyMaterial; + TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; + + if (pKeyData == NULL) + { +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n"); + return TI_NOK; + } + + pKeyDesc = (OS_802_11_KEY*)pKeyData; + + if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) + { /* Bit 31 should always be zero */ +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove TX bit in key index can't be 1\n"); + return TI_NOK; + } + if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) + { /* Bits 8-29 should always be zero */ +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove none zero key index\n"); + return TI_NOK; + } + + encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; + encodedKeyMaterial.keyLen = 0; + encodedKeyMaterial.pData = (char *) keyBuffer; + + if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) + { /* delete all pairwise keys or for the current BSSID */ + if (!MAC_EQUAL(pKeyDesc->BSSID, broadcastMacAddr)) + { + MAC_COPY (keyBuffer, pKeyDesc->BSSID); + } + else + { + macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; + status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); + if (status != TI_OK) + { +TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n"); + return TI_NOK; + } + + MAC_COPY (keyBuffer, macParam.content.ctrlDataCurrentBSSID); + } + + status = pKeyParser->pUcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); + } + else + { /* delete all group keys or for the current BSSID */ + MAC_COPY (keyBuffer, broadcastMacAddr); + status = pKeyParser->pBcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); + } + + return status; +} |