1 /** \file unicastKey802_1x.c 2 * \brief station unicast key 802_1x implementation 3 * 4 * \see unicastKey802_1x.h 5 */ 6 /**************************************************************************** 7 **+-----------------------------------------------------------------------+** 8 **| |** 9 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |** 10 **| All rights reserved. |** 11 **| |** 12 **| Redistribution and use in source and binary forms, with or without |** 13 **| modification, are permitted provided that the following conditions |** 14 **| are met: |** 15 **| |** 16 **| * Redistributions of source code must retain the above copyright |** 17 **| notice, this list of conditions and the following disclaimer. |** 18 **| * Redistributions in binary form must reproduce the above copyright |** 19 **| notice, this list of conditions and the following disclaimer in |** 20 **| the documentation and/or other materials provided with the |** 21 **| distribution. |** 22 **| * Neither the name Texas Instruments nor the names of its |** 23 **| contributors may be used to endorse or promote products derived |** 24 **| from this software without specific prior written permission. |** 25 **| |** 26 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |** 27 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |** 28 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |** 29 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |** 30 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |** 31 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |** 32 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |** 33 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |** 34 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |** 35 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |** 36 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |** 37 **| |** 38 **+-----------------------------------------------------------------------+** 39 ****************************************************************************/ 40 41 /**************************************************************************** 42 * * 43 * MODULE: station unicast key 802_1x * 44 * PURPOSE: station unicast key 802_1x implementation * 45 * * 46 ****************************************************************************/ 47 48 #include "osApi.h" 49 #include "utils.h" 50 #include "report.h" 51 #include "rsnApi.h" 52 53 #include "unicastKey802_1x.h" 54 #include "mainKeysSm.h" 55 56 /** number of states in the state machine */ 57 #define UCAST_KEY_802_1X_MAX_NUM_STATES 3 58 59 /** number of events in the state machine */ 60 #define UCAST_KEY_802_1X_MAX_NUM_EVENTS 4 61 62 63 TI_STATUS unicastKey802_1x_start(struct _unicastKey_t *pUnicastKey); 64 65 TI_STATUS unicastKey802_1x_stop(struct _unicastKey_t *pUnicastKey); 66 67 TI_STATUS unicastKey802_1x_recvSuccess(struct _unicastKey_t *pUnicastKey, 68 encodedKeyMaterial_t *pEncodedKeyMaterial); 69 70 TI_STATUS unicastKey802_1x_recvFailure(struct _unicastKey_t *pUnicastKey); 71 72 TI_STATUS unicastKey802_1x_distribute(struct _unicastKey_t *pUnicastKey); 73 74 TI_STATUS unicastKey802_1x_redistribute(struct _unicastKey_t *pUnicastKey); 75 76 TI_STATUS unicastKey802_1x_event(struct _unicastKey_t *pUnicastKey, 77 UINT8 event, 78 void *pData); 79 80 81 82 /** 83 * 84 * Function - Config KEY Parser module. 85 * 86 * \b Description: 87 * 88 * Called by RSN Manager. 89 * Registers the function 'rsn_UnicastKeyRecv()' at the distributor to receive KEY frames upon receiving a KEY_RECV event. 90 * 91 * \b ARGS: 92 * 93 * 94 * \b RETURNS: 95 * 96 * TI_STATUS - 0 on success, any other value on failure. 97 * 98 */ 99 100 TI_STATUS unicastKey802_1x_config(struct _unicastKey_t *pUnicastKey) 101 { 102 TI_STATUS status = NOK; 103 104 /** 802.1X Station unicast key State Machine matrix */ 105 fsm_actionCell_t unicastKey802_1x_matrix[UCAST_KEY_802_1X_NUM_STATES][UCAST_KEY_802_1X_NUM_EVENTS] = 106 { 107 /* next state and actions for IDLE state */ 108 { {UCAST_KEY_802_1X_STATE_START, (fsm_Action_t)unicastKeySmNop}, 109 {UCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)unicastKeySmNop}, 110 {UCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)unicastKeySmNop}, 111 {UCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)unicastKeySmUnexpected} 112 }, 113 114 /* next state and actions for START state */ 115 { {UCAST_KEY_802_1X_STATE_START, (fsm_Action_t)unicastKeySmUnexpected}, 116 {UCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)unicastKeySmNop}, 117 {UCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)unicastKey802_1x_distribute}, 118 {UCAST_KEY_802_1X_STATE_START, (fsm_Action_t)unicastKeySmNop} 119 }, 120 121 /* next state and actions for COMPLETE state */ 122 { {UCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)unicastKeySmUnexpected}, 123 {UCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)unicastKeySmNop}, 124 {UCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)unicastKey802_1x_distribute}, 125 {UCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)unicastKeySmUnexpected} 126 } 127 }; 128 129 130 pUnicastKey->start = unicastKey802_1x_start; 131 pUnicastKey->stop = unicastKey802_1x_stop; 132 pUnicastKey->recvFailure = unicastKey802_1x_recvFailure; 133 pUnicastKey->recvSuccess = unicastKey802_1x_recvSuccess; 134 135 pUnicastKey->currentState = UCAST_KEY_802_1X_STATE_IDLE; 136 137 status = fsm_Config(pUnicastKey->pUcastKeySm, 138 &unicastKey802_1x_matrix[0][0], 139 UCAST_KEY_802_1X_NUM_STATES, 140 UCAST_KEY_802_1X_NUM_EVENTS, 141 NULL, pUnicastKey->hOs); 142 143 144 return status; 145 } 146 147 148 149 /** 150 * 151 * unicastKey802_1x_event 152 * 153 * \b Description: 154 * 155 * 802.1x station unicast key state machine transition function 156 * 157 * \b ARGS: 158 * 159 * I/O - currentState - current state in the state machine\n 160 * I - event - specific event for the state machine\n 161 * I - pData - Data for state machine action function\n 162 * 163 * \b RETURNS: 164 * 165 * OK on success, NOK otherwise. 166 * 167 * \sa 168 */ 169 #ifdef REPORT_LOG 170 171 static char *unicastKey802_1x_stateDesc[UCAST_KEY_802_1X_NUM_STATES] = { 172 "STATE_IDLE", 173 "STATE_START", 174 "STATE_COMPLETE", 175 }; 176 177 static char *unicastKey802_1x_eventDesc[UCAST_KEY_802_1X_NUM_EVENTS] = { 178 "EVENT_START", 179 "EVENT_STOP", 180 "EVENT_SUCCESS", 181 "EVENT_FAILURE" 182 }; 183 184 #endif 185 186 TI_STATUS unicastKey802_1x_event(struct _unicastKey_t *pUnicastKey, UINT8 event, void *pData) 187 { 188 TI_STATUS status; 189 UINT8 nextState; 190 191 status = fsm_GetNextState(pUnicastKey->pUcastKeySm, pUnicastKey->currentState, event, &nextState); 192 if (status != OK) 193 { 194 WLAN_REPORT_ERROR(pUnicastKey->hReport, RSN_MODULE_LOG, 195 ("UNICAST_KEY_802_1x: ERROR: failed getting next state\n")); 196 return NOK; 197 } 198 199 WLAN_REPORT_INFORMATION(pUnicastKey->hReport, RSN_MODULE_LOG, 200 ("STATION_UNICAST_KEY_802_1x: <%s, %s> --> %s\n", 201 unicastKey802_1x_stateDesc[pUnicastKey->currentState], 202 unicastKey802_1x_eventDesc[event], 203 unicastKey802_1x_stateDesc[nextState])); 204 205 status = fsm_Event(pUnicastKey->pUcastKeySm, &pUnicastKey->currentState, event, pData); 206 207 return status; 208 } 209 210 211 /** 212 * 213 * unicastKey802_1x_start 214 * 215 * \b Description: 216 * 217 * START event handler 218 * 219 * \b ARGS: 220 * 221 * I - pCtrlB - station control block \n 222 * 223 * \b RETURNS: 224 * 225 * OK on success, NOK otherwise. 226 * 227 * \sa unicastKey802_1x_stop() 228 */ 229 TI_STATUS unicastKey802_1x_start(struct _unicastKey_t *pUnicastKey) 230 { 231 TI_STATUS status; 232 233 status = unicastKey802_1x_event(pUnicastKey, UCAST_KEY_802_1X_EVENT_START, pUnicastKey); 234 235 return status; 236 } 237 238 239 /** 240 * 241 * unicastKey802_1x_stop 242 * 243 * \b Description: 244 * 245 * START event handler 246 * 247 * \b ARGS: 248 * 249 * I - pCtrlB - station control block \n 250 * 251 * \b RETURNS: 252 * 253 * OK on success, NOK otherwise. 254 * 255 * \sa unicastKey802_1x_start() 256 */ 257 TI_STATUS unicastKey802_1x_stop(struct _unicastKey_t *pUnicastKey) 258 { 259 TI_STATUS status; 260 261 status = unicastKey802_1x_event(pUnicastKey, UCAST_KEY_802_1X_EVENT_STOP, pUnicastKey); 262 263 return status; 264 } 265 266 267 /** 268 * 269 * unicastKey802_1x_recvSuccess 270 * 271 * \b Description: 272 * 273 * SUCCESS event handler 274 * 275 * \b ARGS: 276 * 277 * I - pCtrlB - station control block \n 278 * I - pEncodedKeyMaterial - Encoded key material \n 279 * 280 * \b RETURNS: 281 * 282 * OK on success, NOK otherwise. 283 * 284 */ 285 TI_STATUS unicastKey802_1x_recvSuccess(struct _unicastKey_t *pUnicastKey, encodedKeyMaterial_t *pEncodedKeyMaterial) 286 { 287 TI_STATUS status; 288 289 pUnicastKey->data.pEncodedKeyMaterial = pEncodedKeyMaterial; 290 291 status = unicastKey802_1x_event(pUnicastKey, UCAST_KEY_802_1X_EVENT_SUCCESS, pUnicastKey); 292 293 return status; 294 } 295 296 297 /** 298 * 299 * unicastKey802_1x_recvFailure 300 * 301 * \b Description: 302 * 303 * FAILURE event handler 304 * 305 * \b ARGS: 306 * 307 * I - pCtrlB - station control block \n 308 * 309 * \b RETURNS: 310 * 311 * OK on success, NOK otherwise. 312 * 313 */ 314 TI_STATUS unicastKey802_1x_recvFailure(struct _unicastKey_t *pUnicastKey) 315 { 316 TI_STATUS status; 317 318 status = unicastKey802_1x_event(pUnicastKey, UCAST_KEY_802_1X_EVENT_FAILURE, pUnicastKey); 319 320 return status; 321 } 322 323 324 /** 325 * 326 * unicastKey802_1x_distribute 327 * 328 * \b Description: 329 * 330 * Distribute unicast key material to the driver and report the main key SM on unicast complete. 331 * 332 * \b ARGS: 333 * 334 * I - pData - Encoded key material \n 335 * 336 * \b RETURNS: 337 * 338 * OK on success, NOK otherwise. 339 */ 340 TI_STATUS unicastKey802_1x_distribute(struct _unicastKey_t *pUnicastKey) 341 { 342 TI_STATUS status=NOK; 343 344 if (pUnicastKey->pKeyDerive->derive!=NULL) 345 { 346 status = pUnicastKey->pKeyDerive->derive(pUnicastKey->pKeyDerive, 347 pUnicastKey->data.pEncodedKeyMaterial); 348 } 349 if (status != OK) 350 { 351 return NOK; 352 } 353 354 if (pUnicastKey->pParent->setDefaultKeyId!=NULL) 355 { 356 status = pUnicastKey->pParent->setDefaultKeyId(pUnicastKey->pParent, 357 (UINT8)pUnicastKey->data.pEncodedKeyMaterial->keyId); 358 } 359 if (status != OK) 360 { 361 return status; 362 } 363 364 if (pUnicastKey->pParent->reportUcastStatus!=NULL) 365 { 366 status = pUnicastKey->pParent->reportUcastStatus(pUnicastKey->pParent, OK); 367 } 368 369 return status; 370 } 371