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