1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #include "bt_target.h" 20 21 #if SMP_INCLUDED == TRUE 22 23 #include <string.h> 24 #include "smp_int.h" 25 26 const char *const smp_state_name [] = 27 { 28 "SMP_STATE_IDLE", 29 "SMP_STATE_WAIT_APP_RSP", 30 "SMP_STATE_SEC_REQ_PENDING", 31 "SMP_STATE_PAIR_REQ_RSP", 32 "SMP_STATE_WAIT_CONFIRM", 33 "SMP_STATE_CONFIRM", 34 "SMP_STATE_RAND", 35 "SMP_STATE_PUBLIC_KEY_EXCH", 36 "SMP_STATE_SEC_CONN_PHS1_START", 37 "SMP_STATE_WAIT_COMMITMENT", 38 "SMP_STATE_WAIT_NONCE", 39 "SMP_STATE_SEC_CONN_PHS2_START", 40 "SMP_STATE_WAIT_DHK_CHECK", 41 "SMP_STATE_DHK_CHECK", 42 "SMP_STATE_ENCRYPTION_PENDING", 43 "SMP_STATE_BOND_PENDING", 44 "SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA", 45 "SMP_STATE_MAX" 46 }; 47 48 const char *const smp_event_name [] = 49 { 50 "PAIRING_REQ_EVT", 51 "PAIRING_RSP_EVT", 52 "CONFIRM_EVT", 53 "RAND_EVT", 54 "PAIRING_FAILED_EVT", 55 "ENC_INFO_EVT", 56 "MASTER_ID_EVT", 57 "ID_INFO_EVT", 58 "ID_ADDR_EVT", 59 "SIGN_INFO_EVT", 60 "SECURITY_REQ_EVT", 61 "PAIR_PUBLIC_KEY_EVT", 62 "PAIR_DHKEY_CHECK_EVT", 63 "PAIR_KEYPRESS_NOTIFICATION_EVT", 64 "PAIR_COMMITMENT_EVT", 65 "KEY_READY_EVT", 66 "ENCRYPTED_EVT", 67 "L2CAP_CONN_EVT", 68 "L2CAP_DISCONN_EVT", 69 "API_IO_RSP_EVT", 70 "API_SEC_GRANT_EVT", 71 "TK_REQ_EVT", 72 "AUTH_CMPL_EVT", 73 "ENC_REQ_EVT", 74 "BOND_REQ_EVT", 75 "DISCARD_SEC_REQ_EVT", 76 "PUBLIC_KEY_EXCHANGE_REQ_EVT", 77 "LOCAL_PUBLIC_KEY_CRTD_EVT", 78 "BOTH_PUBLIC_KEYS_RCVD_EVT", 79 "SEC_CONN_DHKEY_COMPLETE_EVT", 80 "HAVE_LOCAL_NONCE_EVT", 81 "SEC_CONN_PHASE1_CMPLT_EVT", 82 "SEC_CONN_CALC_NC_EVT", 83 "SEC_CONN_DISPLAY_NC_EVT", 84 "SEC_CONN_OK_EVT", 85 "SEC_CONN_2_DHCK_CHECKS_PRESENT_EVT", 86 "SEC_CONN_KEY_READY_EVT", 87 "KEYPRESS_NOTIFICATION_EVT", 88 "SEC_CONN_OOB_DATA_EVT", 89 "CREATE_LOCAL_SEC_CONN_OOB_DATA_EVT", 90 "OUT_OF_RANGE_EVT" 91 }; 92 93 const char *smp_get_event_name(tSMP_EVENT event); 94 const char *smp_get_state_name(tSMP_STATE state); 95 96 #define SMP_SM_IGNORE 0 97 #define SMP_NUM_ACTIONS 2 98 #define SMP_SME_NEXT_STATE 2 99 #define SMP_SM_NUM_COLS 3 100 101 typedef const UINT8(*tSMP_SM_TBL)[SMP_SM_NUM_COLS]; 102 103 enum 104 { 105 SMP_PROC_SEC_REQ, 106 SMP_SEND_PAIR_REQ, 107 SMP_SEND_PAIR_RSP, 108 SMP_SEND_CONFIRM, 109 SMP_SEND_PAIR_FAIL, 110 SMP_SEND_RAND, 111 SMP_SEND_ENC_INFO, 112 SMP_SEND_ID_INFO, 113 SMP_SEND_LTK_REPLY, 114 SMP_PROC_PAIR_CMD, 115 SMP_PROC_PAIR_FAIL, 116 SMP_PROC_CONFIRM, 117 SMP_PROC_RAND, 118 SMP_PROC_ENC_INFO, 119 SMP_PROC_MASTER_ID, 120 SMP_PROC_ID_INFO, 121 SMP_PROC_ID_ADDR, 122 SMP_PROC_SRK_INFO, 123 SMP_PROC_SEC_GRANT, 124 SMP_PROC_SL_KEY, 125 SMP_PROC_COMPARE, 126 SMP_PROC_IO_RSP, 127 SMP_GENERATE_COMPARE, 128 SMP_GENERATE_CONFIRM, 129 SMP_GENERATE_STK, 130 SMP_KEY_DISTRIBUTE, 131 SMP_START_ENC, 132 SMP_PAIRING_CMPL, 133 SMP_DECIDE_ASSO_MODEL, 134 SMP_SEND_APP_CBACK, 135 SMP_CHECK_AUTH_REQ, 136 SMP_PAIR_TERMINATE, 137 SMP_ENC_CMPL, 138 SMP_PROC_DISCARD, 139 SMP_CREATE_PRIVATE_KEY, 140 SMP_USE_OOB_PRIVATE_KEY, 141 SMP_SEND_PAIR_PUBLIC_KEY, 142 SMP_PROCESS_PAIR_PUBLIC_KEY, 143 SMP_HAVE_BOTH_PUBLIC_KEYS, 144 SMP_START_SEC_CONN_PHASE1, 145 SMP_PROCESS_LOCAL_NONCE, 146 SMP_SEND_COMMITMENT, 147 SMP_PROCESS_PAIRING_COMMITMENT, 148 SMP_PROCESS_PEER_NONCE, 149 SMP_CALCULATE_LOCAL_DHKEY_CHECK, 150 SMP_SEND_DHKEY_CHECK, 151 SMP_PROCESS_DHKEY_CHECK, 152 SMP_CALCULATE_PEER_DHKEY_CHECK, 153 SMP_MATCH_DHKEY_CHECKS, 154 SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, 155 SMP_MOVE_TO_SEC_CONN_PHASE2, 156 SMP_PH2_DHKEY_CHECKS_ARE_PRESENT, 157 SMP_WAIT_FOR_BOTH_PUBLIC_KEYS, 158 SMP_START_PASSKEY_VERIFICATION, 159 SMP_SEND_KEYPRESS_NOTIFICATION, 160 SMP_PROCESS_KEYPRESS_NOTIFICATION, 161 SMP_PROCESS_SECURE_CONNECTION_OOB_DATA, 162 SMP_SET_LOCAL_OOB_KEYS, 163 SMP_SET_LOCAL_OOB_RAND_COMMITMENT, 164 SMP_IDLE_TERMINATE, 165 SMP_FAST_CONN_PARAM, 166 SMP_SM_NO_ACTION 167 }; 168 169 static const tSMP_ACT smp_sm_action[] = 170 { 171 smp_proc_sec_req, 172 smp_send_pair_req, 173 smp_send_pair_rsp, 174 smp_send_confirm, 175 smp_send_pair_fail, 176 smp_send_rand, 177 smp_send_enc_info, 178 smp_send_id_info, 179 smp_send_ltk_reply, 180 smp_proc_pair_cmd, 181 smp_proc_pair_fail, 182 smp_proc_confirm, 183 smp_proc_rand, 184 smp_proc_enc_info, 185 smp_proc_master_id, 186 smp_proc_id_info, 187 smp_proc_id_addr, 188 smp_proc_srk_info, 189 smp_proc_sec_grant, 190 smp_proc_sl_key, 191 smp_proc_compare, 192 smp_process_io_response, 193 smp_generate_compare, 194 smp_generate_srand_mrand_confirm, 195 smp_generate_stk, 196 smp_key_distribution, 197 smp_start_enc, 198 smp_pairing_cmpl, 199 smp_decide_association_model, 200 smp_send_app_cback, 201 smp_check_auth_req, 202 smp_pair_terminate, 203 smp_enc_cmpl, 204 smp_proc_discard, 205 smp_create_private_key, 206 smp_use_oob_private_key, 207 smp_send_pair_public_key, 208 smp_process_pairing_public_key, 209 smp_both_have_public_keys, 210 smp_start_secure_connection_phase1, 211 smp_process_local_nonce, 212 smp_send_commitment, 213 smp_process_pairing_commitment, 214 smp_process_peer_nonce, 215 smp_calculate_local_dhkey_check, 216 smp_send_dhkey_check, 217 smp_process_dhkey_check, 218 smp_calculate_peer_dhkey_check, 219 smp_match_dhkey_checks, 220 smp_calculate_numeric_comparison_display_number, 221 smp_move_to_secure_connections_phase2, 222 smp_phase_2_dhkey_checks_are_present, 223 smp_wait_for_both_public_keys, 224 smp_start_passkey_verification, 225 smp_send_keypress_notification, 226 smp_process_keypress_notification, 227 smp_process_secure_connection_oob_data, 228 smp_set_local_oob_keys, 229 smp_set_local_oob_random_commitment, 230 smp_idle_terminate, 231 smp_fast_conn_param 232 }; 233 234 /************ SMP Master FSM State/Event Indirection Table **************/ 235 static const UINT8 smp_master_entry_map[][SMP_STATE_MAX] = 236 { 237 /* state name: Idle WaitApp SecReq Pair Wait Confirm Rand PublKey SCPhs1 Wait Wait SCPhs2 Wait DHKChk Enc Bond CrLocSc 238 Rsp Pend ReqRsp Cfm Exch Strt Cmtm Nonce Strt DHKChk Pend Pend OobData */ 239 /* PAIR_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 240 /* PAIR_RSP */{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 241 /* CONFIRM */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 242 /* RAND */{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, 243 /* PAIR_FAIL */{ 0, 0x81, 0, 0x81, 0x81,0x81, 0x81,0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0, 0, 0 }, 244 /* ENC_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, 245 /* MASTER_ID */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 }, 246 /* ID_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 }, 247 /* ID_ADDR */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0 }, 248 /* SIGN_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 }, 249 /* SEC_REQ */{ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 250 /* PAIR_PUBLIC_KEY */{ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 251 /* PAIR_DHKEY_CHCK */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, 252 /* PAIR_KEYPR_NOTIF */{ 0, 8, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0 }, 253 /* PAIR_COMMITM */{ 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0 }, 254 /* KEY_READY */{ 0, 3, 0, 3, 1, 0, 2, 0, 4, 0, 0, 0, 0, 0, 1, 6, 0 }, 255 /* ENC_CMPL */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, 256 /* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 257 /* L2C_DISC */{ 3, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0 }, 258 /* IO_RSP */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 259 /* SEC_GRANT */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 260 /* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 }, 261 /* AUTH_CMPL */{ 4, 0x82, 0, 0x82, 0x82,0x82, 0x82,0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0 }, 262 /* ENC_REQ */{ 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, 263 /* BOND_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, 264 /* DISCARD_SEC_REQ */{ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, 265 /* PUBL_KEY_EXCH_REQ */{ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 266 /* LOC_PUBL_KEY_CRTD */{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 267 /* BOTH_PUBL_KEYS_RCVD */{ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 268 /* SC_DHKEY_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, 269 /* HAVE_LOC_NONCE */{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2 }, 270 /* SC_PHASE1_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, 271 /* SC_CALC_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, 272 /* SC_DSPL_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0 }, 273 /* SC_NC_OK */{ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 274 /* SC_2_DHCK_CHKS_PRES */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 275 /* SC_KEY_READY */{ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, 276 /* KEYPR_NOTIF */{ 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 277 /* SC_OOB_DATA */{ 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 278 /* CR_LOC_SC_OOB_DATA */{ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 279 }; 280 281 static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] = 282 { 283 /* Event Action Next State */ 284 /* PAIR_FAIL */ {SMP_PROC_PAIR_FAIL, SMP_PAIRING_CMPL, SMP_STATE_IDLE}, 285 /* AUTH_CMPL */ {SMP_SEND_PAIR_FAIL, SMP_PAIRING_CMPL, SMP_STATE_IDLE}, 286 /* L2C_DISC */ {SMP_PAIR_TERMINATE, SMP_SM_NO_ACTION, SMP_STATE_IDLE} 287 }; 288 289 static const UINT8 smp_master_idle_table[][SMP_SM_NUM_COLS] = 290 { 291 /* Event Action Next State */ 292 /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 293 /* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP}, 294 /* L2C_DISC */ {SMP_IDLE_TERMINATE, SMP_SM_NO_ACTION, SMP_STATE_IDLE}, 295 /* AUTH_CMPL */ {SMP_PAIRING_CMPL, SMP_SM_NO_ACTION, SMP_STATE_IDLE} 296 /* CR_LOC_SC_OOB_DATA */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA} 297 298 }; 299 300 static const UINT8 smp_master_wait_for_app_response_table[][SMP_SM_NUM_COLS] = 301 { 302 /* Event Action Next State */ 303 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP}, 304 /* IO_RSP */ {SMP_SEND_PAIR_REQ, SMP_FAST_CONN_PARAM, SMP_STATE_PAIR_REQ_RSP}, 305 306 /* TK ready */ 307 /* KEY_READY */ {SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM}, 308 309 /* start enc mode setup */ 310 /* ENC_REQ */ { SMP_START_ENC, SMP_FAST_CONN_PARAM, SMP_STATE_ENCRYPTION_PENDING}, 311 /* DISCARD_SEC_REQ */ { SMP_PROC_DISCARD, SMP_SM_NO_ACTION, SMP_STATE_IDLE} 312 /* user confirms NC 'OK', i.e. phase 1 is completed */ 313 /* SC_NC_OK */,{ SMP_MOVE_TO_SEC_CONN_PHASE2, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START}, 314 /* user-provided passkey is rcvd */ 315 /* SC_KEY_READY */ { SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 316 /* PAIR_KEYPR_NOTIF */ { SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP}, 317 /* KEYPR_NOTIF */ { SMP_SEND_KEYPRESS_NOTIFICATION, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 318 /* SC_OOB_DATA */ { SMP_USE_OOB_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH} 319 }; 320 321 static const UINT8 smp_master_pair_request_response_table[][SMP_SM_NUM_COLS] = 322 { 323 /* Event Action Next State */ 324 /* PAIR_RSP */ { SMP_PROC_PAIR_CMD, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP}, 325 /* TK_REQ */ { SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 326 327 /* TK ready */ 328 /* KEY_READY */{ SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM} 329 /* PUBL_KEY_EXCH_REQ */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH} 330 }; 331 332 static const UINT8 smp_master_wait_for_confirm_table[][SMP_SM_NUM_COLS] = 333 { 334 /* Event Action Next State */ 335 /* KEY_READY*/ {SMP_SEND_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}/* CONFIRM ready */ 336 }; 337 338 static const UINT8 smp_master_confirm_table[][SMP_SM_NUM_COLS] = 339 { 340 /* Event Action Next State */ 341 /* CONFIRM */ { SMP_PROC_CONFIRM, SMP_SEND_RAND, SMP_STATE_RAND} 342 }; 343 344 static const UINT8 smp_master_rand_table[][SMP_SM_NUM_COLS] = 345 { 346 /* Event Action Next State */ 347 /* RAND */ { SMP_PROC_RAND, SMP_GENERATE_COMPARE, SMP_STATE_RAND}, 348 /* KEY_READY*/ { SMP_PROC_COMPARE, SMP_SM_NO_ACTION, SMP_STATE_RAND}, /* Compare ready */ 349 /* ENC_REQ */ { SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING} 350 }; 351 352 static const UINT8 smp_master_public_key_exchange_table[][SMP_SM_NUM_COLS] = 353 { 354 /* Event Action Next State */ 355 /* LOC_PUBL_KEY_CRTD */{ SMP_SEND_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}, 356 /* PAIR_PUBLIC_KEY */{ SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}, 357 /* BOTH_PUBL_KEYS_RCVD */{ SMP_HAVE_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 358 }; 359 360 static const UINT8 smp_master_sec_conn_phs1_start_table[][SMP_SM_NUM_COLS] = 361 { 362 /* Event Action Next State */ 363 /* SC_DHKEY_CMPLT */{ SMP_START_SEC_CONN_PHASE1, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 364 /* HAVE_LOC_NONCE */{ SMP_PROCESS_LOCAL_NONCE, SMP_SM_NO_ACTION, SMP_STATE_WAIT_COMMITMENT}, 365 /* TK_REQ */{ SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 366 /* SMP_MODEL_SEC_CONN_PASSKEY_DISP model, passkey is sent up to display,*/ 367 /* It's time to start commitment calculation */ 368 /* KEY_READY */{ SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 369 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_SEC_CONN_PHS1_START}, 370 /* PAIR_COMMITM */{ SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 371 }; 372 373 static const UINT8 smp_master_wait_commitment_table[][SMP_SM_NUM_COLS] = 374 { 375 /* Event Action Next State */ 376 /* PAIR_COMMITM */{ SMP_PROCESS_PAIRING_COMMITMENT, SMP_SEND_RAND, SMP_STATE_WAIT_NONCE}, 377 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_COMMITMENT}, 378 }; 379 380 static const UINT8 smp_master_wait_nonce_table[][SMP_SM_NUM_COLS] = 381 { 382 /* Event Action Next State */ 383 /* peer nonce is received */ 384 /* RAND */{SMP_PROC_RAND, SMP_PROCESS_PEER_NONCE, SMP_STATE_SEC_CONN_PHS2_START}, 385 /* NC model, time to calculate number for NC */ 386 /* SC_CALC_NC */{SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, SMP_SM_NO_ACTION, SMP_STATE_WAIT_NONCE}, 387 /* NC model, time to display calculated number for NC to the user */ 388 /* SC_DSPL_NC */{SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 389 }; 390 391 static const UINT8 smp_master_sec_conn_phs2_start_table[][SMP_SM_NUM_COLS] = 392 { 393 /* Event Action Next State */ 394 /* SC_PHASE1_CMPLT */{SMP_CALCULATE_LOCAL_DHKEY_CHECK, SMP_SEND_DHKEY_CHECK, SMP_STATE_WAIT_DHK_CHECK}, 395 }; 396 397 static const UINT8 smp_master_wait_dhk_check_table[][SMP_SM_NUM_COLS] = 398 { 399 /* Event Action Next State */ 400 /* PAIR_DHKEY_CHCK */{SMP_PROCESS_DHKEY_CHECK, SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_STATE_DHK_CHECK}, 401 }; 402 403 static const UINT8 smp_master_dhk_check_table[][SMP_SM_NUM_COLS] = 404 { 405 /* Event Action Next State */ 406 /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check actually received from peer */ 407 /* SC_KEY_READY */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK}, 408 /* locally calculated peer dhkey check is ready -> calculate STK, go to sending */ 409 /* HCI LE Start Encryption command */ 410 /* ENC_REQ */{SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 411 }; 412 413 static const UINT8 smp_master_enc_pending_table[][SMP_SM_NUM_COLS] = 414 { 415 /* Event Action Next State */ 416 /* STK ready */ 417 /* KEY_READY */ { SMP_START_ENC, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 418 /* ENCRYPTED */ { SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 419 /* BOND_REQ */ { SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} 420 }; 421 static const UINT8 smp_master_bond_pending_table[][SMP_SM_NUM_COLS] = 422 { 423 /* Event Action Next State */ 424 /* ENC_INFO */ { SMP_PROC_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 425 /* ID_INFO */ { SMP_PROC_ID_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 426 /* SIGN_INFO*/ { SMP_PROC_SRK_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 427 /* MASTER_ID*/ { SMP_PROC_MASTER_ID, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 428 /* ID_ADDR */ { SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 429 /* KEY_READY */{SMP_SEND_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} /* LTK ready */ 430 }; 431 432 static const UINT8 smp_master_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] = 433 { 434 /* Event Action Next State */ 435 /* LOC_PUBL_KEY_CRTD */ {SMP_SET_LOCAL_OOB_KEYS, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}, 436 /* HAVE_LOC_NONCE */ {SMP_SET_LOCAL_OOB_RAND_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_IDLE} 437 }; 438 439 440 /************ SMP Slave FSM State/Event Indirection Table **************/ 441 static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] = 442 { 443 /* state name: Idle WaitApp SecReq Pair Wait Confirm Rand PublKey SCPhs1 Wait Wait SCPhs2 Wait DHKChk Enc Bond CrLocSc 444 Rsp Pend ReqRsp Cfm Exch Strt Cmtm Nonce Strt DHKChk Pend Pend OobData */ 445 /* PAIR_REQ */{ 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 446 /* PAIR_RSP */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 447 /* CONFIRM */{ 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 448 /* RAND */{ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, 449 /* PAIR_FAIL */{ 0, 0x81, 0x81, 0x81, 0x81,0x81, 0x81,0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0, 0 }, 450 /* ENC_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 }, 451 /* MASTER_ID */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0 }, 452 /* ID_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 }, 453 /* ID_ADDR */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, 454 /* SIGN_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 }, 455 /* SEC_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 456 /* PAIR_PUBLIC_KEY */{ 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 457 /* PAIR_DHKEY_CHCK */{ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0 }, 458 /* PAIR_KEYPR_NOTIF */{ 0, 9, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0 }, 459 /* PAIR_COMMITM */{ 0, 8, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0 }, 460 /* KEY_READY */{ 0, 3, 0, 3, 2, 2, 1, 0, 4, 0, 0, 0, 0, 0, 2, 1, 0 }, 461 /* ENC_CMPL */{ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, 462 /* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 463 /* L2C_DISC */{ 0, 0x83, 0x83, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0 }, 464 /* IO_RSP */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 465 /* SEC_GRANT */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 466 /* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 }, 467 /* AUTH_CMPL */{ 0, 0x82, 0x82, 0x82, 0x82,0x82, 0x82,0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0 }, 468 /* ENC_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, 469 /* BOND_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, 470 /* DISCARD_SEC_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 471 /* PUBL_KEY_EXCH_REQ */{ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 472 /* LOC_PUBL_KEY_CRTD */{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 473 /* BOTH_PUBL_KEYS_RCVD */{ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 474 /* SC_DHKEY_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, 475 /* HAVE_LOC_NONCE */{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2 }, 476 /* SC_PHASE1_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, 477 /* SC_CALC_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, 478 /* SC_DSPL_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0 }, 479 /* SC_NC_OK */{ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 480 /* SC_2_DHCK_CHKS_PRES */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0 }, 481 /* SC_KEY_READY */{ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, 482 /* KEYPR_NOTIF */{ 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 483 /* SC_OOB_DATA */{ 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 484 /* CR_LOC_SC_OOB_DATA */{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 485 }; 486 487 static const UINT8 smp_slave_idle_table[][SMP_SM_NUM_COLS] = 488 { 489 /* Event Action Next State */ 490 /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 491 /* PAIR_REQ */ {SMP_PROC_PAIR_CMD, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP} 492 /* CR_LOC_SC_OOB_DATA */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA} 493 }; 494 495 static const UINT8 smp_slave_wait_for_app_response_table [][SMP_SM_NUM_COLS] = 496 { 497 /* Event Action Next State */ 498 /* IO_RSP */ {SMP_PROC_IO_RSP, SMP_FAST_CONN_PARAM, SMP_STATE_PAIR_REQ_RSP}, 499 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP}, 500 501 /* TK ready */ 502 /* KEY_READY */ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 503 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM} 504 /* DHKey Check from master is received before phase 1 is completed - race */ 505 /* PAIR_DHKEY_CHCK */,{SMP_PROCESS_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 506 /* user confirms NC 'OK', i.e. phase 1 is completed */ 507 /* SC_NC_OK */ {SMP_MOVE_TO_SEC_CONN_PHASE2, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START}, 508 /* user-provided passkey is rcvd */ 509 /* SC_KEY_READY */ {SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 510 /* PAIR_COMMITM */ {SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 511 /* PAIR_KEYPR_NOTIF */ {SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP}, 512 /* KEYPR_NOTIF */ {SMP_SEND_KEYPRESS_NOTIFICATION, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 513 /* SC_OOB_DATA */ {SMP_SEND_PAIR_RSP, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP}, 514 }; 515 516 static const UINT8 smp_slave_sec_request_table[][SMP_SM_NUM_COLS] = 517 { 518 /* Event Action Next State */ 519 /* PAIR_REQ */{SMP_PROC_PAIR_CMD, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP}, 520 /* ENCRYPTED*/{SMP_ENC_CMPL, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP}, 521 }; 522 523 static const UINT8 smp_slave_pair_request_response_table[][SMP_SM_NUM_COLS] = 524 { 525 /* Event Action Next State */ 526 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}, 527 /* TK_REQ */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 528 529 /* TK/Confirm ready */ 530 /* KEY_READY */{SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP} 531 /* PUBL_KEY_EXCH_REQ */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}, 532 /* PAIR_PUBLIC_KEY */ { SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP}, 533 }; 534 535 static const UINT8 smp_slave_wait_confirm_table[][SMP_SM_NUM_COLS] = 536 { 537 /* Event Action Next State */ 538 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SEND_CONFIRM, SMP_STATE_CONFIRM}, 539 /* KEY_READY*/ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM} 540 }; 541 542 static const UINT8 smp_slave_confirm_table[][SMP_SM_NUM_COLS] = 543 { 544 /* Event Action Next State */ 545 /* RAND */ {SMP_PROC_RAND, SMP_GENERATE_COMPARE, SMP_STATE_RAND}, 546 547 /* TK/Confirm ready */ 548 /* KEY_READY*/ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM} 549 }; 550 551 static const UINT8 smp_slave_rand_table[][SMP_SM_NUM_COLS] = 552 { 553 /* Event Action Next State */ 554 /* KEY_READY */ {SMP_PROC_COMPARE, SMP_SM_NO_ACTION, SMP_STATE_RAND}, /* compare match */ 555 /* RAND */ {SMP_SEND_RAND, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING} 556 }; 557 558 static const UINT8 smp_slave_public_key_exch_table[][SMP_SM_NUM_COLS] = 559 { 560 /* Event Action Next State */ 561 /* LOC_PUBL_KEY_CRTD */{ SMP_WAIT_FOR_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}, 562 /* PAIR_PUBLIC_KEY */{ SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}, 563 /* BOTH_PUBL_KEYS_RCVD */{ SMP_HAVE_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 564 }; 565 566 static const UINT8 smp_slave_sec_conn_phs1_start_table[][SMP_SM_NUM_COLS] = 567 { 568 /* Event Action Next State */ 569 /* SC_DHKEY_CMPLT */{ SMP_START_SEC_CONN_PHASE1, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 570 /* HAVE_LOC_NONCE */{ SMP_PROCESS_LOCAL_NONCE,SMP_SM_NO_ACTION, SMP_STATE_WAIT_COMMITMENT}, 571 /* TK_REQ */{ SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 572 /* SMP_MODEL_SEC_CONN_PASSKEY_DISP model, passkey is sent up to display, it's time to start */ 573 /* commitment calculation */ 574 /* KEY_READY */{ SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 575 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION,SMP_SEND_APP_CBACK, SMP_STATE_SEC_CONN_PHS1_START}, 576 /*COMMIT*/{SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START}, 577 }; 578 579 static const UINT8 smp_slave_wait_commitment_table[][SMP_SM_NUM_COLS] = 580 { 581 /* Event Action Next State */ 582 /* PAIR_COMMITM */{SMP_PROCESS_PAIRING_COMMITMENT, SMP_SEND_COMMITMENT, SMP_STATE_WAIT_NONCE}, 583 /* PAIR_KEYPR_NOTIF */{SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_COMMITMENT}, 584 }; 585 586 static const UINT8 smp_slave_wait_nonce_table[][SMP_SM_NUM_COLS] = 587 { 588 /* Event Action Next State */ 589 /* peer nonce is received */ 590 /* RAND */{SMP_PROC_RAND, SMP_PROCESS_PEER_NONCE, SMP_STATE_SEC_CONN_PHS2_START}, 591 /* NC model, time to calculate number for NC */ 592 /* SC_CALC_NC */{SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, SMP_SM_NO_ACTION, SMP_STATE_WAIT_NONCE}, 593 /* NC model, time to display calculated number for NC to the user */ 594 /* SC_DSPL_NC */{SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP}, 595 }; 596 597 static const UINT8 smp_slave_sec_conn_phs2_start_table[][SMP_SM_NUM_COLS] = 598 { 599 /* Event Action Next State */ 600 /* SC_PHASE1_CMPLT */{SMP_CALCULATE_LOCAL_DHKEY_CHECK, SMP_PH2_DHKEY_CHECKS_ARE_PRESENT, SMP_STATE_WAIT_DHK_CHECK}, 601 /* DHKey Check from master is received before slave DHKey calculation is completed - race */ 602 /* PAIR_DHKEY_CHCK */{SMP_PROCESS_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START}, 603 }; 604 605 static const UINT8 smp_slave_wait_dhk_check_table[][SMP_SM_NUM_COLS] = 606 { 607 /* Event Action Next State */ 608 /* PAIR_DHKEY_CHCK */{SMP_PROCESS_DHKEY_CHECK, SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_STATE_DHK_CHECK}, 609 /* DHKey Check from master was received before slave came to this state */ 610 /* SC_2_DHCK_CHKS_PRES */{SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK}, 611 }; 612 613 static const UINT8 smp_slave_dhk_check_table[][SMP_SM_NUM_COLS] = 614 { 615 /* Event Action Next State */ 616 617 /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check */ 618 /* actually received from peer */ 619 /* SC_KEY_READY */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK}, 620 621 /* dhkey checks match -> send local dhkey check to master, go to wait for HCI LE */ 622 /* Long Term Key Request Event */ 623 /* PAIR_DHKEY_CHCK */{SMP_SEND_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 624 }; 625 626 static const UINT8 smp_slave_enc_pending_table[][SMP_SM_NUM_COLS] = 627 { 628 /* Event Action Next State */ 629 /* ENC_REQ */ {SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 630 631 /* STK ready */ 632 /* KEY_READY */ {SMP_SEND_LTK_REPLY, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 633 /* ENCRYPTED */ {SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, 634 /* BOND_REQ */ {SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} 635 }; 636 static const UINT8 smp_slave_bond_pending_table[][SMP_SM_NUM_COLS] = 637 { 638 /* Event Action Next State */ 639 640 /* LTK ready */ 641 /* KEY_READY */{ SMP_SEND_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 642 643 /* rev SRK */ 644 /* SIGN_INFO */{ SMP_PROC_SRK_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 645 /* ENC_INFO */ { SMP_PROC_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 646 /* ID_INFO */ { SMP_PROC_ID_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 647 /* MASTER_ID*/ { SMP_PROC_MASTER_ID, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, 648 /* ID_ADDR */ { SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} 649 650 }; 651 652 static const UINT8 smp_slave_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] = 653 { 654 /* Event Action Next State */ 655 /* LOC_PUBL_KEY_CRTD */ {SMP_SET_LOCAL_OOB_KEYS, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}, 656 /* HAVE_LOC_NONCE */ {SMP_SET_LOCAL_OOB_RAND_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_IDLE} 657 }; 658 659 static const tSMP_SM_TBL smp_state_table[][2] = 660 { 661 /* SMP_STATE_IDLE */ 662 {smp_master_idle_table, smp_slave_idle_table}, 663 664 /* SMP_STATE_WAIT_APP_RSP */ 665 {smp_master_wait_for_app_response_table, smp_slave_wait_for_app_response_table}, 666 667 /* SMP_STATE_SEC_REQ_PENDING */ 668 {NULL, smp_slave_sec_request_table}, 669 670 /* SMP_STATE_PAIR_REQ_RSP */ 671 {smp_master_pair_request_response_table, smp_slave_pair_request_response_table}, 672 673 /* SMP_STATE_WAIT_CONFIRM */ 674 {smp_master_wait_for_confirm_table, smp_slave_wait_confirm_table}, 675 676 /* SMP_STATE_CONFIRM */ 677 {smp_master_confirm_table, smp_slave_confirm_table}, 678 679 /* SMP_STATE_RAND */ 680 {smp_master_rand_table, smp_slave_rand_table}, 681 682 /* SMP_STATE_PUBLIC_KEY_EXCH */ 683 {smp_master_public_key_exchange_table,smp_slave_public_key_exch_table}, 684 685 /* SMP_STATE_SEC_CONN_PHS1_START */ 686 {smp_master_sec_conn_phs1_start_table, smp_slave_sec_conn_phs1_start_table}, 687 688 /* SMP_STATE_WAIT_COMMITMENT */ 689 {smp_master_wait_commitment_table, smp_slave_wait_commitment_table}, 690 691 /* SMP_STATE_WAIT_NONCE */ 692 {smp_master_wait_nonce_table, smp_slave_wait_nonce_table}, 693 694 /* SMP_STATE_SEC_CONN_PHS2_START */ 695 {smp_master_sec_conn_phs2_start_table, smp_slave_sec_conn_phs2_start_table}, 696 697 /* SMP_STATE_WAIT_DHK_CHECK */ 698 {smp_master_wait_dhk_check_table, smp_slave_wait_dhk_check_table}, 699 700 /* SMP_STATE_DHK_CHECK */ 701 {smp_master_dhk_check_table, smp_slave_dhk_check_table}, 702 703 /* SMP_STATE_ENCRYPTION_PENDING */ 704 {smp_master_enc_pending_table, smp_slave_enc_pending_table}, 705 706 /* SMP_STATE_BOND_PENDING */ 707 {smp_master_bond_pending_table, smp_slave_bond_pending_table}, 708 709 /* SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA */ 710 {smp_master_create_local_sec_conn_oob_data, smp_slave_create_local_sec_conn_oob_data} 711 }; 712 713 typedef const UINT8 (*tSMP_ENTRY_TBL)[SMP_STATE_MAX]; 714 static const tSMP_ENTRY_TBL smp_entry_table[] = 715 { 716 smp_master_entry_map, 717 smp_slave_entry_map 718 }; 719 720 #if SMP_DYNAMIC_MEMORY == FALSE 721 tSMP_CB smp_cb; 722 #endif 723 #define SMP_ALL_TBL_MASK 0x80 724 725 /******************************************************************************* 726 ** Function smp_set_state 727 ** Returns None 728 *******************************************************************************/ 729 void smp_set_state(tSMP_STATE state) 730 { 731 if (state < SMP_STATE_MAX) 732 { 733 SMP_TRACE_DEBUG( "State change: %s(%d) ==> %s(%d)", 734 smp_get_state_name(smp_cb.state), smp_cb.state, 735 smp_get_state_name(state), state ); 736 smp_cb.state = state; 737 } 738 else 739 { 740 SMP_TRACE_DEBUG("smp_set_state invalid state =%d", state ); 741 } 742 } 743 744 /******************************************************************************* 745 ** Function smp_get_state 746 ** Returns The smp state 747 *******************************************************************************/ 748 tSMP_STATE smp_get_state(void) 749 { 750 return smp_cb.state; 751 } 752 753 /******************************************************************************* 754 ** 755 ** Function smp_sm_event 756 ** 757 ** Description Handle events to the state machine. It looks up the entry 758 ** in the smp_entry_table array. 759 ** If it is a valid entry, it gets the state table.Set the next state, 760 ** if not NULL state.Execute the action function according to the 761 ** state table. If the state returned by action function is not NULL 762 ** state, adjust the new state to the returned state.If (api_evt != MAX), 763 ** call callback function. 764 ** 765 ** Returns void. 766 ** 767 *******************************************************************************/ 768 void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data) 769 { 770 UINT8 curr_state = p_cb->state; 771 tSMP_SM_TBL state_table; 772 UINT8 action, entry, i; 773 tSMP_ENTRY_TBL entry_table = smp_entry_table[p_cb->role]; 774 775 SMP_TRACE_EVENT("main smp_sm_event"); 776 if (curr_state >= SMP_STATE_MAX) 777 { 778 SMP_TRACE_DEBUG( "Invalid state: %d", curr_state) ; 779 return; 780 } 781 782 SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\ 783 (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state), 784 p_cb->state, smp_get_event_name(event), event) ; 785 786 /* look up the state table for the current state */ 787 /* lookup entry /w event & curr_state */ 788 /* If entry is ignore, return. 789 * Otherwise, get state table (according to curr_state or all_state) */ 790 if ((event <= SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE )) 791 { 792 if (entry & SMP_ALL_TBL_MASK) 793 { 794 entry &= ~SMP_ALL_TBL_MASK; 795 state_table = smp_all_table; 796 } 797 else 798 state_table = smp_state_table[curr_state][p_cb->role]; 799 } 800 else 801 { 802 SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]", 803 smp_get_event_name(event), event, smp_get_state_name(curr_state), 804 curr_state); 805 return; 806 } 807 808 /* Get possible next state from state table. */ 809 810 smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]); 811 812 /* If action is not ignore, clear param, exec action and get next state. 813 * The action function may set the Param for cback. 814 * Depending on param, call cback or free buffer. */ 815 /* execute action */ 816 /* execute action functions */ 817 for (i = 0; i < SMP_NUM_ACTIONS; i++) 818 { 819 if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION) 820 { 821 (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data); 822 } 823 else 824 { 825 break; 826 } 827 } 828 SMP_TRACE_DEBUG( "result state = %s", smp_get_state_name( p_cb->state ) ) ; 829 } 830 831 /******************************************************************************* 832 ** Function smp_get_state_name 833 ** Returns The smp state name. 834 *******************************************************************************/ 835 const char * smp_get_state_name(tSMP_STATE state) 836 { 837 const char *p_str = smp_state_name[SMP_STATE_MAX]; 838 839 if (state < SMP_STATE_MAX) 840 { 841 p_str = smp_state_name[state]; 842 } 843 return p_str; 844 } 845 846 /******************************************************************************* 847 ** Function smp_get_event_name 848 ** Returns The smp event name. 849 *******************************************************************************/ 850 const char * smp_get_event_name(tSMP_EVENT event) 851 { 852 const char *p_str = smp_event_name[SMP_MAX_EVT]; 853 854 if (event <= SMP_MAX_EVT) 855 { 856 p_str = smp_event_name[event- 1]; 857 } 858 return p_str; 859 } 860 861 #endif 862 863