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