4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 /** \file keyParserExternal.c
35 * \brief External key parser implementation.
40 /****************************************************************************
42 * MODULE: External Key Parser *
43 * PURPOSE: EAP parser implementation *
45 ****************************************************************************/
47 #define __FILE_ID__ FILE_ID_34
54 #include "keyParser.h"
55 #include "keyParserExternal.h"
56 #include "mainKeysSm.h"
57 #include "mainSecSm.h"
60 #include "unicastKeySM.h"
61 #include "broadcastKeySM.h"
62 #include "DataCtrl_Api.h"
64 #define CKIP_KEY_LEN 16
65 #define TKIP_KEY_LEN 32
66 #define AES_KEY_LEN 16
71 * Function - Init KEY Parser module.
75 * Called by RSN Manager.
76 * Registers the function 'rsn_keyParserRecv()' at the distributor to receive KEY frames upon receiving a KEY_RECV event.
83 * TI_STATUS - 0 on success, any other value on failure.
87 TI_STATUS keyParserExternal_config(struct _keyParser_t *pKeyParser)
89 pKeyParser->recv = keyParserExternal_recv;
90 pKeyParser->replayReset = keyParser_nop;
91 pKeyParser->remove = keyParserExternal_remove;
98 * keyParserExternal_recv
102 * External key Parser receive function:
103 * - Called by NDIS (Windows) upon receiving an External Key.
104 * - Filters the following keys:
105 * - Keys with invalid key index
106 * - Keys with invalid MAC address
110 * I - pKeyParser - Pointer to the keyParser context \n
111 * I - pKeyData - A pointer to the Key Data. \n
112 * I - keyDataLen - The Key Data length. \n
116 * TI_OK on success, TI_NOK otherwise.
120 TI_STATUS keyParserExternal_recv(struct _keyParser_t *pKeyParser,
121 TI_UINT8 *pKeyData, TI_UINT32 keyDataLen)
124 OS_802_11_KEY *pKeyDesc;
125 encodedKeyMaterial_t encodedKeyMaterial;
126 paramInfo_t macParam;
127 TI_BOOL macEqual2Associated=TI_FALSE;
128 TI_BOOL macIsBroadcast=TI_FALSE;
129 TI_BOOL wepKey = TI_FALSE;
130 TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
131 TI_UINT8 nullMacAddr[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
132 TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH];
135 if (pKeyData == NULL)
137 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n");
141 pKeyDesc = (OS_802_11_KEY*)pKeyData;
143 /* copy the key data, mac address and RSC */
144 MAC_COPY (keyBuffer, pKeyDesc->BSSID);
145 /* configure keyRSC value (if needed) */
146 if (pKeyDesc->KeyIndex & EXT_KEY_RSC_KEY_MASK)
147 { /* set key recieve sequence counter */
148 os_memoryCopy(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], (TI_UINT8*)&(pKeyDesc->KeyRSC), KEY_RSC_LEN);
152 os_memoryZero(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], KEY_RSC_LEN);
155 /* check type and validity of keys */
156 /* check MAC Address validity */
157 macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
158 status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam);
162 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n");
166 /* check key length */
167 if((pKeyDesc->KeyLength != WEP_KEY_LEN_40) &&
168 (pKeyDesc->KeyLength != WEP_KEY_LEN_104) &&
169 (pKeyDesc->KeyLength != WEP_KEY_LEN_232) &&
170 (pKeyDesc->KeyLength != CKIP_KEY_LEN) &&
171 (pKeyDesc->KeyLength != TKIP_KEY_LEN) &&
172 (pKeyDesc->KeyLength != AES_KEY_LEN) )
175 TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Incorrect key length - %d \n", pKeyDesc->KeyLength);
178 if (MAC_EQUAL(macParam.content.ctrlDataCurrentBSSID, pKeyDesc->BSSID))
180 macEqual2Associated = TI_TRUE;
182 if (MAC_EQUAL (pKeyDesc->BSSID, broadcastMacAddr))
184 macIsBroadcast = TI_TRUE;
186 if ((pKeyDesc->KeyLength == WEP_KEY_LEN_40) ||
187 (pKeyDesc->KeyLength == WEP_KEY_LEN_104) ||
188 (pKeyDesc->KeyLength == WEP_KEY_LEN_232))
189 { /* In Add WEP the MAC address is nulled, since it's irrelevant */
190 macEqual2Associated = TI_TRUE;
194 if (pKeyDesc->KeyIndex & EXT_KEY_SUPP_AUTHENTICATOR_MASK)
195 { /* The key is being set by an Authenticator - not allowed in IBSS mode */
196 if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS)
197 { /* in IBSS only Broadcast MAC is allowed */
198 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Authenticator set key in IBSS mode !!!\n");
204 if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK)
205 { /* the reamining bits in the key index are not 0 (when they should be) */
206 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Key index bits 8-27 should be 0 !!!\n");
210 encodedKeyMaterial.pData = (char *) keyBuffer;
211 /* Check key length according to the cipher suite - TKIP, etc...??? */
214 if (!((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || (pKeyDesc->KeyLength == WEP_KEY_LEN_104)
215 || (pKeyDesc->KeyLength == WEP_KEY_LEN_232)))
216 { /*Invalid key length*/
217 TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "WEP_KEY_PARSER: ERROR: Invalid Key length: %d !!!\n", pKeyDesc->KeyLength);
221 os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength);
222 if (MAC_EQUAL (nullMacAddr, pKeyDesc->BSSID))
224 macIsBroadcast = TI_TRUE;
227 encodedKeyMaterial.keyLen = pKeyDesc->KeyLength;
229 else /* this is TKIP or CKIP */
231 if ((pKeyDesc->KeyLength == CKIP_KEY_LEN) && (pKeyParser->pPaeConfig->unicastSuite == TWD_CIPHER_CKIP))
233 os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength);
234 encodedKeyMaterial.keyLen = pKeyDesc->KeyLength;
238 os_memoryCopy(pKeyParser->hOs,
239 &keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN],
240 pKeyDesc->KeyMaterial,
241 pKeyDesc->KeyLength);
243 encodedKeyMaterial.keyLen = MAC_ADDR_LEN+KEY_RSC_LEN+pKeyDesc->KeyLength;
247 encodedKeyMaterial.keyId = pKeyDesc->KeyIndex;
249 TRACE2(pKeyParser->hReport, REPORT_SEVERITY_INFORMATION, "EXT_KEY_PARSER: Key received keyId=%x, keyLen=%d \n", pKeyDesc->KeyIndex, pKeyDesc->KeyLength );
251 if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK)
253 /* check that the lower 8 bits of the key index are 0 */
254 if (!wepKey && (pKeyDesc->KeyIndex & 0xff))
256 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_WARNING, "EXT_KEY_PARSER: ERROR: Pairwise key must have index 0 !!!\n");
262 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Broadcast MAC address for unicast !!!\n");
265 if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK)
266 { /* tx only pairwase key */
267 /* set unicast keys */
268 if (pKeyParser->pUcastKey->recvSuccess!=NULL)
270 status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial);
273 /* recieve only pairwase keys are not allowed */
274 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: recieve only pairwase keys are not allowed !!!\n");
280 { /* set broadcast keys */
282 { /* not broadcast MAC */
283 if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS)
284 { /* in IBSS only Broadcast MAC is allowed */
285 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: not broadcast MAC in IBSS mode !!!\n");
288 else if (!macEqual2Associated)
289 { /* ESS mode and MAC is different than the associated one */
290 /* save the key for later */
291 status = TI_OK; /* pKeyParser->pBcastKey->saveKey(pKeyParser->pBcastKey, &encodedKey);*/
294 { /* MAC is equal to the associated one - configure immediately */
297 MAC_COPY (keyBuffer, broadcastMacAddr);
299 if (pKeyParser->pBcastKey->recvSuccess!=NULL)
301 status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial);
306 { /* MAC is broadcast - configure immediately */
309 MAC_COPY (keyBuffer, broadcastMacAddr);
312 /* set broadcast key */
313 if (pKeyParser->pBcastKey->recvSuccess!=NULL)
315 status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial);
318 if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK)
319 { /* Group key used to transmit */
320 /* set as unicast key as well */
321 if (pKeyParser->pUcastKey->recvSuccess!=NULL)
323 status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial);
335 TI_STATUS keyParserExternal_remove(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen)
338 OS_802_11_KEY *pKeyDesc;
339 paramInfo_t macParam;
340 encodedKeyMaterial_t encodedKeyMaterial;
341 TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
342 TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH];
344 if (pKeyData == NULL)
346 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n");
350 pKeyDesc = (OS_802_11_KEY*)pKeyData;
352 if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK)
353 { /* Bit 31 should always be zero */
354 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove TX bit in key index can't be 1\n");
357 if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK)
358 { /* Bits 8-29 should always be zero */
359 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove none zero key index\n");
363 encodedKeyMaterial.keyId = pKeyDesc->KeyIndex;
364 encodedKeyMaterial.keyLen = 0;
365 encodedKeyMaterial.pData = (char *) keyBuffer;
367 if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK)
368 { /* delete all pairwise keys or for the current BSSID */
369 if (!MAC_EQUAL(pKeyDesc->BSSID, broadcastMacAddr))
371 MAC_COPY (keyBuffer, pKeyDesc->BSSID);
375 macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
376 status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam);
379 TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n");
383 MAC_COPY (keyBuffer, macParam.content.ctrlDataCurrentBSSID);
386 status = pKeyParser->pUcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial);
389 { /* delete all group keys or for the current BSSID */
390 MAC_COPY (keyBuffer, broadcastMacAddr);
391 status = pKeyParser->pBcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial);