• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  ****************************************************************************************
3  *
4  * @file ble_sec.h
5  *
6  * @brief BLE SEC API
7  *
8  ****************************************************************************************
9  * @attention
10   #####Copyright (c) 2019 GOODIX
11   All rights reserved.
12 
13     Redistribution and use in source and binary forms, with or without
14     modification, are permitted provided that the following conditions are met:
15   * Redistributions of source code must retain the above copyright
16     notice, this list of conditions and the following disclaimer.
17   * Redistributions in binary form must reproduce the above copyright
18     notice, this list of conditions and the following disclaimer in the
19     documentation and/or other materials provided with the distribution.
20   * Neither the name of GOODIX nor the names of its contributors may be used
21     to endorse or promote products derived from this software without
22     specific prior written permission.
23 
24   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34   POSSIBILITY OF SUCH DAMAGE.
35  *****************************************************************************************
36  */
37 
38 /**
39  * @addtogroup BLE
40  * @{
41  */
42 
43 /**
44 @addtogroup BLE_SEC Security Manager(SM)
45 @{
46 @brief Definitions and prototypes for the BLE_SEC interface.
47 */
48 
49 #ifndef __BLE_SEC_H__
50 #define __BLE_SEC_H__
51 
52 #include <stdbool.h>
53 
54 /** @addtogroup BLE_SM_DEFINES Defines
55  * @{
56  */
57 /** @defgroup SEC_AUTH_FLAG  SEC Auth Flag
58 * @{
59 */
60 #define AUTH_NONE               0                 /**< No auth requirement. */
61 #define AUTH_BOND              (1 << 0)           /**< Bond flag. */
62 #define AUTH_MITM              (1 << 2)           /**< MITM flag. */
63 #define AUTH_SEC_CON           (1 << 3)           /**< Security connection flag. */
64 #define AUTH_KEY_PRESS_NOTIFY  (1 << 4)           /**< Key press notify flag. */
65 #define AUTH_ALL               (AUTH_BOND | AUTH_MITM | AUTH_SEC_CON | AUTH_KEY_PRESS_NOTIFY)  /**< All authentication
66                                                                                                     flags are on. */
67 /** @} */
68 
69 /** @defgroup SEC_KEY_DIST_FLAG  SEC Key Distribution Flag
70 * @{
71 */
72 #define KDIST_NONE      0            /**< No key needs to be distributed. */
73 #define KDIST_ENCKEY   (1 << 0)      /**< Distribute encryption and master identification info. */
74 #define KDIST_IDKEY    (1 << 1)      /**< Distribute identity and address info. */
75 #define KDIST_SIGNKEY  (1 << 2)      /**< Distribute signing info. */
76 #define KDIST_ALL      (KDIST_ENCKEY | KDIST_IDKEY | KDIST_SIGNKEY)  /**< Distribute all info. */
77 
78 /** @} */
79 /** @} */
80 
81 /** @addtogroup BLE_SEC_ENUMERATIONS Enumerations
82  * @{ */
83 /** @brief SEC IO Capability. */
84 typedef enum {
85     IO_DISPLAY_ONLY       = 0x00,       /**< Display only. */
86     IO_DISPLAY_YES_NO     = 0x01,       /**< Display and input yes or no. */
87     IO_KEYBOARD_ONLY      = 0x02,       /**< Keyboard only. */
88     IO_NO_INPUT_NO_OUTPUT = 0x03,       /**< No input and no output. */
89     IO_KEYBOARD_DISPLAY   = 0x04        /**< Keyboard and display. */
90 } sec_io_cap_t;
91 
92 /** @brief SEC Encryption Request Type.
93   * @note These types indicate some operations need to interact with app during pair process.
94  */
95 typedef enum {
96     PAIR_REQ, /**< Pair request. Apps need to decide whether to accept this request. */
97     TK_REQ,   /**< TK request. Apps need to set the TK value. */
98     OOB_REQ,  /**< OOB request. Apps need to set the OOB value. */
99     NC_REQ    /**< Number comparison request.
100                    Apps need to check if it is the same number displayed in Master and Slave. */
101 } sec_enc_req_type_t;
102 
103 /** @brief SEC Key Press Notify.  */
104 typedef enum {
105     KEY_PRESS_STARTED   = 0x00,        /**< Passkey entry started. */
106     KEY_PRESS_ENTERED   = 0x01,        /**< Passkey digit entered. */
107     KEY_PRESS_ERASED    = 0x02,        /**< Passkey digit erased. */
108     KEY_PRESS_CLEARED   = 0x03,        /**< Passkey cleared. */
109     KEY_PRESS_COMPLETED = 0x04         /**< Passkey entry completed. */
110 } sec_keypress_notify_t;
111 
112 /** @brief SEC pair result.  */
113 typedef enum {
114     ENC_SUCCESS                     = 0x00, /**< Encrypt success. */
115     ENC_FAIL_PASSKEY_ENTRY_FAIL     = 0x01, /**< The user input of passkey failed, for example,
116                                                  the user cancelled the operation. */
117     ENC_FAIL_OOB_NOT_AVAILBL        = 0x02, /**< The OOB data is not available. */
118     ENC_FAIL_AUTH_REQ               = 0x03, /**< The pairing procedure cannot be performed as authentication
119                                                  requirements cannot be met due to IO incapability of
120                                                  one or both devices. */
121     ENC_FAIL_CONFIRM_VAL_FAIL       = 0x04, /**< The confirm value does not match the calculated compare value. */
122     ENC_FAIL_PAIRING_NOT_SUPPORT    = 0x05, /**< Pairing is not supported by the device. */
123     ENC_FAIL_ENCRPT_KEY_SIZE        = 0x06, /**< The resultant encryption key size is insufficient for the security
124                                                  requirements of this device. */
125     ENC_FAIL_COMMAND_NOT_SUPPORT    = 0x07, /**< The SMP command received is not supported on this device. */
126     ENC_FAIL_UNSPECIFIED            = 0x08, /**< Pairing failed due to an unspecified reason. */
127     ENC_FAIL_REPEAT_ATTEMPT         = 0x09, /**< Pairing or authentication procedure is disallowed because too little
128                                                  time has elapsed since last pairing request or security request. */
129     ENC_FAIL_INVALID_PARAM          = 0x0A, /**< The Invalid Parameters error code indicates that the command length is
130                                                  invalid or that a parameter is outside of the specified range. */
131     ENC_FAIL_DHKEY_CHECK_FAIL       = 0x0B, /**< Indicate to the remote device that the DHKey Check value received
132                                                  doesn't  match the one calculated by the local device. */
133     ENC_FAIL_NUM_CMP_FAIL           = 0x0C, /**< Indicate that the confirm values in the numeric comparison protocol
134                                                  do not match. */
135     ENC_FAIL_BR_EDR_IN_PROGRESS     = 0x0D, /**< Indicate that the pairing over the LE transport failed due to
136                                                  a Pairing Request sent over the BR/EDR transport in process. */
137     ENC_FAIL_KEY_DRIV_GEN_NOT_ALLOW = 0x0E, /**< Indicate that the BR/EDR Link Key generated on the BR/EDR transport
138                                                  cannot be used to derive and distribute keys for the LE transport. */
139     ENC_FAIL_LTK_MISSING = 0x0F,            /**< Indicate the LTK of peer devices missing. */
140 } sec_enc_ind_t;
141 
142 /** @brief SEC mode and level.  */
143 typedef enum {
144     SEC_MODE1_LEVEL1 = 0x00,    /**< No security is needed. */
145     SEC_MODE1_LEVEL2 = 0x01,    /**< Encrypted link is required. Unnecessary: MITM and SC. */
146     SEC_MODE1_LEVEL3 = 0x02,    /**< Encrypted link is required. Necessary: MITM; unnecessary: SC. */
147     SEC_MODE1_LEVEL4 = 0x03,    /**< Encrypted link is required. Necessary: MITM and SC. */
148     SEC_MODE2_LEVEL1 = 0x04,    /**< Data signing is required. Unnecessary: MITM and SC. */
149     SEC_MODE2_LEVEL2 = 0x05,    /**< Data signing is required. Necessary: MITM; unnecessary: SC. */
150 } sec_mode_level_t;
151 
152 /** @brief SEC TK type. */
153 typedef enum {
154     SEC_TK_OOB = 0x00,        /**<TK got from OOB (out of band) method. */
155     SEC_TK_DISPLAY,           /**<TK generated and shall be displayed by local device. */
156     SEC_TK_KEY_ENTRY          /**<TK shall be entered by user using device keyboard. */
157 } sec_tk_type_t;
158 
159 /** @brief Key missing reason. */
160 typedef enum {
161     BOND_INFO_LOAD_FAILED = 0x00,      /**<Bond information load failed. */
162     LTK_VALID_MASK_ERR,                /**<LTK valid mask flag is false. */
163     EDIV_RAND_VALUE_ERR                /**<Ediv and rand value not match. */
164 } sec_key_missing_reason_t;
165 /** @} */
166 
167 /** @addtogroup BLE_SEC_STRUCTURES Structures
168  * @{ */
169 /** @brief SEC Parameter. */
170 typedef struct {
171     sec_mode_level_t level;         /**< Set the minimum security level of the device, see @ref sec_mode_level_t. */
172     sec_io_cap_t     io_cap;        /**< Set the IO capability, see @ref sec_io_cap_t. */
173     bool             oob;           /**< Indicate whether OOB is supported. */
174     uint8_t          auth;          /**< Set the auth, see @ref SEC_AUTH_FLAG. */
175     uint8_t          key_size;      /**< Indicate the supported maximum LTK size (range: 7-16). */
176     uint8_t          ikey_dist;     /**< Set the initial key distribution, see @ref SEC_KEY_DIST_FLAG. */
177     uint8_t          rkey_dist;     /**< Set the response key distribution, see @ref SEC_KEY_DIST_FLAG. */
178 } sec_param_t;
179 
180 /** @brief TK value. */
181 typedef struct {
182     uint8_t key[16];          /**< TK value. */
183 } sec_tk_t;
184 
185 /** @brief SEC OOB value. */
186 typedef struct {
187     uint8_t conf[16];        /**< Confirm value. */
188     uint8_t rand[16];        /**< Random value. */
189 } sec_oob_t;
190 
191 /** @brief SEC Confirm encryption data. */
192 typedef union {
193     sec_tk_t  tk;           /**< TK value, see @ref sec_tk_t. */
194     sec_oob_t oob;          /**< OOB value, see @ref sec_oob_t. */
195 } sec_cfm_enc_data_t;
196 
197 /** @brief SEC Confirm encryption. */
198 typedef struct {
199     sec_enc_req_type_t req_type;         /**< Request type, see @ref sec_enc_req_type_t. */
200     bool               accept;           /**< Indicate whether to accept the request. */
201     sec_cfm_enc_data_t data;             /**< SEC Confirm encryption data, see @ref sec_cfm_enc_data_t. */
202 } sec_cfm_enc_t;
203 
204 /** @brief SEC number comparison value. */
205 typedef struct {
206     uint8_t value[4];       /**< Number comparison value (000000~999999). */
207 } sec_nc_t;
208 
209 /** @brief SEC encryption request data. */
210 typedef union {
211     sec_tk_type_t tk_type;      /**<TK type, see @ref sec_tk_type_t. */
212     sec_oob_t     oob_data;     /**<OOB data, see @ref sec_oob_t. */
213     sec_nc_t      nc_data;      /**<Number comparison data, see @ref sec_nc_t. */
214 } sec_enc_req_data_t;
215 
216 /** @brief SEC encryption request. */
217 typedef struct {
218     sec_enc_req_type_t req_type;        /**< Indicate the request type, @ref sec_enc_req_type_t. */
219     sec_enc_req_data_t data;            /**< SEC encryption request data, @ref sec_enc_req_data_t. */
220 } sec_enc_req_t;
221 
222 /** @brief SEC register call back. */
223 typedef struct {
224     /**< Security manager module receives encryption request callback. */
225     void (*app_sec_enc_req_cb)(uint8_t conn_idx, sec_enc_req_t *p_enc_req);
226     /**< Security manager module receives encryption indication callback, see @ref SEC_AUTH_FLAG. */
227     void (*app_sec_enc_ind_cb)(uint8_t conn_idx, sec_enc_ind_t enc_ind, uint8_t auth);
228     /**< Security manager module receives key press notify callback. */
229     void (*app_sec_keypress_notify_cb)(uint8_t conn_idx, sec_keypress_notify_t notify_type);
230     /**< Security manager module receives key missing callback, see @ref sec_key_missing_reason_t. */
231     void (*app_sec_key_missing_cb)(uint8_t conn_idx, sec_key_missing_reason_t reason);
232 } sec_cb_fun_t;
233 /** @} */
234 
235 /** @addtogroup BLE_SEC_FUNCTIONS Functions
236  * @{ */
237 /**
238  ****************************************************************************************
239  * @brief Set security parameter.
240  *
241  * @param[in] p_sec_param Pointer to the security parameter structure, @ref sec_param_t.
242  *
243  * @retval ::SDK_SUCCESS: The security parameter is successfully set to the BLE stack.
244  * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied.
245  * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied.
246  ****************************************************************************************
247  */
248 uint16_t ble_sec_params_set(sec_param_t *p_sec_param);
249 
250 /**
251  ****************************************************************************************
252  * @brief Start security encryption, this interface is used by both slave and master
253  *
254  * @note If the local device role is master, it will check that if the peer device is bonded firstly.
255  *  If the peer device is bonded,
256  *  the stack will encrypt the link directly, otherwise the stack will send a pair request to the peer device.
257  *  During the pairing, the callback @ref sec_cb_fun_t::app_sec_enc_req_cb may be called.
258  *  After the link has been encrypted, the callback @ref sec_cb_fun_t::app_sec_enc_ind_cb will be called.
259  * @note If the local device role is slave, the stack will send a security request to the peer device.
260  *
261  * @param[in] conn_idx ACL connection index, the first ACL connection index is 0, and increased one by one.
262  *
263  * @retval ::SDK_SUCCESS: The security encryption is successfully set to the BLE stack.
264  * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
265  ****************************************************************************************
266  */
267 uint16_t ble_sec_enc_start(uint8_t conn_idx);
268 
269 /**
270  ****************************************************************************************
271  * @brief Send the encrypt confirm information
272  * @note This function should be called in the handle of callback @ref sec_cb_fun_t::app_sec_enc_req_cb.
273  *
274  * @param[in] conn_idx  ACL connection index, the first ACL connection index is 0, and increased one by one.
275  * @param[in] p_cfm_enc Pointer to the confirm encryption structure, see @ref sec_cfm_enc_t.
276  *
277  * @retval ::SDK_SUCCESS: The confirm encryption is successfully set to the BLE stack.
278  * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied.
279  * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
280  * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
281  ****************************************************************************************
282  */
283 uint16_t ble_sec_enc_cfm(uint8_t conn_idx, const sec_cfm_enc_t *p_cfm_enc);
284 
285 /**
286  ****************************************************************************************
287  * @brief Send key press notify
288  *
289  * @param[in] conn_idx    ACL connection index. The first ACL connection index is 0,
290  *            and the index will be increased one by one.
291  * @param[in] notify_type Key press notify type, see @ref sec_keypress_notify_t.
292  *
293  * @retval ::SDK_SUCCESS: The key press notify type is successfully set to the BLE stack.
294  * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
295  * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
296  ****************************************************************************************
297  */
298 uint16_t ble_sec_keypress_notify_send(uint8_t conn_idx, uint8_t notify_type);
299 /** @} */
300 
301 #endif
302 
303 /** @} */
304 /** @} */
305