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