1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
/****************************************************************************/
/* */
/* Name: smp_int.h */
/* */
/* Function this file contains internally used SMP definitions */
/* */
/* Copyright (c) 1999-2008, Broadcom Corp., All Rights Reserved. */
/* WIDCOMM Bluetooth Core. Proprietary and confidential. */
/* */
/*****************************************************************************/
#ifndef SMP_INT_H
#define SMP_INT_H
#include "btu.h"
#include "smp_api.h"
#define SMP_MODEL_ENC_ONLY 0
#define SMP_MODEL_PASSKEY 1
#define SMP_MODEL_OOB 2
#define SMP_MODEL_KEY_NOTIF 3
#define SMP_MODEL_MAX 4
typedef UINT8 tSMP_ASSO_MODEL;
#ifndef SMP_MAX_CONN
#define SMP_MAX_CONN 2
#endif
#define SMP_WAIT_FOR_RSP_TOUT 30
#define SMP_WAIT_FOR_REL_DELAY_TOUT 5
/* SMP L2CAP command code */
#define SMP_OPCODE_PAIRING_REQ 0x01
#define SMP_OPCODE_PAIRING_RSP 0x02
#define SMP_OPCODE_CONFIRM 0x03
#define SMP_OPCODE_INIT 0x04
#define SMP_OPCODE_PAIRING_FAILED 0x05
#define SMP_OPCODE_ENCRYPT_INFO 0x06
#define SMP_OPCODE_MASTER_ID 0x07
#define SMP_OPCODE_IDENTITY_INFO 0x08
#define SMP_OPCODE_ID_ADDR 0x09
#define SMP_OPCODE_SIGN_INFO 0x0A
#define SMP_OPCODE_SEC_REQ 0x0B
#define SMP_OPCODE_MAX (SMP_OPCODE_SEC_REQ + 1)
/* SMP events */
#define SMP_PAIRING_REQ_EVT SMP_OPCODE_PAIRING_REQ
#define SMP_PAIRING_RSP_EVT SMP_OPCODE_PAIRING_RSP
#define SMP_CONFIRM_EVT SMP_OPCODE_CONFIRM
#define SMP_RAND_EVT SMP_OPCODE_INIT
#define SMP_PAIRING_FAILED_EVT SMP_OPCODE_PAIRING_FAILED
#define SMP_ENCRPTION_INFO_EVT SMP_OPCODE_ENCRYPT_INFO
#define SMP_MASTER_ID_EVT SMP_OPCODE_MASTER_ID
#define SMP_ID_INFO_EVT SMP_OPCODE_IDENTITY_INFO
#define SMP_ID_ADDR_EVT SMP_OPCODE_ID_ADDR
#define SMP_SIGN_INFO_EVT SMP_OPCODE_SIGN_INFO
#define SMP_SECURITY_REQ_EVT SMP_OPCODE_SEC_REQ
#define SMP_SELF_DEF_EVT SMP_SECURITY_REQ_EVT
#define SMP_KEY_READY_EVT (SMP_SELF_DEF_EVT + 1)
#define SMP_ENCRYPTED_EVT (SMP_SELF_DEF_EVT + 2)
#define SMP_L2CAP_CONN_EVT (SMP_SELF_DEF_EVT + 3)
#define SMP_L2CAP_DISCONN_EVT (SMP_SELF_DEF_EVT + 4)
#define SMP_IO_RSP_EVT (SMP_SELF_DEF_EVT + 5)
#define SMP_API_SEC_GRANT_EVT (SMP_SELF_DEF_EVT + 6)
#define SMP_TK_REQ_EVT (SMP_SELF_DEF_EVT + 7)
#define SMP_AUTH_CMPL_EVT (SMP_SELF_DEF_EVT + 8)
#define SMP_ENC_REQ_EVT (SMP_SELF_DEF_EVT + 9)
#define SMP_BOND_REQ_EVT (SMP_SELF_DEF_EVT + 10)
#define SMP_DISCARD_SEC_REQ_EVT (SMP_SELF_DEF_EVT + 11)
#define SMP_RELEASE_DELAY_EVT (SMP_SELF_DEF_EVT + 12)
#define SMP_RELEASE_DELAY_TOUT_EVT (SMP_SELF_DEF_EVT + 13)
typedef UINT8 tSMP_EVENT;
#define SMP_MAX_EVT SMP_RELEASE_DELAY_TOUT_EVT + 1
/* auumption it's only using the low 8 bits, if bigger than that, need to expand it to be 16 bits */
#define SMP_SEC_KEY_MASK 0x00ff
/* SMP pairing state */
enum
{
SMP_ST_IDLE,
SMP_ST_WAIT_APP_RSP,
SMP_ST_SEC_REQ_PENDING,
SMP_ST_PAIR_REQ_RSP,
SMP_ST_WAIT_CONFIRM,
SMP_ST_CONFIRM,
SMP_ST_RAND,
SMP_ST_ENC_PENDING,
SMP_ST_BOND_PENDING,
SMP_ST_RELEASE_DELAY,
SMP_ST_MAX
};
typedef UINT8 tSMP_STATE;
/* random and encrption activity state */
enum
{
SMP_GEN_COMPARE = 1,
SMP_GEN_CONFIRM,
SMP_GEN_DIV_LTK,
SMP_GEN_DIV_CSRK,
SMP_GEN_RAND_V,
SMP_GEN_TK,
SMP_GEN_SRAND_MRAND,
SMP_GEN_SRAND_MRAND_CONT
};
enum
{
SMP_KEY_TYPE_TK,
SMP_KEY_TYPE_CFM,
SMP_KEY_TYPE_CMP,
SMP_KEY_TYPE_STK,
SMP_KEY_TYPE_LTK
};
typedef struct
{
UINT8 key_type;
UINT8* p_data;
}tSMP_KEY;
typedef union
{
UINT8 *p_data; /* UINT8 type data pointer */
tSMP_KEY key;
UINT16 reason;
}tSMP_INT_DATA;
/* internal status mask */
#define SMP_PAIR_FLAGS_WE_STARTED_DD (1)
#define SMP_PAIR_FLAGS_PEER_STARTED_DD (1 << 1)
#define SMP_PAIR_FLAGS_CMD_CONFIRM (1 << SMP_OPCODE_CONFIRM) /* 1 << 3 */
#define SMP_PAIR_FLAG_ENC_AFTER_PAIR (1 << 4)
/* check if authentication requirement need MITM protection */
#define SMP_NO_MITM_REQUIRED(x) (((x) & SMP_AUTH_YN_BIT) == 0)
#define SMP_ENCRYT_KEY_SIZE 16
#define SMP_ENCRYT_DATA_SIZE 16
#define SMP_ECNCRPYT_STATUS HCI_SUCCESS
/* SMP control block */
typedef struct
{
tSMP_CALLBACK *p_callback;
TIMER_LIST_ENT rsp_timer_ent;
UINT8 trace_level;
BD_ADDR pairing_bda;
tSMP_STATE state;
UINT8 failure;
UINT8 status;
UINT8 role;
UINT8 flags;
UINT8 cb_evt;
tSMP_SEC_LEVEL sec_level;
BOOLEAN connect_initialized;
BT_OCTET16 confirm;
BT_OCTET16 rconfirm;
BT_OCTET16 rrand;
BT_OCTET16 rand;
tSMP_IO_CAP peer_io_caps;
tSMP_IO_CAP loc_io_caps;
tSMP_OOB_FLAG peer_oob_flag;
tSMP_OOB_FLAG loc_oob_flag;
tSMP_AUTH_REQ peer_auth_req;
tSMP_AUTH_REQ loc_auth_req;
UINT8 peer_enc_size;
UINT8 loc_enc_size;
UINT8 peer_i_key;
UINT8 peer_r_key;
UINT8 loc_i_key;
UINT8 loc_r_key;
BT_OCTET16 tk;
BT_OCTET16 ltk;
UINT16 div;
BT_OCTET16 csrk; /* storage for local CSRK */
UINT16 ediv;
BT_OCTET8 enc_rand;
UINT8 rand_enc_proc;
BOOLEAN last_cmd;
BD_ADDR local_bda;
BOOLEAN is_pair_cancel;
BOOLEAN discard_sec_req;
#if SMP_CONFORMANCE_TESTING == TRUE
BOOLEAN enable_test_confirm_val;
BT_OCTET16 test_confirm;
BOOLEAN enable_test_rand_val;
BT_OCTET16 test_rand;
BOOLEAN enable_test_pair_fail;
UINT8 pair_fail_status;
BOOLEAN remove_fixed_channel_disable;
#endif
}tSMP_CB;
/* Server Action functions are of this type */
typedef void (*tSMP_ACT)(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
#ifdef __cplusplus
extern "C"
{
#endif
#if SMP_DYNAMIC_MEMORY == FALSE
SMP_API extern tSMP_CB smp_cb;
#else
SMP_API extern tSMP_CB *smp_cb_ptr;
#define smp_cb (*smp_cb_ptr)
#endif
#ifdef __cplusplus
}
#endif
/* Functions provided by att_main.c */
SMP_API extern void smp_init (void);
#if SMP_CONFORMANCE_TESTING == TRUE
/* Used only for conformance testing */
SMP_API extern void smp_set_test_confirm_value (BOOLEAN enable, UINT8 *p_c_value);
SMP_API extern void smp_set_test_rand_value (BOOLEAN enable, UINT8 *p_c_value);
SMP_API extern void smp_set_test_pair_fail_status (BOOLEAN enable, UINT8 status);
SMP_API extern void smp_remove_fixed_channel_disable (BOOLEAN disable);
#endif
/* smp main */
extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data);
extern void smp_proc_sec_request(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_sec_request(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_master_id(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_id_addr(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_sec_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_sec_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_sl_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_enc_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_discard(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_release_delay(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_release_delay_tout(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_decide_asso_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_compare(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_check_auth_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_io_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_ltk_reply(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_pair_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_generate_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
/* smp_l2c */
extern void smp_l2cap_if_init (void);
/* smp utility */
extern BOOLEAN smp_send_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
extern void smp_cb_cleanup(tSMP_CB *p_cb);
extern void smp_reset_control_value(tSMP_CB *p_cb);
extern void smp_proc_pairing_cmpl(tSMP_CB *p_cb);
extern void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey);
extern void smp_mask_enc_key(UINT8 loc_enc_size, UINT8 * p_data);
extern void smp_rsp_timeout(TIMER_LIST_ENT *p_tle);
extern void smp_xor_128(BT_OCTET16 a, BT_OCTET16 b);
extern BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len,
UINT8 *plain_text, UINT8 pt_len,
tSMP_ENC *p_out);
/* smp key */
extern void smp_generate_confirm (tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_generate_compare (tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_generate_stk (tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_generate_ltk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_generate_passkey (tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_genenrate_rand_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
/* smp main util */
extern void smp_set_state(tSMP_STATE state);
extern tSMP_STATE smp_get_state(void);
#endif /* SMP_INT_H */
|