1/* 2 * keyParserExternal.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34/** \file keyParserExternal.c 35 * \brief External key parser implementation. 36 * 37 * \see keyParser.h 38*/ 39 40/**************************************************************************** 41 * * 42 * MODULE: External Key Parser * 43 * PURPOSE: EAP parser implementation * 44 * * 45 ****************************************************************************/ 46 47#define __FILE_ID__ FILE_ID_34 48#include "tidef.h" 49#include "osApi.h" 50#include "report.h" 51 52#include "keyTypes.h" 53 54#include "keyParser.h" 55#include "keyParserExternal.h" 56#include "mainKeysSm.h" 57#include "mainSecSm.h" 58#include "admCtrl.h" 59 60#include "unicastKeySM.h" 61#include "broadcastKeySM.h" 62#include "DataCtrl_Api.h" 63 64#define TKIP_KEY_LEN 32 65#define AES_KEY_LEN 16 66 67 68/** 69* 70* Function - Init KEY Parser module. 71* 72* \b Description: 73* 74* Called by RSN Manager. 75* Registers the function 'rsn_keyParserRecv()' at the distributor to receive KEY frames upon receiving a KEY_RECV event. 76* 77* \b ARGS: 78* 79* 80* \b RETURNS: 81* 82* TI_STATUS - 0 on success, any other value on failure. 83* 84*/ 85 86TI_STATUS keyParserExternal_config(struct _keyParser_t *pKeyParser) 87{ 88 pKeyParser->recv = keyParserExternal_recv; 89 pKeyParser->replayReset = keyParser_nop; 90 pKeyParser->remove = keyParserExternal_remove; 91 return TI_OK; 92} 93 94 95/** 96* 97* keyParserExternal_recv 98* 99* \b Description: 100* 101* External key Parser receive function: 102* - Called by NDIS (Windows) upon receiving an External Key. 103* - Filters the following keys: 104* - Keys with invalid key index 105* - Keys with invalid MAC address 106* 107* \b ARGS: 108* 109* I - pKeyParser - Pointer to the keyParser context \n 110* I - pKeyData - A pointer to the Key Data. \n 111* I - keyDataLen - The Key Data length. \n 112* 113* \b RETURNS: 114* 115* TI_OK on success, TI_NOK otherwise. 116* 117*/ 118 119TI_STATUS keyParserExternal_recv(struct _keyParser_t *pKeyParser, 120 TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) 121{ 122 TI_STATUS status; 123 OS_802_11_KEY *pKeyDesc; 124 encodedKeyMaterial_t encodedKeyMaterial; 125 paramInfo_t macParam; 126 TI_BOOL macEqual2Associated=TI_FALSE; 127 TI_BOOL macIsBroadcast=TI_FALSE; 128 TI_BOOL wepKey = TI_FALSE; 129 TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 130 TI_UINT8 nullMacAddr[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 131 TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; 132 133 134 if (pKeyData == NULL) 135 { 136TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n"); 137 return TI_NOK; 138 } 139 140 pKeyDesc = (OS_802_11_KEY*)pKeyData; 141 142 /* copy the key data, mac address and RSC */ 143 MAC_COPY (keyBuffer, pKeyDesc->BSSID); 144 /* configure keyRSC value (if needed) */ 145 if (pKeyDesc->KeyIndex & EXT_KEY_RSC_KEY_MASK) 146 { /* set key recieve sequence counter */ 147 os_memoryCopy(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], (TI_UINT8*)&(pKeyDesc->KeyRSC), KEY_RSC_LEN); 148 } 149 else 150 { 151 os_memoryZero(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], KEY_RSC_LEN); 152 } 153 154 /* check type and validity of keys */ 155 /* check MAC Address validity */ 156 macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; 157 status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); 158 159 if (status != TI_OK) 160 { 161TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n"); 162 return TI_NOK; 163 } 164 165 /* check key length */ 166 if((pKeyDesc->KeyLength != WEP_KEY_LEN_40) && 167 (pKeyDesc->KeyLength != WEP_KEY_LEN_104) && 168 (pKeyDesc->KeyLength != WEP_KEY_LEN_232) && 169 (pKeyDesc->KeyLength != TKIP_KEY_LEN) && 170 (pKeyDesc->KeyLength != AES_KEY_LEN) ) 171 172 { 173TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Incorrect key length - %d \n", pKeyDesc->KeyLength); 174 return TI_NOK; 175 } 176 if (MAC_EQUAL(macParam.content.ctrlDataCurrentBSSID, pKeyDesc->BSSID)) 177 { 178 macEqual2Associated = TI_TRUE; 179 } 180 if (MAC_EQUAL (pKeyDesc->BSSID, broadcastMacAddr)) 181 { 182 macIsBroadcast = TI_TRUE; 183 } 184 if ((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || 185 (pKeyDesc->KeyLength == WEP_KEY_LEN_104) || 186 (pKeyDesc->KeyLength == WEP_KEY_LEN_232)) 187 { /* In Add WEP the MAC address is nulled, since it's irrelevant */ 188 macEqual2Associated = TI_TRUE; 189 wepKey = TI_TRUE; 190 } 191 192 if (pKeyDesc->KeyIndex & EXT_KEY_SUPP_AUTHENTICATOR_MASK) 193 { /* The key is being set by an Authenticator - not allowed in IBSS mode */ 194 if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS) 195 { /* in IBSS only Broadcast MAC is allowed */ 196 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Authenticator set key in IBSS mode !!!\n"); 197 return TI_NOK; 198 } 199 200 } 201 202 if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) 203 { /* the reamining bits in the key index are not 0 (when they should be) */ 204TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Key index bits 8-27 should be 0 !!!\n"); 205 return TI_NOK; 206 } 207 208 encodedKeyMaterial.pData = (char *) keyBuffer; 209 /* Check key length according to the cipher suite - TKIP, etc...??? */ 210 if (wepKey) 211 { 212 if (!((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || (pKeyDesc->KeyLength == WEP_KEY_LEN_104) 213 || (pKeyDesc->KeyLength == WEP_KEY_LEN_232))) 214 { /*Invalid key length*/ 215 TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "WEP_KEY_PARSER: ERROR: Invalid Key length: %d !!!\n", pKeyDesc->KeyLength); 216 return TI_NOK; 217 } 218 219 os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); 220 if (MAC_EQUAL (nullMacAddr, pKeyDesc->BSSID)) 221 { 222 macIsBroadcast = TI_TRUE; 223 } 224 225 encodedKeyMaterial.keyLen = pKeyDesc->KeyLength; 226 } 227 else /* this is TKIP or CKIP */ 228 { 229 if ((pKeyDesc->KeyLength == AES_KEY_LEN) && (pKeyParser->pPaeConfig->unicastSuite == TWD_CIPHER_CKIP)) 230 { 231 os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); 232 encodedKeyMaterial.keyLen = pKeyDesc->KeyLength; 233 } 234 else 235 { 236 os_memoryCopy(pKeyParser->hOs, 237 &keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN], 238 pKeyDesc->KeyMaterial, 239 pKeyDesc->KeyLength); 240 241 encodedKeyMaterial.keyLen = MAC_ADDR_LEN+KEY_RSC_LEN+pKeyDesc->KeyLength; 242 } 243 } 244 245 encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; 246 247TRACE2(pKeyParser->hReport, REPORT_SEVERITY_INFORMATION, "EXT_KEY_PARSER: Key received keyId=%x, keyLen=%d \n", pKeyDesc->KeyIndex, pKeyDesc->KeyLength ); 248 249 if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) 250 { /* Pairwise key */ 251 /* check that the lower 8 bits of the key index are 0 */ 252 if (!wepKey && (pKeyDesc->KeyIndex & 0xff)) 253 { 254TRACE0(pKeyParser->hReport, REPORT_SEVERITY_WARNING, "EXT_KEY_PARSER: ERROR: Pairwise key must have index 0 !!!\n"); 255 return TI_NOK; 256 } 257 258 if (macIsBroadcast) 259 { 260 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Broadcast MAC address for unicast !!!\n"); 261 return TI_NOK; 262 } 263 if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) 264 { /* tx only pairwase key */ 265 /* set unicast keys */ 266 if (pKeyParser->pUcastKey->recvSuccess!=NULL) 267 { 268 status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial); 269 } 270 } else { 271 /* recieve only pairwase keys are not allowed */ 272 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: recieve only pairwase keys are not allowed !!!\n"); 273 return TI_NOK; 274 } 275 276 } 277 else 278 { /* set broadcast keys */ 279 if (!macIsBroadcast) 280 { /* not broadcast MAC */ 281 if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS) 282 { /* in IBSS only Broadcast MAC is allowed */ 283 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: not broadcast MAC in IBSS mode !!!\n"); 284 return TI_NOK; 285 } 286 else if (!macEqual2Associated) 287 { /* ESS mode and MAC is different than the associated one */ 288 /* save the key for later */ 289 status = TI_OK; /* pKeyParser->pBcastKey->saveKey(pKeyParser->pBcastKey, &encodedKey);*/ 290 } 291 else 292 { /* MAC is equal to the associated one - configure immediately */ 293 if (!wepKey) 294 { 295 MAC_COPY (keyBuffer, broadcastMacAddr); 296 } 297 if (pKeyParser->pBcastKey->recvSuccess!=NULL) 298 { 299 status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial); 300 } 301 } 302 } 303 else 304 { /* MAC is broadcast - configure immediately */ 305 if (!wepKey) 306 { 307 MAC_COPY (keyBuffer, broadcastMacAddr); 308 } 309 310 /* set broadcast key */ 311 if (pKeyParser->pBcastKey->recvSuccess!=NULL) 312 { 313 status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial); 314 } 315 316 if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) 317 { /* Group key used to transmit */ 318 /* set as unicast key as well */ 319 if (pKeyParser->pUcastKey->recvSuccess!=NULL) 320 { 321 status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial); 322 } 323 } 324 } 325 } 326 327 return status; 328} 329 330 331 332 333TI_STATUS keyParserExternal_remove(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) 334{ 335 TI_STATUS status; 336 OS_802_11_KEY *pKeyDesc; 337 paramInfo_t macParam; 338 encodedKeyMaterial_t encodedKeyMaterial; 339 TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 340 TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; 341 342 if (pKeyData == NULL) 343 { 344TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n"); 345 return TI_NOK; 346 } 347 348 pKeyDesc = (OS_802_11_KEY*)pKeyData; 349 350 if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) 351 { /* Bit 31 should always be zero */ 352TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove TX bit in key index can't be 1\n"); 353 return TI_NOK; 354 } 355 if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) 356 { /* Bits 8-29 should always be zero */ 357TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove none zero key index\n"); 358 return TI_NOK; 359 } 360 361 encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; 362 encodedKeyMaterial.keyLen = 0; 363 encodedKeyMaterial.pData = (char *) keyBuffer; 364 365 if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) 366 { /* delete all pairwise keys or for the current BSSID */ 367 if (!MAC_EQUAL(pKeyDesc->BSSID, broadcastMacAddr)) 368 { 369 MAC_COPY (keyBuffer, pKeyDesc->BSSID); 370 } 371 else 372 { 373 macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; 374 status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); 375 if (status != TI_OK) 376 { 377TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n"); 378 return TI_NOK; 379 } 380 381 MAC_COPY (keyBuffer, macParam.content.ctrlDataCurrentBSSID); 382 } 383 384 status = pKeyParser->pUcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); 385 } 386 else 387 { /* delete all group keys or for the current BSSID */ 388 MAC_COPY (keyBuffer, broadcastMacAddr); 389 status = pKeyParser->pBcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); 390 } 391 392 return status; 393} 394