1/*
2 * mainSecSm.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 mainSecSm.c
35 *  \brief 802.1X finite state machine header file
36 *
37 *  \see mainSecSm.h
38 */
39
40
41/***************************************************************************/
42/*                                                                         */
43/*      MODULE: mainSecSm.c                                                */
44/*    PURPOSE:  Main Security State Machine API                            */
45/*                                                                         */
46/***************************************************************************/
47
48#define __FILE_ID__  FILE_ID_39
49#include "osApi.h"
50#include "paramOut.h"
51#include "report.h"
52#include "DataCtrl_Api.h"
53#include "smeApi.h"
54#include "rsn.h"
55#include "rsnApi.h"
56#include "mainSecSm.h"
57#include "mainSecNull.h"
58#include "mainSecKeysOnly.h"
59#include "mainKeysSm.h"
60#include "externalSec.h"
61
62/* Constants */
63
64/** number of events in the state machine */
65#define MAIN_SEC_MAX_NUM_EVENTS     7
66
67/** number of states in the state machine */
68#define MAIN_SEC_MAX_NUM_STATES     6
69
70/* Enumerations */
71
72/* Typedefs */
73
74/* Structures */
75
76/* External data definitions */
77
78/* External functions definitions */
79
80/* Global variables */
81
82/* Local function prototypes */
83
84TI_STATUS mainSec_setKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey);
85TI_STATUS mainSec_removeKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey);
86TI_STATUS mainSec_setDefaultKeyId(struct _mainSec_t *pMainSec, TI_UINT8 keyId);
87
88/* functions */
89
90/**
91*
92* mainSec_create
93*
94* \b Description:
95*
96* Allocate memory for the main security context, and create all the rest of the needed contexts.
97*
98* \b ARGS:
99*
100*  I - hOs - OS handle for OS operations.
101*
102* \b RETURNS:
103*
104*  pointer to main security context. If failed, returns NULL.
105*
106* \sa
107*/
108mainSec_t* mainSec_create(TI_HANDLE hOs)
109{
110    mainSec_t   *pHandle;
111    TI_STATUS       status;
112
113    /* allocate association context memory */
114    pHandle = (mainSec_t*)os_memoryAlloc(hOs, sizeof(mainSec_t));
115    if (pHandle == NULL)
116    {
117        return NULL;
118    }
119
120    os_memoryZero(hOs, pHandle, sizeof(mainSec_t));
121
122    /* allocate memory for association state machine */
123    status = fsm_Create(hOs, &pHandle->pMainSecSm, MAIN_SEC_MAX_NUM_STATES, MAIN_SEC_MAX_NUM_EVENTS);
124    if (status != TI_OK)
125    {
126        os_memoryFree(hOs, pHandle, sizeof(mainSec_t));
127        return NULL;
128    }
129
130    pHandle->pMainKeys = mainKeys_create(hOs);
131    if (pHandle->pMainKeys == NULL)
132    {
133        fsm_Unload(hOs, pHandle->pMainSecSm);
134        os_memoryFree(hOs, pHandle, sizeof(mainSec_t));
135        return NULL;
136    }
137
138    pHandle->pKeyParser = pHandle->pMainKeys->pKeyParser;
139    pHandle->hOs = hOs;
140
141    /* created only for external security mode */
142    pHandle->pExternalSec = externalSec_create(hOs);
143    if (pHandle->pExternalSec == NULL)
144    {
145        mainKeys_unload(pHandle->pMainKeys);
146        fsm_Unload(hOs, pHandle->pMainSecSm);
147        os_memoryFree(hOs, pHandle, sizeof(mainSec_t));
148        return NULL;
149    }
150
151    return pHandle;
152}
153
154/**
155*
156* mainSec_config
157*
158* \b Description:
159*
160* Init main security state machine state machine
161*
162* \b ARGS:
163*
164*  none
165*
166* \b RETURNS:
167*
168*  TI_OK on success, TI_NOK otherwise.
169*
170* \sa
171*/
172TI_STATUS mainSec_config (mainSec_t *pMainSec,
173                          mainSecInitData_t *pInitData,
174                          void *pParent,
175                          TI_HANDLE hReport,
176                          TI_HANDLE hOs,
177                          TI_HANDLE hCtrlData,
178                          TI_HANDLE hEvHandler,
179                          TI_HANDLE hConn,
180                          TI_HANDLE hTimer)
181{
182    TI_STATUS               status;
183
184    pMainSec->setKey = mainSec_setKey;
185    pMainSec->removeKey = mainSec_removeKey;
186    pMainSec->setDefaultKeyId = mainSec_setDefaultKeyId;
187
188    pMainSec->pParent = pParent;
189    pMainSec->hReport = hReport;
190    pMainSec->hOs = hOs;
191
192    TRACE4(pMainSec->hReport, REPORT_SEVERITY_SM, "MainSec SM: config, authProtocol = %d, keyExchangeProtocol=%d, unicastSuite=%d, broadcastSuite=%d\n", pInitData->pPaeConfig->authProtocol, pInitData->pPaeConfig->keyExchangeProtocol, pInitData->pPaeConfig->unicastSuite, pInitData->pPaeConfig->broadcastSuite);
193
194    if (TI_TRUE == pMainSec->pParent->bRsnExternalMode)
195    {
196            status = externalSec_config(pMainSec);
197    }
198    else
199    {
200         switch (pInitData->pPaeConfig->keyExchangeProtocol)
201         {
202            case RSN_KEY_MNG_NONE:
203                status = mainSecSmNull_config(pMainSec, pInitData->pPaeConfig);
204                break;
205            case RSN_KEY_MNG_802_1X:
206                status = mainSecKeysOnly_config(pMainSec, pInitData->pPaeConfig);
207                break;
208            default:
209                status = mainSecSmNull_config(pMainSec, pInitData->pPaeConfig);
210                break;
211         }
212    }
213
214    status  = mainKeys_config (pMainSec->pMainKeys,
215                               pInitData->pPaeConfig,
216                               pMainSec,
217                               pMainSec->hReport,
218                               pMainSec->hOs,
219                               hCtrlData,
220                               hEvHandler,
221                               hConn,
222                               pMainSec->pParent,
223                               hTimer);
224    if (status != TI_OK)
225    {
226        TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: error in configuring mainKeys SM\n");
227        return status;
228    }
229
230    TRACE0(pMainSec->hReport, REPORT_SEVERITY_SM, "MAIN_SEC_SM: successful configuration SM\n");
231
232    return status;
233}
234
235/**
236*
237* mainSec_config
238*
239* \b Description:
240*
241* Init main security state machine state machine
242*
243* \b ARGS:
244*
245*  none
246*
247* \b RETURNS:
248*
249*  TI_OK on success, TI_NOK otherwise.
250*
251* \sa
252*/
253TI_STATUS mainSec_unload(mainSec_t *pMainSec)
254{
255    TI_STATUS   status;
256
257    if (pMainSec == NULL)
258    {
259        return TI_NOK;
260    }
261
262    status = mainKeys_unload(pMainSec->pMainKeys);
263    if (status != TI_OK)
264    {
265        /* report failure but don't stop... */
266        TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: Error releasing Main Keys SM memory \n");
267    }
268
269    status = fsm_Unload(pMainSec->hOs, pMainSec->pMainSecSm);
270    if (status != TI_OK)
271    {
272        /* report failure but don't stop... */
273        TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: Error releasing FSM memory \n");
274    }
275
276    status = externalSec_unload(pMainSec->pExternalSec);
277    if (status != TI_OK)
278    {
279        /* report failure but don't stop... */
280        TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: Error releasing ExternalSec memory \n");
281    }
282
283    os_memoryFree(pMainSec->hOs, pMainSec, sizeof(mainSec_t));
284
285    return TI_OK;
286}
287
288/**
289*
290* mainSec_setKey
291*
292* \b Description:
293*
294* Start the NULL main security SM. Reports success to the rsn module immediately.
295*
296* \b ARGS:
297*
298*  none
299*
300* \b RETURNS:
301*
302*  TI_OK on success, TI_NOK otherwise.
303*
304* \sa
305*/
306TI_STATUS mainSec_setKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey)
307{
308    TI_STATUS               status = TI_OK;
309
310    if ((pMainSec == NULL) || (pKey == NULL))
311    {
312        return TI_NOK;
313    }
314
315    if (pKey->keyType != KEY_NULL)
316    {
317        TRACE6(pMainSec->hReport, REPORT_SEVERITY_INFORMATION, "MAIN_SEC_SM: setting key #%d, value = 0x%X 0x%X 0x%X 0x%X 0x%X\n", pKey->keyIndex, (TI_UINT8)pKey->encKey[0], (TI_UINT8)pKey->encKey[1], (TI_UINT8)pKey->encKey[2], (TI_UINT8)pKey->encKey[3], (TI_UINT8)pKey->encKey[4]);
318
319        status = pMainSec->pParent->setKey(pMainSec->pParent, pKey);
320    }
321
322    return status;
323}
324
325/**
326*
327* mainSec_removeKey
328*
329* \b Description:
330*
331* Start the NULL main security SM. Reports success to the rsn module immediately.
332*
333* \b ARGS:
334*
335*  none
336*
337* \b RETURNS:
338*
339*  TI_OK on success, TI_NOK otherwise.
340*
341* \sa
342*/
343TI_STATUS mainSec_removeKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey)
344{
345    TI_STATUS               status = TI_OK;
346
347    if ((pMainSec == NULL) || (pKey == NULL))
348    {
349        return TI_NOK;
350    }
351
352    if (pKey->keyType != KEY_NULL)
353    {
354        TRACE1(pMainSec->hReport, REPORT_SEVERITY_INFORMATION, "MAIN_SEC_SM: removing key #%d, \n", pKey->keyIndex);
355
356        status = pMainSec->pParent->removeKey(pMainSec->pParent, pKey);
357    }
358
359    return status;
360}
361
362/**
363*
364* mainSec_setDefaultKeyId
365*
366* \b Description:
367*
368* Start the NULL main security SM. Reports success to the rsn module immediately.
369*
370* \b ARGS:
371*
372*  none
373*
374* \b RETURNS:
375*
376*  TI_OK on success, TI_NOK otherwise.
377*
378* \sa
379*/
380TI_STATUS mainSec_setDefaultKeyId(struct _mainSec_t *pMainSec, TI_UINT8 keyId)
381{
382    TI_STATUS               status = TI_OK;
383
384    if (pMainSec == NULL)
385    {
386        return TI_NOK;
387    }
388
389    status = pMainSec->pParent->setDefaultKeyId(pMainSec->pParent, keyId);
390
391    return status;
392}
393
394
395