• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
smp_set_state(tSMP_STATE state)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 *******************************************************************************/
smp_get_state(void)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 *******************************************************************************/
smp_sm_event(tSMP_CB * p_cb,tSMP_EVENT event,void * p_data)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 *******************************************************************************/
smp_get_state_name(tSMP_STATE state)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 *******************************************************************************/
smp_get_event_name(tSMP_EVENT event)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