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, 0x81, 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