-
Notifications
You must be signed in to change notification settings - Fork 606
/
sm.h
314 lines (268 loc) · 10.3 KB
/
sm.h
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
302
303
304
305
306
307
308
309
310
311
312
313
314
/*
* Copyright (C) 2014 BlueKitchen GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* 4. Any redistribution, use, or modification is done solely for
* personal benefit and not for any commercial purpose or for
* monetary gain.
*
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
* GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Please inquire about commercial licensing options at
* contact@bluekitchen-gmbh.com
*
*/
/**
* @title Security Manager
*
*/
#ifndef SM_H
#define SM_H
#if defined __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "btstack_util.h"
#include "btstack_defines.h"
#include "hci.h"
typedef struct {
btstack_linked_item_t item;
bd_addr_t address;
bd_addr_type_t address_type;
} sm_lookup_entry_t;
/* API_START */
/**
* @brief Initializes the Security Manager, connects to L2CAP
*/
void sm_init(void);
/**
* @brief Set secret ER key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
* @note If not set and btstack_tlv is configured, ER key is generated and stored in TLV by SM
* @param er key
*/
void sm_set_er(sm_key_t er);
/**
* @brief Set secret IR key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
* @note If not set and btstack_tlv is configured, IR key is generated and stored in TLV by SM
* @param ir key
*/
void sm_set_ir(sm_key_t ir);
/**
* @brief Registers OOB Data Callback. The callback should set the oob_data and return 1 if OOB data is availble
* @param get_oob_data_callback
*/
void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_data));
/**
* @brief Add event packet handler.
* @param callback_handler
*/
void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler);
/**
* @brief Remove event packet handler.
* @param callback_handler
*/
void sm_remove_event_handler(btstack_packet_callback_registration_t * callback_handler);
/**
* @brief Limit the STK generation methods. Bonding is stopped if the resulting one isn't in the list
* @param OR combination of SM_STK_GENERATION_METHOD_
*/
void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods);
/**
* @brief Set the accepted encryption key size range. Bonding is stopped if the result isn't within the range
* @param min_size (default 7)
* @param max_size (default 16)
*/
void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size);
/**
* @brief Sets the requested authentication requirements, bonding yes/no, MITM yes/no, SC yes/no, keypress yes/no
* @param OR combination of SM_AUTHREQ_ flags
*/
void sm_set_authentication_requirements(uint8_t auth_req);
/**
* @brief Sets the available IO Capabilities
* @param IO_CAPABILITY_
*/
void sm_set_io_capabilities(io_capability_t io_capability);
/**
* @brief Enable/disable Secure Connections Mode only
* @param enable secure connections only mode
*/
void sm_set_secure_connections_only_mode(bool enable);
/**
* @brief Let Peripheral request an encrypted connection right after connecting
* @param enable
* @note Not used normally. Bonding is triggered by access to protected attributes in ATT Server
*/
void sm_set_request_security(bool enable);
/**
* @brief Trigger Security Request
* @deprecated please use sm_request_pairing instead
*/
void sm_send_security_request(hci_con_handle_t con_handle);
/**
* @brief Decline bonding triggered by event before
* @param con_handle
*/
void sm_bonding_decline(hci_con_handle_t con_handle);
/**
* @brief Confirm Just Works bonding
* @param con_handle
*/
void sm_just_works_confirm(hci_con_handle_t con_handle);
/**
* @brief Confirm value from SM_EVENT_NUMERIC_COMPARISON_REQUEST for Numeric Comparison bonding
* @param con_handle
*/
void sm_numeric_comparison_confirm(hci_con_handle_t con_handle);
/**
* @brief Reports passkey input by user
* @param con_handle
* @param passkey in [0..999999]
*/
void sm_passkey_input(hci_con_handle_t con_handle, uint32_t passkey);
/**
* @brief Send keypress notification for keyboard only devices
* @param con_handle
* @param action see SM_KEYPRESS_* in bluetooth.h
*/
void sm_keypress_notification(hci_con_handle_t con_handle, uint8_t action);
/**
* @brief Used by att_server.c and gatt_client.c to request user authentication
* @param con_handle
*/
void sm_request_pairing(hci_con_handle_t con_handle);
/**
* @brief Report user authorization decline.
* @param con_handle
*/
void sm_authorization_decline(hci_con_handle_t con_handle);
/**
* @brief Report user authorization grant.
* @param con_handle
*/
void sm_authorization_grant(hci_con_handle_t con_handle);
/**
* @brief Support for signed writes, used by att_server.
* @return ready
*/
int sm_cmac_ready(void);
/**
* @brief Support for signed writes, used by att_server.
* @note Message is in little endian to allows passing in ATT PDU without flipping.
* @note signing data: [opcode, attribute_handle, message, sign_counter]
* @note calculated hash in done_callback is big endian and has 16 byte.
* @param key
* @param opcde
* @param attribute_handle
* @param message_len
* @param message
* @param sign_counter
*/
void sm_cmac_signed_write_start(const sm_key_t key, uint8_t opcode, uint16_t attribute_handle, uint16_t message_len, const uint8_t * message, uint32_t sign_counter, void (*done_callback)(uint8_t * hash));
/**
* @brief Match address against bonded devices
* @param address_type
* @param address
* @return 0 if successfully added to lookup queue
* @note Triggers SM_IDENTITY_RESOLVING_* events
*/
int sm_address_resolution_lookup(uint8_t address_type, bd_addr_t address);
/**
* @brief Get Identity Resolving state
* @param con_handle
* @return irk_lookup_state_t
* @note return IRK_LOOKUP_IDLE if connection does not exist
*/
irk_lookup_state_t sm_identity_resolving_state(hci_con_handle_t con_handle);
/**
* @brief Identify device in LE Device DB.
* @param con_handle
* @return index from le_device_db or -1 if not found/identified
*/
int sm_le_device_index(hci_con_handle_t con_handle);
/**
* @brief Get LTK for encrypted connection
* @param con_handle
* @param ltk buffer to store long term key
* @return ERROR_CODE_SUCCESS ok
* ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no connection for this con handle exists
* ERROR_CODE_PIN_OR_KEY_MISSING if connection is not encrypted
*/
uint8_t sm_get_ltk(hci_con_handle_t con_handle, sm_key_t ltk);
/**
* @brief Use fixec passkey for Legacy and SC instead of generating a random number
* @note Can be used to improve security over Just Works if no keyboard or displary are present and
* individual random passkey can be printed on the device during production
* @param passkey
*/
void sm_use_fixed_passkey_in_display_role(uint32_t passkey);
/**
* @brief Allow connection re-encryption in Peripheral (Responder) role for LE Legacy Pairing
* without entry for Central device stored in LE Device DB
* @note BTstack in Peripheral Role (Responder) supports LE Legacy Pairing without a persistent LE Device DB as
* the LTK is reconstructed from a local secret IRK and EDIV + Random stored on Central (Initiator) device
* On the downside, it's not really possible to delete a pairing if this is enabled.
* @param allow encryption using reconstructed LTK without stored entry (Default: 1)
*/
void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow);
/**
* @brief Generate OOB data for LE Secure Connections
* @note This generates a 128 bit random number ra and then calculates Ca = f4(PKa, PKa, ra, 0)
* New OOB data should be generated for each pairing. Ra is used for subsequent OOB pairings
* @param callback
* @return status
*/
uint8_t sm_generate_sc_oob_data(void (*callback)(const uint8_t * confirm_value, const uint8_t * random_value));
/**
* @brief Registers OOB Data Callback for LE Secure Conections. The callback should set all arguments and return 1 if OOB data is availble
* @note the oob_sc_local_random usually is the random_value returend by sm_generate_sc_oob_data
* @param get_oob_data_callback
*/
void sm_register_sc_oob_data_callback( int (*get_sc_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_sc_peer_confirm, uint8_t * oob_sc_peer_random));
/**
* @bbrief Register LTK Callback that allows to provide a custom LTK on re-encryption. The callback returns true if LTK was modified
* @param get_ltk_callback
*/
void sm_register_ltk_callback( bool (*get_ltk_callback)(hci_con_handle_t con_handle, uint8_t address_type, bd_addr_t addr, uint8_t * ltk));
/* API_END */
/**
* @brief De-Init SM
*/
void sm_deinit(void);
/**
* @brief Use Debug Keys for LE Secure Connections for testing until restart
* @note Requires ENABLE_LE_SECURE_CONNECTIONS and ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY
*/
void sm_test_enable_secure_connections_debug_keys(void);
// PTS testing
void sm_test_set_irk(sm_key_t irk);
void sm_test_use_fixed_local_csrk(void);
#ifdef ENABLE_TESTING_SUPPORT
void sm_test_set_pairing_failure(int reason);
#endif
#if defined __cplusplus
}
#endif
#endif // SM_H