1 /**
2  ****************************************************************************************
3  *
4  * @file smpc_api.h
5  *
6  * @brief Header file SMPC API.
7  *
8  * Copyright (C) RivieraWaves 2009-2016
9  *
10  *
11  ****************************************************************************************
12  */
13 
14 #ifndef SMPC_API_H_
15 #define SMPC_API_H_
16 
17 /**
18  ****************************************************************************************
19  * @addtogroup SMPC_API Task
20  * @ingroup SMPC
21  * @brief Provides a SMP API for controller tasks.
22  *
23  * The SMPC api is responsible for all security protocol and secure connections handling.
24  *
25  * @{
26  ****************************************************************************************
27  */
28 /*
29  * INCLUDE FILES
30  ****************************************************************************************
31  */
32 
33 
34 #include "rwip_config.h"
35 #if (BLE_SMPC)
36 #include "smp_common.h"
37 #include "gap.h"
38 #include "gapc_task.h"
39 #include "l2cc_pdu.h"
40 
41 /*
42  * DEFINES
43  ****************************************************************************************
44  */
45 
46 
47 /// check if flag is set
48 #define SMPC_IS_FLAG_SET(conidx, flag)        ((gapc_env[conidx]->smpc.timer_state & flag) == flag)
49 
50 #define SMPC_TIMER_SET_FLAG(conidx, flag)     (gapc_env[conidx]->smpc.timer_state |= flag)
51 
52 #define SMPC_TIMER_UNSET_FLAG(conidx, flag)   (gapc_env[conidx]->smpc.timer_state &= ~flag)
53 
54 
55 /**
56  * Timer State Masks
57  */
58 /// Timeout Timer
59 #define SMPC_TIMER_TIMEOUT_FLAG                 (0x01)
60 /// Repeated Attempts Timer
61 #define SMPC_TIMER_REP_ATT_FLAG                 (SMPC_TIMER_TIMEOUT_FLAG << 1)
62 /// Blocked because of SMP Timeout
63 #define SMPC_TIMER_TIMEOUT_BLOCKED_FLAG         (SMPC_TIMER_REP_ATT_FLAG << 1)
64 
65 
66 /// SMPC Internal State Code
67 enum smpc_state
68 {
69     SMPC_STATE_RESERVED     = 0x00,
70 
71     /********************************************************
72      * Pairing Procedure
73      ********************************************************/
74 
75     /**------------------------------------**
76      * Pairing Features Exchange Phase      *
77      **------------------------------------**/
78     /// Is waiting for the pairing response
79     SMPC_PAIRING_RSP_WAIT,
80     /// Is waiting for the pairing features
81     SMPC_PAIRING_FEAT_WAIT,
82 
83     /**------------------------------------**
84      * Legacy (Pre BT 4.2 ) Authentication and Encryption Phase  *
85      **------------------------------------**/
86 
87     /// Is waiting for the TK
88     SMPC_PAIRING_TK_WAIT,
89     /// Is waiting for the TK, peer confirm value has been received
90     SMPC_PAIRING_TK_WAIT_CONF_RCV,
91     /// Calculate the Random Number, part 1
92     SMPC_PAIRING_GEN_RAND_P1,
93     /// Calculate the Random Number, part 2
94     SMPC_PAIRING_GEN_RAND_P2,
95     /// The first part of the device's confirm value is being generated
96     SMPC_PAIRING_CFM_P1,  //7
97     /// The device's confirm value is being generated
98     SMPC_PAIRING_CFM_P2,
99     /// The first part of the peer device's confirm value is being generated
100     SMPC_PAIRING_REM_CFM_P1,
101     /// The peer device's confirm value is being generated
102     SMPC_PAIRING_REM_CFM_P2,
103     /// The device is waiting for the confirm value generated by the peer device
104     SMPC_PAIRING_WAIT_CONFIRM,  //b
105     /// The device is waiting for the random value generated by the peer device
106     SMPC_PAIRING_WAIT_RAND,
107     /// The STK is being generated
108     SMPC_PAIRING_GEN_STK,
109 
110     #if (SECURE_CONNECTIONS)
111     /**------------------------------------**
112      * Secure Connections (BT 4.2 ) Authentication and Encryption Phase  *
113      **------------------------------------**/
114      SMPC_PAIRING_SC_W4_PEER_PUBLIC_KEY,
115 
116      // Just Works and Numeric Comparison
117      //---------------------------------
118 
119      // In Just Works/Numeric Comparison - this state is used while
120      // we are waiting for the LL to generate a Rand.
121      SMPC_PAIRING_SC_W4_LOCAL_RAND_N_P1,
122      SMPC_PAIRING_SC_W4_LOCAL_RAND_N_P2,
123      // Used in Slave during F4 while waiting for AES_CMAC
124      SMPC_PAIRING_SC_W4_F4_COMMITMENT_DETERMINATION,
125 
126      // Used in Master to Wait for Peer Commitment Cb
127      SMPC_PAIRING_SC_W4_PEER_COMMITMENT,
128 
129      // Used in Master/Slave to Wait for Random Number From peer.
130      SMPC_PAIRING_SC_W4_PEER_RAND,
131 
132      // Used in Slave to wait for Random Number Na from Master
133     // SMPC_PAIRING_SC_W4_PAIRING_Na,
134 
135      // Used in Master during F4 calculation for Commitment Check
136      SMPC_PAIRING_SC_W4_F4_COMMITMENT_CHECK,
137 
138      // Numeric Comparison
139      // States specific to Secure Commenctions - numeric comparison
140 
141      // Used in both Master/Slave to wait for the AES-CMAC calculation does to calculated the
142      // PassCode for the user.
143 
144      SMPC_PAIRING_SC_W4_G2_AES_CMAC,
145 
146      // Wait for the user to enter Accept/Reject for the Numeric Value
147      SMPC_PAIRING_SC_W4_NC_ACCEPT,
148      // Used in both Master/Slave while waiting for the user Pass Code Confirmation.
149 
150      SMPC_PAIRING_SC_W4_USER_PASSCODE_CONFIRMATION,
151 
152      //-----------------------------
153      // Secure Connections - Passkey
154      //-----------------------------
155 
156     // Used in both Master/Slave while the user is entering the PassKey
157     SMPC_PAIRING_SC_PASSKEY_W4_PASSKEY_RAND,
158 
159     // Used in both Master/Slave while Random numbers Nai,Nbi are being generated.
160     SMPC_PAIRING_SC_PASSKEY_W4_LOCAL_RAND_N_P1,
161 
162     // Used in both Master/Slave while Random numbers Nai,Nbi are being generated.
163     SMPC_PAIRING_SC_PASSKEY_W4_LOCAL_RAND_N_P2,
164 
165     // Used in both Master/Slave while waiting for the commitment value Cai,Cbi from the peer
166     SMPC_PAIRING_SC_PASSKEY_W4_PEER_COMMITMENT,
167 
168     // Used in both Master/Slave while using AES_CMAC during F4 calculation of the commitment
169     SMPC_PAIRING_SC_PASSKEY_W4_F4_COMMITMENT_DETERMINATION,
170 
171     // Used in both Master/Slave while waiting for the random number Nai,Nbi from the peer
172     SMPC_PAIRING_SC_PASSKEY_W4_PEER_RAND,
173 
174     // Used in both Master/Slave while using AES_CMAC during F4 calculation for the commitment check
175     SMPC_PAIRING_SC_PASSKEY_W4_F4_COMMITMENT_CHECK,
176 
177 
178     // OOB
179     SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_N_P1,
180 
181     SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_N_P2,
182 
183     SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_R_P1,
184 
185     SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_R_P2,
186 
187     SMPC_PAIRING_SC_OOB_W4_F4_COMMITMENT_DETERMINATION,
188 
189     SMPC_PAIRING_SC_OOB_W4_F4_COMMITMENT_CHECK,
190 
191     SMPC_PAIRING_SC_OOB_W4_PEER_RAND,
192 
193     // Wait for OOB data (A,Ca,Ra OR B,Cb,Rb) to be recieved from Peer.
194     SMPC_PAIRING_SC_OOB_W4_OOB_DATA,
195 
196     // Secure Connections Authentication Phase 2
197 
198     // Wait for the AES_CMACsalt to generate T
199     SMPC_PAIRING_SC_W4_F5_P1,
200 
201     // Wait for the AES_CMAC to generate MACKEY
202     SMPC_PAIRING_SC_W4_F5_P2,
203 
204     // Wait for the AES_CMAC to generate LTK
205     SMPC_PAIRING_SC_W4_F5_P3,
206 
207     // Wait for the AES_CMAC to complete the DHKEY check
208     SMPC_PAIRING_SC_W4_F6_DHKEY_CHECK,
209 
210     // Wait for DHkey_Check from the peer
211     SMPC_PAIRING_SC_W4_PEER_DHKEY_CHECK,
212 
213     SMPC_PAIRING_SC_W4_F6_DHKEY_VERIFICATION,
214 
215     SMPC_PAIRING_SC_W4_DHKEY_KEY_COMPLETE,
216 
217     SMPC_PAIRING_SC_W4_ENCRYPTION_START,
218 
219     SMPC_PAIRING_SC_W4_ENCRYPTION_CHANGE,
220 
221     #endif //  (SECURE_CONNECTIONS)
222     /**------------------------------------**
223      * Transport Keys Distribution Phase    *
224      **------------------------------------**/
225 
226     /// Default pairing remote waiting state
227     SMPC_PAIRING_APP_WAIT,
228     /// Is waiting for the LTK from application
229     SMPC_PAIRING_APP_LTK_WAIT,
230     /// Is waiting for the Identity Resolving Key from application
231     SMPC_PAIRING_APP_IRK_WAIT,
232     /// Is waiting for the CSRK from application
233     SMPC_PAIRING_APP_CSRK_WAIT,
234 
235 
236     /// Default pairing remote waiting state
237     SMPC_PAIRING_REM_WAIT,
238     /// Is waiting for the remote LTK
239     SMPC_PAIRING_REM_LTK_WAIT,
240     /// Is waiting for the remote EDIV and Rand Value
241     SMPC_PAIRING_REM_MST_ID_WAIT,
242     /// Is waiting for the remote IRK
243     SMPC_PAIRING_REM_IRK_WAIT,
244     /// Is waiting for the remote BD Address
245     SMPC_PAIRING_REM_BD_ADDR_WAIT,
246     /// Is waiting for the remote CSRK
247     SMPC_PAIRING_REM_CSRK_WAIT,
248 
249     /********************************************************
250      * Signing Procedure
251      ********************************************************/
252     /// Generation of L
253     SMPC_SIGN_L_GEN,
254     /// Generation of Ci
255     SMPC_SIGN_Ci_GEN,
256 
257     /********************************************************
258      * Encryption Procedure (STK or LTK)
259      ********************************************************/
260     /// Is waiting the change encryption event with LTK
261     SMPC_START_ENC_LTK,
262     /// Is waiting the change encryption event with STK
263     SMPC_START_ENC_STK
264 };
265 
266 /*
267  * FUNCTION DEFINITION
268  ****************************************************************************************
269  */
270 
271 #if (BLE_CENTRAL)
272 /**
273  ****************************************************************************************
274  * @brief Handles pairing request from GAP, start the pairing procedure
275  *
276  * @param[in] idx     Connection Index
277  * @param[in] pairing Pairing Information
278  *
279  * @return Status of Pairing start
280  ****************************************************************************************
281  */
282 uint8_t smpc_pairing_start(uint8_t idx, struct gapc_pairing  *pairing);
283 #endif // (BLE_CENTRAL)
284 
285 
286 /**
287  ****************************************************************************************
288  * @brief Handles TK exchange part of pairing
289  *
290  * @param[in] idx     Connection Index
291  * @param[in] accept  True if pairing is accepted, False else
292  * @param[in] tk      The TK transmitted by application
293  *
294  * @return status of pairing
295  ****************************************************************************************
296  */
297 uint8_t smpc_pairing_tk_exch(uint8_t idx, bool accept,  struct gap_sec_key *tk);
298 
299 /**
300  ****************************************************************************************
301  * @brief Handles LTK exchange part of pairing
302  *
303  * @param[in] idx     Connection Index
304  * @param[in] ltk     The LTK transmitted by application
305  *
306  * @return status of pairing
307  ****************************************************************************************
308  */
309 uint8_t smpc_pairing_ltk_exch(uint8_t idx, struct gapc_ltk* ltk);
310 
311 
312 /**
313  ****************************************************************************************
314  * @brief Handles IRK exchange part of pairing
315  *
316  * @param[in] idx      Connection Index
317  * @param[in] irk      The IRK transmitted by application
318  * @param[in] identity Device identity address
319  *
320  * @return status of pairing
321  ****************************************************************************************
322  */
323 uint8_t smpc_pairing_irk_exch(uint8_t idx, struct gap_sec_key* irk, struct gap_bdaddr *identity);
324 
325 /**
326  ****************************************************************************************
327  * @brief Handles CSRK exchange part of pairing
328  *
329  * @param[in] idx     Connection Index
330  * @param[in] csrk    The CSRK transmitted by application
331  *
332  * @return status of pairing
333  ****************************************************************************************
334  */
335 uint8_t smpc_pairing_csrk_exch(uint8_t idx, struct gap_sec_key *csrk);
336 
337 #if (SECURE_CONNECTIONS)
338 /**
339  ****************************************************************************************
340  * @brief Handles OOB exchange part of pairing
341  *
342  * @param[in] idx     Connection Index
343  * @param[in] accept  Accept or Reject the OOB (reject if OOB reception not available on the device)
344  * @param[in] csrk    The OOB Confirm and OOB Rand from the peer
345  *
346  * @return status of pairing
347  ****************************************************************************************
348  */
349 
350 uint8_t smpc_pairing_oob_exch(uint8_t idx, bool accept, struct gapc_oob *oob);
351 
352 /**
353  ****************************************************************************************
354  * @brief Handles Numeric Value Acceptance as part of pairing
355  *
356  * @param[in] idx     Connection Index
357  * @param[in] accept  Accept or Reject the numeric comparison
358  *
359  * @return status of pairing
360  ****************************************************************************************
361  */
362 
363 uint8_t smpc_pairing_nc_exch(uint8_t idx,uint8_t accept );
364 
365 #endif //  (SECURE_CONNECTIONS)
366 /**
367  ****************************************************************************************
368  * @brief Handles reception of pairing response information
369  *
370  * @param[in] idx     Connection Index
371  * @param[in] accept  True if pairing is accepted, False else
372  * @param[in] feat    Pairing response feature information
373  *
374  * @return status of pairing
375  ****************************************************************************************
376  */
377 uint8_t smpc_pairing_rsp(uint8_t idx, bool accept, struct gapc_pairing *feat);
378 
379 
380 #if (BLE_PERIPHERAL)
381 
382 /**
383  ****************************************************************************************
384  * @brief Handles reception of pairing request information
385  *
386  * @param[in] idx     Connection Index
387  * @param[in] feat    Pairing request feature information
388  ****************************************************************************************
389  */
390 void smpc_pairing_req_handler(uint8_t idx, struct gapc_pairing *feat);
391 
392 /**
393  ****************************************************************************************
394  * @brief Handles request to send a security request to peer device
395  *
396  * @param[in] idx     Connection Index
397  * @param[in] auth    Requested Authentication Level
398  *
399  * @return status of the request
400  ****************************************************************************************
401  */
402 uint8_t smpc_security_req_send(uint8_t idx, uint8_t auth);
403 #endif // (BLE_PERIPHERAL)
404 
405 
406 #if (BLE_CENTRAL)
407 /**
408  ****************************************************************************************
409  * @brief Master requests to start encryption
410  *
411  * @param[in] idx     Connection Index
412  * @param[in] ltk     LTK information
413  *
414  * @return status of the request
415  ****************************************************************************************
416  */
417 uint8_t smpc_encrypt_start(uint8_t idx, struct gapc_ltk *ltk);
418 #endif //(BLE_CENTRAL)
419 
420 
421 #if (BLE_PERIPHERAL)
422 
423 /**
424  ****************************************************************************************
425  * @brief Handles reception of encryption request
426  *
427  * @param[in] idx     Connection Index
428  * @param[in] ltk     LTK to search information
429  ****************************************************************************************
430  */
431 void smpc_encrypt_start_handler(uint8_t idx, struct gapc_ltk *ltk);
432 
433 /**
434  ****************************************************************************************
435  * @brief Slave respond to peer device encryption request
436  *
437  * @param[in] idx      Connection Index
438  * @param[in] accept   Accept or not to start encryption
439  * @param[in] ltk      LTK information
440  * @param[in] key_size Encryption key size
441  ****************************************************************************************
442  */
443 void smpc_encrypt_cfm(uint8_t idx, bool accept, struct gap_sec_key *ltk, uint8_t key_size);
444 #endif //(BLE_PERIPHERAL)
445 
446 
447 /**
448  ****************************************************************************************
449  * @brief Request to sign an attribute packet or check signature
450  *
451  * @param[in] idx      Connection Index
452  * @param[in] param    ATT packet information
453  *
454  * @return status of signature request
455  ****************************************************************************************
456  */
457 uint8_t smpc_sign_command(uint8_t idx, struct gapc_sign_cmd *param);
458 
459 
460 /**
461  ****************************************************************************************
462  * @brief Continue signature generation or check of an attribute packet after an AES.
463  *
464  * @param[in] idx      Connection Index
465  * @param[in] aes_res  Result of AES calculation
466  ****************************************************************************************
467  */
468 void smpc_sign_cont(uint8_t idx, uint8_t* aes_res);
469 
470 /**
471  ****************************************************************************************
472  * @brief Continue generation of rand number for confirm value.
473  *
474  * @param[in] idx      Connection Index
475  * @param[in] randnb   Generated Random Number
476  ****************************************************************************************
477  */
478 void smpc_confirm_gen_rand(uint8_t idx, rand_nb_t* randnb);
479 
480 /**
481  ****************************************************************************************
482  * @brief Continue Calculation of Confirm Value or STK after AES.
483  *
484  * @param[in] idx      Connection Index
485  * @param[in] aes_res  Result of AES calculation
486  ****************************************************************************************
487  */
488 void smpc_calc_confirm_cont(uint8_t idx, uint8_t* aes_res);
489 
490 /**
491  ****************************************************************************************
492  * @brief Send an KeyPress Notification Event to the Host
493  *
494  * @param[in] idx      Connection Index
495  * @param[in] keypress KeyPress Type
496  ****************************************************************************************
497  */
498 void smpc_key_press_notification_ind(uint8_t idx, uint8_t keypress);
499 
500 /**
501  ****************************************************************************************
502  * @brief Stop the timer used to detect a SMP Timeout
503  *
504  * @param[in] conidx        Connection Index
505  ****************************************************************************************
506  */
507 void smpc_clear_timeout_timer(uint8_t conidx);
508 
509 
510 /**
511  ****************************************************************************************
512  * @brief Handle reception of a SMP PDU sent by the peer device.
513  *
514  * @param[in] conidx        Connection Index
515  * @param[in] pdu           Unpacked PDU
516  ****************************************************************************************
517  */
518 void smpc_pdu_recv(uint8_t conidx, struct l2cc_pdu *pdu);
519 
520 /**
521  ****************************************************************************************
522  * @brief Send a SMP PDU to the peer device
523  *
524  * @param[in] conidx        Connection Index
525  * @param[in] cmd_code      Code of the PDU to send
526  * @param[in] value         Unpacked value
527  ****************************************************************************************
528  */
529 void smpc_pdu_send(uint8_t conidx, uint8_t cmd_code, void *value);
530 
531 
532 /**
533  ****************************************************************************************
534  * @brief Inform the HL that the pairing procedure currently in progress is over.
535  *
536  * @param[in] conidx          Connection Index
537  * @param[in] role            Current role of the device
538  * @param[in] status          Status
539  * @param[in] start_ra_timer  Indicate if the repeated attempts timer shall be started in
540  *                            the case of a pairing failed.
541  ****************************************************************************************
542  */
543 void smpc_pairing_end(uint8_t conidx, uint8_t role, uint8_t status, bool start_ra_timer);
544 
545 
546 /**
547  ****************************************************************************************
548  * @brief Handle reception of a DH Key from HCI
549  *
550  * @param[in] conidx        Connection Index
551  * @param[in] status        Indicates if HCI request Succeeded or Failed
552  * @param[in] dh_key        Diffie Helman Key - 32 Bytes
553  ****************************************************************************************
554  */
555 void smpc_handle_dh_key_check_complete(uint8_t conidx,const uint8_t* dh_key);
556 
557 #endif // (BLE_SMPC)
558 #endif //(SMPC_API_H_)
559 
560 /// @} SMPC_API
561