1 /** \file broadcastKey802_1x.c 2 * \brief broadcast key 802.1x implementation 3 * 4 * \see broadcastKey802_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: 802.1x station broadcast key SM * 44 * PURPOSE: 802.1x station broadcast key SM implementation * 45 * * 46 ****************************************************************************/ 47 48 #include "osApi.h" 49 #include "utils.h" 50 #include "report.h" 51 #include "rsnApi.h" 52 53 #include "keyDerive.h" 54 55 #include "broadcastKey802_1x.h" 56 #include "mainKeysSm.h" 57 58 59 TI_STATUS broadcastKey802_1x_start(struct _broadcastKey_t *pBroadcastKey); 60 61 TI_STATUS broadcastKey802_1x_stop(struct _broadcastKey_t *pBroadcastKey); 62 63 TI_STATUS broadcastKey802_1x_recvSuccess(struct _broadcastKey_t *pBroadcastKey, 64 encodedKeyMaterial_t *pEncodedKeyMaterial); 65 66 TI_STATUS broadcastKey802_1x_recvFailure(struct _broadcastKey_t *pBroadcastKey); 67 68 TI_STATUS broadcastKey802_1x_distribute(struct _broadcastKey_t *pBroadcastKey); 69 70 TI_STATUS broadcastKey802_1x_redistribute(struct _broadcastKey_t *pBroadcastKey); 71 72 TI_STATUS broadcastKey802_1x_event(struct _broadcastKey_t *pBroadcastKey, 73 UINT8 event, 74 void *pData); 75 76 77 /** 78 * 79 * Function - Init KEY Parser module. 80 * 81 * \b Description: 82 * 83 * Called by RSN Manager. 84 * Registers the function 'rsn_BroadcastKeyRecv()' at the distributor to receive KEY frames upon receiving a KEY_RECV event. 85 * 86 * \b ARGS: 87 * 88 * 89 * \b RETURNS: 90 * 91 * TI_STATUS - 0 on success, any other value on failure. 92 * 93 */ 94 95 TI_STATUS broadcastKey802_1x_config(struct _broadcastKey_t *pBroadcastKey) 96 { 97 TI_STATUS status = NOK; 98 99 /** Station broadcast key State Machine matrix */ 100 fsm_actionCell_t broadcastKey802_1x_matrix[BCAST_KEY_802_1X_NUM_STATES][BCAST_KEY_802_1X_NUM_EVENTS] = 101 { 102 /* next state and actions for IDLE state */ 103 { {BCAST_KEY_802_1X_STATE_START, (fsm_Action_t)broadcastKeySmNop}, 104 {BCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)broadcastKeySmNop}, 105 {BCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)broadcastKeySmNop}, 106 {BCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)broadcastKeySmUnexpected} 107 }, 108 109 /* next state and actions for START state */ 110 { {BCAST_KEY_802_1X_STATE_START, (fsm_Action_t)broadcastKeySmUnexpected}, 111 {BCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)broadcastKeySmNop}, 112 {BCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)broadcastKey802_1x_distribute}, 113 {BCAST_KEY_802_1X_STATE_START, (fsm_Action_t)broadcastKeySmNop} 114 }, 115 116 /* next state and actions for COMPLETE state */ 117 { {BCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)broadcastKeySmUnexpected}, 118 {BCAST_KEY_802_1X_STATE_IDLE, (fsm_Action_t)broadcastKeySmNop}, 119 {BCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)broadcastKey802_1x_distribute}, 120 {BCAST_KEY_802_1X_STATE_COMPLETE, (fsm_Action_t)broadcastKeySmUnexpected} 121 } 122 }; 123 124 125 pBroadcastKey->start = broadcastKey802_1x_start; 126 pBroadcastKey->stop = broadcastKey802_1x_stop; 127 pBroadcastKey->recvFailure = broadcastKey802_1x_recvFailure; 128 pBroadcastKey->recvSuccess = broadcastKey802_1x_recvSuccess; 129 130 pBroadcastKey->currentState = BCAST_KEY_802_1X_STATE_IDLE; 131 132 status = fsm_Config(pBroadcastKey->pBcastKeySm, 133 &broadcastKey802_1x_matrix[0][0], 134 BCAST_KEY_802_1X_NUM_STATES, 135 BCAST_KEY_802_1X_NUM_EVENTS, 136 NULL, pBroadcastKey->hOs); 137 138 139 140 return status; 141 } 142 143 144 /** 145 * 146 * broadcastKey802_1x_event 147 * 148 * \b Description: 149 * 150 * broadcast key state machine transition function 151 * 152 * \b ARGS: 153 * 154 * I/O - currentState - current state in the state machine\n 155 * I - event - specific event for the state machine\n 156 * I - pData - Data for state machine action function\n 157 * 158 * \b RETURNS: 159 * 160 * OK on success, NOK otherwise. 161 * 162 * \sa 163 */ 164 165 #ifdef REPORT_LOG 166 167 static char *broadcastKey802_1x_stateDesc[BCAST_KEY_802_1X_NUM_STATES] = { 168 "STATE_IDLE", 169 "STATE_START", 170 "STATE_COMPLETE", 171 }; 172 173 static char *broadcastKey802_1x_eventDesc[BCAST_KEY_802_1X_NUM_EVENTS] = { 174 "EVENT_START", 175 "EVENT_STOP", 176 "EVENT_SUCCESS", 177 "EVENT_FAILURE" 178 }; 179 180 #endif 181 182 TI_STATUS broadcastKey802_1x_event(struct _broadcastKey_t *pBroadcastKey, UINT8 event, void *pData) 183 { 184 TI_STATUS status; 185 UINT8 nextState; 186 187 status = fsm_GetNextState(pBroadcastKey->pBcastKeySm, pBroadcastKey->currentState, event, &nextState); 188 if (status != OK) 189 { 190 WLAN_REPORT_ERROR(pBroadcastKey->hReport, RSN_MODULE_LOG, 191 ("BROADCAST_KEY_SM: ERROR: failed getting next state\n")); 192 return NOK; 193 } 194 195 WLAN_REPORT_INFORMATION(pBroadcastKey->hReport, RSN_MODULE_LOG, 196 ("STATION_BROADCAST_KEY_SM: <%s, %s> --> %s\n", 197 broadcastKey802_1x_stateDesc[pBroadcastKey->currentState], 198 broadcastKey802_1x_eventDesc[event], 199 broadcastKey802_1x_stateDesc[nextState])); 200 201 status = fsm_Event(pBroadcastKey->pBcastKeySm, &pBroadcastKey->currentState, event, pData); 202 203 return status; 204 } 205 206 207 /** 208 * 209 * broadcastKey802_1x_start 210 * 211 * \b Description: 212 * 213 * START event handler 214 * 215 * \b ARGS: 216 * 217 * I - pCtrlB - station control block \n 218 * 219 * \b RETURNS: 220 * 221 * OK on success, NOK otherwise. 222 * 223 * \sa broadcastKey802_1x_stop() 224 */ 225 TI_STATUS broadcastKey802_1x_start(struct _broadcastKey_t *pBroadcastKey) 226 { 227 TI_STATUS status; 228 229 status = broadcastKey802_1x_event(pBroadcastKey, BCAST_KEY_802_1X_EVENT_START, pBroadcastKey); 230 231 return status; 232 } 233 234 235 /** 236 * 237 * broadcastKey802_1x_stop 238 * 239 * \b Description: 240 * 241 * START event handler 242 * 243 * \b ARGS: 244 * 245 * I - pCtrlB - station control block \n 246 * 247 * \b RETURNS: 248 * 249 * OK on success, NOK otherwise. 250 * 251 * \sa broadcastKey802_1x_start() 252 */ 253 TI_STATUS broadcastKey802_1x_stop(struct _broadcastKey_t *pBroadcastKey) 254 { 255 TI_STATUS status; 256 257 status = broadcastKey802_1x_event(pBroadcastKey, BCAST_KEY_802_1X_EVENT_STOP, pBroadcastKey); 258 259 return status; 260 } 261 262 263 /** 264 * 265 * broadcastKey802_1x_recvSuccess 266 * 267 * \b Description: 268 * 269 * SUCCESS event handler 270 * 271 * \b ARGS: 272 * 273 * I - pCtrlB - station control block \n 274 * I - pEncodedKeyMaterial - Encoded key material \n 275 * 276 * \b RETURNS: 277 * 278 * OK on success, NOK otherwise. 279 * 280 */ 281 TI_STATUS broadcastKey802_1x_recvSuccess(struct _broadcastKey_t *pBroadcastKey, encodedKeyMaterial_t *pEncodedKeyMaterial) 282 { 283 TI_STATUS status; 284 285 pBroadcastKey->data.pEncodedKeyMaterial = pEncodedKeyMaterial; 286 287 status = broadcastKey802_1x_event(pBroadcastKey, BCAST_KEY_802_1X_EVENT_SUCCESS, pBroadcastKey); 288 289 return status; 290 } 291 292 293 /** 294 * 295 * broadcastKey802_1x_recvFailure 296 * 297 * \b Description: 298 * 299 * FAILURE event handler 300 * 301 * \b ARGS: 302 * 303 * I - pCtrlB - station control block \n 304 * 305 * \b RETURNS: 306 * 307 * OK on success, NOK otherwise. 308 * 309 */ 310 TI_STATUS broadcastKey802_1x_recvFailure(struct _broadcastKey_t *pBroadcastKey) 311 { 312 TI_STATUS status; 313 314 status = broadcastKey802_1x_event(pBroadcastKey, BCAST_KEY_802_1X_EVENT_FAILURE, pBroadcastKey); 315 316 return status; 317 } 318 319 320 /** 321 * 322 * broadcastKey802_1x_distribute 323 * 324 * \b Description: 325 * 326 * Distribute broadcast key material to the driver and report the main key SM on broadcast complete. 327 * 328 * \b ARGS: 329 * 330 * I - pData - Encoded key material \n 331 * 332 * \b RETURNS: 333 * 334 * OK on success, NOK otherwise. 335 */ 336 TI_STATUS broadcastKey802_1x_distribute(struct _broadcastKey_t *pBroadcastKey) 337 { 338 TI_STATUS status=NOK; 339 340 if (pBroadcastKey->pKeyDerive->derive!=NULL) 341 { 342 status = pBroadcastKey->pKeyDerive->derive(pBroadcastKey->pKeyDerive, 343 pBroadcastKey->data.pEncodedKeyMaterial); 344 } 345 if (status != OK) 346 { 347 return NOK; 348 } 349 350 if (pBroadcastKey->pParent->reportBcastStatus!=NULL) 351 { 352 status = pBroadcastKey->pParent->reportBcastStatus(pBroadcastKey->pParent, OK); 353 } 354 355 return status; 356 } 357 358