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 84 TI_STATUS mainSec_setKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey); 85 TI_STATUS mainSec_removeKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey); 86 TI_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 */ 108 mainSec_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 144 if (pHandle->pExternalSec == NULL) 145 { 146 fsm_Unload(hOs, pHandle->pMainSecSm); 147 mainKeys_unload(pHandle->pMainKeys); 148 os_memoryFree(hOs, pHandle, sizeof(mainSec_t)); 149 return NULL; 150 } 151 152 return pHandle; 153 } 154 155 /** 156 * 157 * mainSec_config 158 * 159 * \b Description: 160 * 161 * Init main security state machine state machine 162 * 163 * \b ARGS: 164 * 165 * none 166 * 167 * \b RETURNS: 168 * 169 * TI_OK on success, TI_NOK otherwise. 170 * 171 * \sa 172 */ 173 TI_STATUS mainSec_config (mainSec_t *pMainSec, 174 mainSecInitData_t *pInitData, 175 void *pParent, 176 TI_HANDLE hReport, 177 TI_HANDLE hOs, 178 TI_HANDLE hCtrlData, 179 TI_HANDLE hEvHandler, 180 TI_HANDLE hConn, 181 TI_HANDLE hTimer) 182 { 183 TI_STATUS status; 184 185 pMainSec->setKey = mainSec_setKey; 186 pMainSec->removeKey = mainSec_removeKey; 187 pMainSec->setDefaultKeyId = mainSec_setDefaultKeyId; 188 189 pMainSec->pParent = pParent; 190 pMainSec->hReport = hReport; 191 pMainSec->hOs = hOs; 192 193 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); 194 195 if (TI_TRUE == pMainSec->pParent->bRsnExternalMode) 196 { 197 status = externalSec_config(pMainSec); 198 } 199 else 200 { 201 switch (pInitData->pPaeConfig->keyExchangeProtocol) 202 { 203 case RSN_KEY_MNG_NONE: 204 status = mainSecSmNull_config(pMainSec, pInitData->pPaeConfig); 205 break; 206 case RSN_KEY_MNG_802_1X: 207 status = mainSecKeysOnly_config(pMainSec, pInitData->pPaeConfig); 208 break; 209 default: 210 status = mainSecSmNull_config(pMainSec, pInitData->pPaeConfig); 211 break; 212 } 213 } 214 215 status = mainKeys_config (pMainSec->pMainKeys, 216 pInitData->pPaeConfig, 217 pMainSec, 218 pMainSec->hReport, 219 pMainSec->hOs, 220 hCtrlData, 221 hEvHandler, 222 hConn, 223 pMainSec->pParent, 224 hTimer); 225 if (status != TI_OK) 226 { 227 TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: error in configuring mainKeys SM\n"); 228 return status; 229 } 230 231 TRACE0(pMainSec->hReport, REPORT_SEVERITY_SM, "MAIN_SEC_SM: successful configuration SM\n"); 232 233 return status; 234 } 235 236 /** 237 * 238 * mainSec_config 239 * 240 * \b Description: 241 * 242 * Init main security state machine state machine 243 * 244 * \b ARGS: 245 * 246 * none 247 * 248 * \b RETURNS: 249 * 250 * TI_OK on success, TI_NOK otherwise. 251 * 252 * \sa 253 */ 254 TI_STATUS mainSec_unload(mainSec_t *pMainSec) 255 { 256 TI_STATUS status; 257 258 if (pMainSec == NULL) 259 { 260 return TI_NOK; 261 } 262 263 status = mainKeys_unload(pMainSec->pMainKeys); 264 if (status != TI_OK) 265 { 266 /* report failure but don't stop... */ 267 TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: Error releasing Main Keys SM memory \n"); 268 } 269 270 status = fsm_Unload(pMainSec->hOs, pMainSec->pMainSecSm); 271 if (status != TI_OK) 272 { 273 /* report failure but don't stop... */ 274 TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: Error releasing FSM memory \n"); 275 } 276 277 status = externalSec_Destroy (pMainSec->pExternalSec); 278 if (status != TI_OK) 279 { 280 /* report failure but don't stop... */ 281 TRACE0(pMainSec->hReport, REPORT_SEVERITY_ERROR, "MAIN_SEC_SM: Error releasing External Security SM memory \n"); 282 } 283 284 os_memoryFree(pMainSec->hOs, pMainSec, sizeof(mainSec_t)); 285 286 return TI_OK; 287 } 288 289 /** 290 * 291 * mainSec_setKey 292 * 293 * \b Description: 294 * 295 * Start the NULL main security SM. Reports success to the rsn module immediately. 296 * 297 * \b ARGS: 298 * 299 * none 300 * 301 * \b RETURNS: 302 * 303 * TI_OK on success, TI_NOK otherwise. 304 * 305 * \sa 306 */ 307 TI_STATUS mainSec_setKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey) 308 { 309 TI_STATUS status = TI_OK; 310 311 if ((pMainSec == NULL) || (pKey == NULL)) 312 { 313 return TI_NOK; 314 } 315 316 if (pKey->keyType != KEY_NULL) 317 { 318 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]); 319 320 status = pMainSec->pParent->setKey(pMainSec->pParent, pKey); 321 } 322 323 return status; 324 } 325 326 /** 327 * 328 * mainSec_removeKey 329 * 330 * \b Description: 331 * 332 * Start the NULL main security SM. Reports success to the rsn module immediately. 333 * 334 * \b ARGS: 335 * 336 * none 337 * 338 * \b RETURNS: 339 * 340 * TI_OK on success, TI_NOK otherwise. 341 * 342 * \sa 343 */ 344 TI_STATUS mainSec_removeKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey) 345 { 346 TI_STATUS status = TI_OK; 347 348 if ((pMainSec == NULL) || (pKey == NULL)) 349 { 350 return TI_NOK; 351 } 352 353 if (pKey->keyType != KEY_NULL) 354 { 355 TRACE1(pMainSec->hReport, REPORT_SEVERITY_INFORMATION, "MAIN_SEC_SM: removing key #%d, \n", pKey->keyIndex); 356 357 status = pMainSec->pParent->removeKey(pMainSec->pParent, pKey); 358 } 359 360 return status; 361 } 362 363 /** 364 * 365 * mainSec_setDefaultKeyId 366 * 367 * \b Description: 368 * 369 * Start the NULL main security SM. Reports success to the rsn module immediately. 370 * 371 * \b ARGS: 372 * 373 * none 374 * 375 * \b RETURNS: 376 * 377 * TI_OK on success, TI_NOK otherwise. 378 * 379 * \sa 380 */ 381 TI_STATUS mainSec_setDefaultKeyId(struct _mainSec_t *pMainSec, TI_UINT8 keyId) 382 { 383 TI_STATUS status = TI_OK; 384 385 if (pMainSec == NULL) 386 { 387 return TI_NOK; 388 } 389 390 status = pMainSec->pParent->setDefaultKeyId(pMainSec->pParent, keyId); 391 392 return status; 393 } 394 395 396