xref: /btstack/src/ble/sm.h (revision 3deb3ec68039c68a16974dffc53343233662f909)
1*3deb3ec6SMatthias Ringwald /*
2*3deb3ec6SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*3deb3ec6SMatthias Ringwald  *
4*3deb3ec6SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*3deb3ec6SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*3deb3ec6SMatthias Ringwald  * are met:
7*3deb3ec6SMatthias Ringwald  *
8*3deb3ec6SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*3deb3ec6SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*3deb3ec6SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*3deb3ec6SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*3deb3ec6SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*3deb3ec6SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*3deb3ec6SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*3deb3ec6SMatthias Ringwald  *    from this software without specific prior written permission.
16*3deb3ec6SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*3deb3ec6SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*3deb3ec6SMatthias Ringwald  *    monetary gain.
19*3deb3ec6SMatthias Ringwald  *
20*3deb3ec6SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*3deb3ec6SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*3deb3ec6SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*3deb3ec6SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*3deb3ec6SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*3deb3ec6SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*3deb3ec6SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*3deb3ec6SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*3deb3ec6SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*3deb3ec6SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*3deb3ec6SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*3deb3ec6SMatthias Ringwald  * SUCH DAMAGE.
32*3deb3ec6SMatthias Ringwald  *
33*3deb3ec6SMatthias Ringwald  * Please inquire about commercial licensing options at
34*3deb3ec6SMatthias Ringwald  * [email protected]
35*3deb3ec6SMatthias Ringwald  *
36*3deb3ec6SMatthias Ringwald  */
37*3deb3ec6SMatthias Ringwald 
38*3deb3ec6SMatthias Ringwald #ifndef __SM_H
39*3deb3ec6SMatthias Ringwald #define __SM_H
40*3deb3ec6SMatthias Ringwald 
41*3deb3ec6SMatthias Ringwald #include "utils.h"
42*3deb3ec6SMatthias Ringwald #include "btstack.h"
43*3deb3ec6SMatthias Ringwald #include <stdint.h>
44*3deb3ec6SMatthias Ringwald 
45*3deb3ec6SMatthias Ringwald #if defined __cplusplus
46*3deb3ec6SMatthias Ringwald extern "C" {
47*3deb3ec6SMatthias Ringwald #endif
48*3deb3ec6SMatthias Ringwald 
49*3deb3ec6SMatthias Ringwald 
50*3deb3ec6SMatthias Ringwald // Bluetooth Spec definitions
51*3deb3ec6SMatthias Ringwald typedef enum {
52*3deb3ec6SMatthias Ringwald     SM_CODE_PAIRING_REQUEST = 0X01,
53*3deb3ec6SMatthias Ringwald     SM_CODE_PAIRING_RESPONSE,
54*3deb3ec6SMatthias Ringwald     SM_CODE_PAIRING_CONFIRM,
55*3deb3ec6SMatthias Ringwald     SM_CODE_PAIRING_RANDOM,
56*3deb3ec6SMatthias Ringwald     SM_CODE_PAIRING_FAILED,
57*3deb3ec6SMatthias Ringwald     SM_CODE_ENCRYPTION_INFORMATION,
58*3deb3ec6SMatthias Ringwald     SM_CODE_MASTER_IDENTIFICATION,
59*3deb3ec6SMatthias Ringwald     SM_CODE_IDENTITY_INFORMATION,
60*3deb3ec6SMatthias Ringwald     SM_CODE_IDENTITY_ADDRESS_INFORMATION,
61*3deb3ec6SMatthias Ringwald     SM_CODE_SIGNING_INFORMATION,
62*3deb3ec6SMatthias Ringwald     SM_CODE_SECURITY_REQUEST
63*3deb3ec6SMatthias Ringwald } SECURITY_MANAGER_COMMANDS;
64*3deb3ec6SMatthias Ringwald 
65*3deb3ec6SMatthias Ringwald // IO Capability Values
66*3deb3ec6SMatthias Ringwald typedef enum {
67*3deb3ec6SMatthias Ringwald     IO_CAPABILITY_DISPLAY_ONLY = 0,
68*3deb3ec6SMatthias Ringwald     IO_CAPABILITY_DISPLAY_YES_NO,
69*3deb3ec6SMatthias Ringwald     IO_CAPABILITY_KEYBOARD_ONLY,
70*3deb3ec6SMatthias Ringwald     IO_CAPABILITY_NO_INPUT_NO_OUTPUT,
71*3deb3ec6SMatthias Ringwald     IO_CAPABILITY_KEYBOARD_DISPLAY, // not used by secure simple pairing
72*3deb3ec6SMatthias Ringwald } io_capability_t;
73*3deb3ec6SMatthias Ringwald 
74*3deb3ec6SMatthias Ringwald 
75*3deb3ec6SMatthias Ringwald // Authentication requirement flags
76*3deb3ec6SMatthias Ringwald #define SM_AUTHREQ_NO_BONDING 0x00
77*3deb3ec6SMatthias Ringwald #define SM_AUTHREQ_BONDING 0x01
78*3deb3ec6SMatthias Ringwald #define SM_AUTHREQ_MITM_PROTECTION 0x04
79*3deb3ec6SMatthias Ringwald 
80*3deb3ec6SMatthias Ringwald // Key distribution flags used by spec
81*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_ENC_KEY 0X01
82*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_ID_KEY  0x02
83*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_SIGN    0x04
84*3deb3ec6SMatthias Ringwald 
85*3deb3ec6SMatthias Ringwald // Key distribution flags used internally
86*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION       0x01
87*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_FLAG_MASTER_IDENTIFICATION        0x02
88*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_FLAG_IDENTITY_INFORMATION         0x04
89*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION 0x08
90*3deb3ec6SMatthias Ringwald #define SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION       0x10
91*3deb3ec6SMatthias Ringwald 
92*3deb3ec6SMatthias Ringwald // STK Generation Methods
93*3deb3ec6SMatthias Ringwald #define SM_STK_GENERATION_METHOD_JUST_WORKS 0x01
94*3deb3ec6SMatthias Ringwald #define SM_STK_GENERATION_METHOD_OOB        0x02
95*3deb3ec6SMatthias Ringwald #define SM_STK_GENERATION_METHOD_PASSKEY    0x04
96*3deb3ec6SMatthias Ringwald 
97*3deb3ec6SMatthias Ringwald // Pairing Failed Reasons
98*3deb3ec6SMatthias Ringwald #define SM_REASON_RESERVED                     0x00
99*3deb3ec6SMatthias Ringwald #define SM_REASON_PASSKEYT_ENTRY_FAILED        0x01
100*3deb3ec6SMatthias Ringwald #define SM_REASON_OOB_NOT_AVAILABLE            0x02
101*3deb3ec6SMatthias Ringwald #define SM_REASON_AUTHENTHICATION_REQUIREMENTS 0x03
102*3deb3ec6SMatthias Ringwald #define SM_REASON_CONFIRM_VALUE_FAILED         0x04
103*3deb3ec6SMatthias Ringwald #define SM_REASON_PAIRING_NOT_SUPPORTED        0x05
104*3deb3ec6SMatthias Ringwald #define SM_REASON_ENCRYPTION_KEY_SIZE          0x06
105*3deb3ec6SMatthias Ringwald #define SM_REASON_COMMAND_NOT_SUPPORTED        0x07
106*3deb3ec6SMatthias Ringwald #define SM_REASON_UNSPECIFIED_REASON           0x08
107*3deb3ec6SMatthias Ringwald #define SM_REASON_REPEATED_ATTEMPTS            0x09
108*3deb3ec6SMatthias Ringwald // also, invalid parameters
109*3deb3ec6SMatthias Ringwald // and reserved
110*3deb3ec6SMatthias Ringwald 
111*3deb3ec6SMatthias Ringwald // Only for PTS testing
112*3deb3ec6SMatthias Ringwald void sm_test_set_irk(sm_key_t irk);
113*3deb3ec6SMatthias Ringwald 
114*3deb3ec6SMatthias Ringwald typedef struct {
115*3deb3ec6SMatthias Ringwald     linked_item_t  item;
116*3deb3ec6SMatthias Ringwald     bd_addr_t      address;
117*3deb3ec6SMatthias Ringwald     bd_addr_type_t address_type;
118*3deb3ec6SMatthias Ringwald } sm_lookup_entry_t;
119*3deb3ec6SMatthias Ringwald 
120*3deb3ec6SMatthias Ringwald /* API_START */
121*3deb3ec6SMatthias Ringwald 
122*3deb3ec6SMatthias Ringwald /**
123*3deb3ec6SMatthias Ringwald  * @brief Initializes the Security Manager, connects to L2CAP
124*3deb3ec6SMatthias Ringwald  */
125*3deb3ec6SMatthias Ringwald void sm_init(void);
126*3deb3ec6SMatthias Ringwald 
127*3deb3ec6SMatthias Ringwald /**
128*3deb3ec6SMatthias Ringwald  * @brief Set secret ER key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
129*3deb3ec6SMatthias Ringwald  * @param er
130*3deb3ec6SMatthias Ringwald  */
131*3deb3ec6SMatthias Ringwald void sm_set_er(sm_key_t er);
132*3deb3ec6SMatthias Ringwald 
133*3deb3ec6SMatthias Ringwald /**
134*3deb3ec6SMatthias Ringwald  * @brief Set secret IR key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
135*3deb3ec6SMatthias Ringwald  */
136*3deb3ec6SMatthias Ringwald void sm_set_ir(sm_key_t ir);
137*3deb3ec6SMatthias Ringwald 
138*3deb3ec6SMatthias Ringwald /**
139*3deb3ec6SMatthias Ringwald  *
140*3deb3ec6SMatthias Ringwald  * @brief Registers OOB Data Callback. The callback should set the oob_data and return 1 if OOB data is availble
141*3deb3ec6SMatthias Ringwald  * @param get_oob_data_callback
142*3deb3ec6SMatthias Ringwald  */
143*3deb3ec6SMatthias Ringwald void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t addres_type, bd_addr_t addr, uint8_t * oob_data));
144*3deb3ec6SMatthias Ringwald 
145*3deb3ec6SMatthias Ringwald /**
146*3deb3ec6SMatthias Ringwald  *
147*3deb3ec6SMatthias Ringwald  * @brief Registers packet handler. Called by att_server.c
148*3deb3ec6SMatthias Ringwald  */
149*3deb3ec6SMatthias Ringwald void sm_register_packet_handler(btstack_packet_handler_t handler);
150*3deb3ec6SMatthias Ringwald 
151*3deb3ec6SMatthias Ringwald /**
152*3deb3ec6SMatthias Ringwald  * @brief Limit the STK generation methods. Bonding is stopped if the resulting one isn't in the list
153*3deb3ec6SMatthias Ringwald  * @param OR combination of SM_STK_GENERATION_METHOD_
154*3deb3ec6SMatthias Ringwald  */
155*3deb3ec6SMatthias Ringwald void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods);
156*3deb3ec6SMatthias Ringwald 
157*3deb3ec6SMatthias Ringwald /**
158*3deb3ec6SMatthias Ringwald  * @brief Set the accepted encryption key size range. Bonding is stopped if the result isn't within the range
159*3deb3ec6SMatthias Ringwald  * @param min_size (default 7)
160*3deb3ec6SMatthias Ringwald  * @param max_size (default 16)
161*3deb3ec6SMatthias Ringwald  */
162*3deb3ec6SMatthias Ringwald void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size);
163*3deb3ec6SMatthias Ringwald 
164*3deb3ec6SMatthias Ringwald /**
165*3deb3ec6SMatthias Ringwald  * @brief Sets the requested authentication requirements, bonding yes/no, MITM yes/no
166*3deb3ec6SMatthias Ringwald  * @param OR combination of SM_AUTHREQ_ flags
167*3deb3ec6SMatthias Ringwald  */
168*3deb3ec6SMatthias Ringwald void sm_set_authentication_requirements(uint8_t auth_req);
169*3deb3ec6SMatthias Ringwald 
170*3deb3ec6SMatthias Ringwald /**
171*3deb3ec6SMatthias Ringwald  * @brief Sets the available IO Capabilities
172*3deb3ec6SMatthias Ringwald  * @param IO_CAPABILITY_
173*3deb3ec6SMatthias Ringwald  */
174*3deb3ec6SMatthias Ringwald void sm_set_io_capabilities(io_capability_t io_capability);
175*3deb3ec6SMatthias Ringwald 
176*3deb3ec6SMatthias Ringwald /**
177*3deb3ec6SMatthias Ringwald  * @brief Let Peripheral request an encrypted connection right after connecting
178*3deb3ec6SMatthias Ringwald  * @note Not used normally. Bonding is triggered by access to protected attributes in ATT Server
179*3deb3ec6SMatthias Ringwald  */
180*3deb3ec6SMatthias Ringwald void sm_set_request_security(int enable);
181*3deb3ec6SMatthias Ringwald 
182*3deb3ec6SMatthias Ringwald /**
183*3deb3ec6SMatthias Ringwald  * @brief Trigger Security Request
184*3deb3ec6SMatthias Ringwald  * @note Not used normally. Bonding is triggered by access to protected attributes in ATT Server
185*3deb3ec6SMatthias Ringwald  */
186*3deb3ec6SMatthias Ringwald void sm_send_security_request(uint16_t handle);
187*3deb3ec6SMatthias Ringwald 
188*3deb3ec6SMatthias Ringwald /**
189*3deb3ec6SMatthias Ringwald  * @brief Decline bonding triggered by event before
190*3deb3ec6SMatthias Ringwald  * @param addr_type and address
191*3deb3ec6SMatthias Ringwald  */
192*3deb3ec6SMatthias Ringwald void sm_bonding_decline(uint16_t handle);
193*3deb3ec6SMatthias Ringwald 
194*3deb3ec6SMatthias Ringwald /**
195*3deb3ec6SMatthias Ringwald  * @brief Confirm Just Works bonding
196*3deb3ec6SMatthias Ringwald  * @param addr_type and address
197*3deb3ec6SMatthias Ringwald  */
198*3deb3ec6SMatthias Ringwald void sm_just_works_confirm(uint16_t handle);
199*3deb3ec6SMatthias Ringwald 
200*3deb3ec6SMatthias Ringwald /**
201*3deb3ec6SMatthias Ringwald  * @brief Reports passkey input by user
202*3deb3ec6SMatthias Ringwald  * @param addr_type and address
203*3deb3ec6SMatthias Ringwald  * @param passkey in [0..999999]
204*3deb3ec6SMatthias Ringwald  */
205*3deb3ec6SMatthias Ringwald void sm_passkey_input(uint16_t handle, uint32_t passkey);
206*3deb3ec6SMatthias Ringwald 
207*3deb3ec6SMatthias Ringwald /**
208*3deb3ec6SMatthias Ringwald  *
209*3deb3ec6SMatthias Ringwald  * @brief Get encryption key size.
210*3deb3ec6SMatthias Ringwald  * @param addr_type and address
211*3deb3ec6SMatthias Ringwald  * @return 0 if not encrypted, 7-16 otherwise
212*3deb3ec6SMatthias Ringwald  */
213*3deb3ec6SMatthias Ringwald int sm_encryption_key_size(uint16_t handle);
214*3deb3ec6SMatthias Ringwald 
215*3deb3ec6SMatthias Ringwald /**
216*3deb3ec6SMatthias Ringwald  * @brief Get authentication property.
217*3deb3ec6SMatthias Ringwald  * @param addr_type and address
218*3deb3ec6SMatthias Ringwald  * @return 1 if bonded with OOB/Passkey (AND MITM protection)
219*3deb3ec6SMatthias Ringwald  */
220*3deb3ec6SMatthias Ringwald int sm_authenticated(uint16_t handle);
221*3deb3ec6SMatthias Ringwald 
222*3deb3ec6SMatthias Ringwald /**
223*3deb3ec6SMatthias Ringwald  * @brief Queries authorization state.
224*3deb3ec6SMatthias Ringwald  * @param addr_type and address
225*3deb3ec6SMatthias Ringwald  * @return authorization_state for the current session
226*3deb3ec6SMatthias Ringwald  */
227*3deb3ec6SMatthias Ringwald authorization_state_t sm_authorization_state(uint16_t handle);
228*3deb3ec6SMatthias Ringwald 
229*3deb3ec6SMatthias Ringwald /**
230*3deb3ec6SMatthias Ringwald  * @brief Used by att_server.c to request user authorization.
231*3deb3ec6SMatthias Ringwald  * @param addr_type and address
232*3deb3ec6SMatthias Ringwald  */
233*3deb3ec6SMatthias Ringwald void sm_request_pairing(uint16_t handle);
234*3deb3ec6SMatthias Ringwald 
235*3deb3ec6SMatthias Ringwald /**
236*3deb3ec6SMatthias Ringwald  * @brief Report user authorization decline.
237*3deb3ec6SMatthias Ringwald  * @param addr_type and address
238*3deb3ec6SMatthias Ringwald  */
239*3deb3ec6SMatthias Ringwald void sm_authorization_decline(uint16_t handle);
240*3deb3ec6SMatthias Ringwald 
241*3deb3ec6SMatthias Ringwald /**
242*3deb3ec6SMatthias Ringwald  * @brief Report user authorization grant.
243*3deb3ec6SMatthias Ringwald  * @param addr_type and address
244*3deb3ec6SMatthias Ringwald  */
245*3deb3ec6SMatthias Ringwald void sm_authorization_grant(uint16_t handle);
246*3deb3ec6SMatthias Ringwald 
247*3deb3ec6SMatthias Ringwald /**
248*3deb3ec6SMatthias Ringwald  * @brief Support for signed writes, used by att_server.
249*3deb3ec6SMatthias Ringwald  * @note Message and result are in little endian to allows passing in ATT PDU without flipping.
250*3deb3ec6SMatthias Ringwald  * @note calculated hash in done_callback is big endian
251*3deb3ec6SMatthias Ringwald  */
252*3deb3ec6SMatthias Ringwald int  sm_cmac_ready(void);
253*3deb3ec6SMatthias Ringwald void sm_cmac_start(sm_key_t k, uint8_t opcode, uint16_t attribute_handle, uint16_t message_len, uint8_t * message, uint32_t sign_counter, void (*done_handler)(uint8_t hash[8]));
254*3deb3ec6SMatthias Ringwald 
255*3deb3ec6SMatthias Ringwald /*
256*3deb3ec6SMatthias Ringwald  * @brief Match address against bonded devices
257*3deb3ec6SMatthias Ringwald  * @return 0 if successfully added to lookup queue
258*3deb3ec6SMatthias Ringwald  * @note Triggers SM_IDENTITY_RESOLVING_* events
259*3deb3ec6SMatthias Ringwald  */
260*3deb3ec6SMatthias Ringwald int sm_address_resolution_lookup(uint8_t addr_type, bd_addr_t addr);
261*3deb3ec6SMatthias Ringwald 
262*3deb3ec6SMatthias Ringwald /**
263*3deb3ec6SMatthias Ringwald  * @brief Identify device in LE Device DB.
264*3deb3ec6SMatthias Ringwald  * @param handle
265*3deb3ec6SMatthias Ringwald  * @return index from le_device_db or -1 if not found/identified
266*3deb3ec6SMatthias Ringwald  */
267*3deb3ec6SMatthias Ringwald int sm_le_device_index(uint16_t handle );
268*3deb3ec6SMatthias Ringwald /* API_END */
269*3deb3ec6SMatthias Ringwald 
270*3deb3ec6SMatthias Ringwald // testing only
271*3deb3ec6SMatthias Ringwald void sm_test_use_fixed_local_csrk(void);
272*3deb3ec6SMatthias Ringwald 
273*3deb3ec6SMatthias Ringwald #if defined __cplusplus
274*3deb3ec6SMatthias Ringwald }
275*3deb3ec6SMatthias Ringwald #endif
276*3deb3ec6SMatthias Ringwald 
277*3deb3ec6SMatthias Ringwald #endif // __SM_H
278