1 /**
2  ****************************************************************************************
3  *
4  * @file app_sec.c
5  *
6  * @brief Application Security Entry Point
7  *
8  * Copyright (C) RivieraWaves 2009-2015
9  *
10  *
11  ****************************************************************************************
12  */
13 
14 /**
15  ****************************************************************************************
16  * @addtogroup APP
17  * @{
18  ****************************************************************************************
19  */
20 
21 /*
22  * INCLUDE FILES
23  ****************************************************************************************
24  */
25 
26 #include "rwip_config.h"
27 #include <stdbool.h>
28 //#include "ble_arch.h"
29 
30 #if (BLE_APP_SEC)
31 
32 #include <string.h>
33 #include "co_math.h"
34 #include "gapc_task.h"      // GAP Controller Task API Definition
35 #include "gapm_task.h"      // GAPM task API definition
36 #include "gap.h"            // GAP Definition
37 #include "gapc.h"           // GAPC Definition
38 #include "gapm.h"
39 #include "prf_types.h"
40 
41 #include "app.h"            // Application API Definition
42 #include "app_sec.h"        // Application Security API Definition
43 #include "app_task.h"       // Application Manager API Definition
44 #include "interface.h"
45 
46 #if (NVDS_SUPPORT)
47 #include "nvds.h"           // NVDS API Definitions
48 #endif //(NVDS_SUPPORT)
49 /*
50  * GLOBAL VARIABLE DEFINITIONS
51  ****************************************************************************************
52  */
53 
54 /// Application Security Environment Structure
55 struct app_sec_env_tag app_sec_env;
56 
57 
58 
59 //struct current_bond_info_t current_bond_info;
60 /*
61  * GLOBAL FUNCTION DEFINITIONS
62  ****************************************************************************************
63  */
64 
app_sec_msg_dflt_handler(ke_msg_id_t const msgid,void * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)65 static int app_sec_msg_dflt_handler(ke_msg_id_t const msgid,
66                                         void*param,
67                                     ke_task_id_t const dest_id,
68                                     ke_task_id_t const src_id)
69 {
70     return (KE_MSG_CONSUMED);
71 }
72 
app_sec_init()73 void app_sec_init()
74 {
75     /*------------------------------------------------------
76      * RETRIEVE BOND STATUS
77      *------------------------------------------------------*/
78     #if (NVDS_SUPPORT)
79     uint8_t length = NVDS_LEN_PERIPH_BONDED;
80     // Get bond status from NVDS
81     if (nvds_get(NVDS_TAG_PERIPH_BONDED, &length, (uint8_t *)&app_sec_env.bonded) != NVDS_OK)
82     {
83         // If read value is invalid, set status to not bonded
84         app_sec_env.bonded = false;
85     }
86 /************************************************************************************************************/
87     uint8_t length1 = NVDS_LEN_DEVICE_NUM;
88 
89     if (nvds_get(NVDS_TAG_DEVICE_NUM, &length1, &app_sec_env.device_num) != NVDS_OK)
90     {
91         // If read value is invalid, set device number to 0
92         app_sec_env.device_num = 0;
93     }
94 /************************************************************************************************************/
95 
96 
97 
98     #endif //(NVDS_SUPPORT)
99 }
100 
101 
app_sec_send_security_req(uint8_t conidx)102 void app_sec_send_security_req(uint8_t conidx)
103 {
104 
105       //start to security cmd
106       struct gapc_security_cmd *cmd = KE_MSG_ALLOC(GAPC_SECURITY_CMD,
107                  KE_BUILD_ID(TASK_GAPC, app_env.conidx), TASK_APP, gapc_security_cmd);// Security request
108       cmd->operation = GAPC_SECURITY_REQ;
109 
110       cmd->auth = GAP_AUTH_REQ_NO_MITM_BOND;
111 
112       //iocap will select MITM or not
113 
114       // Send the message
115       ke_msg_send(cmd);
116 }
117 
118 
119 /**
120  ****************************************************************************************
121  * @brief Handles reception of bond request command
122  *
123  * @param[in] msgid     Id of the message received.
124  * @param[in] param     Pointer to the parameters of the message.
125  * @param[in] dest_id   ID of the receiving task instance (TASK_GAP).
126  * @param[in] src_id    ID of the sending task instance.
127  *
128  * @return If the message was consumed or not.
129  ****************************************************************************************
130  */
gapc_bond_req_ind_handler(ke_msg_id_t const msgid,struct gapc_bond_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)131 static int gapc_bond_req_ind_handler(ke_msg_id_t const msgid,struct gapc_bond_req_ind const *param,ke_task_id_t const dest_id,ke_task_id_t const src_id)
132 {
133     struct gapc_bond_cfm *cfm = KE_MSG_ALLOC(GAPC_BOND_CFM,src_id, TASK_APP,gapc_bond_cfm);
134     switch (param->request)
135     {
136         case (GAPC_PAIRING_REQ):
137         {
138             cfm->request = GAPC_PAIRING_RSP;
139             cfm->accept = true;
140 
141             // OOB information
142             cfm->data.pairing_feat.oob            = GAP_OOB_AUTH_DATA_NOT_PRESENT;
143             // Encryption key size
144             cfm->data.pairing_feat.key_size       = KEY_LEN;
145             // IO capabilities
146             cfm->data.pairing_feat.iocap          = app_env.iocap;
147             // Authentication requirements
148             cfm->data.pairing_feat.auth           = GAP_AUTH_REQ_NO_MITM_BOND; //GAP_AUTH_REQ_NO_MITM_BOND;
149 
150             cfm->data.pairing_feat.ikey_dist      = GAP_KDIST_NONE;
151             //Responder key distribution
152             cfm->data.pairing_feat.rkey_dist      = GAP_KDIST_ENCKEY;
153             //Security requirements
154             cfm->data.pairing_feat.sec_req        = GAP_NO_SEC;
155 
156         }
157         break;
158 
159         case(GAPC_LTK_EXCH):
160         {
161 
162             uint8_t counter;
163 
164             cfm->data.ltk.ediv = (uint16_t)( (co_rand_word() + app_env.loc_irk[1]*256 + app_env.loc_irk[0]) );
165 
166             for(counter = 0; counter < RAND_NB_LEN; counter++)
167             {
168                 cfm->data.ltk.randnb.nb[counter] = (uint8_t)((co_rand_word() + app_env.loc_irk[counter])  );
169             }
170 
171             for(counter = 0; counter < KEY_LEN; counter++)
172             {
173                 cfm->data.ltk.ltk.key[counter]    = (uint8_t)((co_rand_word() + app_env.loc_irk[counter]) );
174             }
175 
176             cfm->request = GAPC_LTK_EXCH;
177 
178             cfm->accept = true;
179 
180 #if (NVDS_SUPPORT)
181 
182             switch (app_sec_env.device_num % 5)
183             {
184                 case 0:
185                     if (nvds_put(NVDS_TAG_LTK, NVDS_LEN_LTK, (uint8_t *)&cfm->data.ltk) != NVDS_OK)
186                     {
187                         ASSERT_ERR(0);
188                     }
189                     break;
190                 case 1:
191                     if (nvds_put(NVDS_TAG_LTK1, NVDS_LEN_LTK1, (uint8_t *)&cfm->data.ltk) != NVDS_OK)
192                     {
193                         ASSERT_ERR(0);
194                     }
195                     break;
196                 case 2:
197                     if (nvds_put(NVDS_TAG_LTK2, NVDS_LEN_LTK2, (uint8_t *)&cfm->data.ltk) != NVDS_OK)
198                     {
199                         ASSERT_ERR(0);
200                     }
201                     break;
202                 case 3:
203                     if (nvds_put(NVDS_TAG_LTK3, NVDS_LEN_LTK3, (uint8_t *)&cfm->data.ltk) != NVDS_OK)
204                     {
205                         ASSERT_ERR(0);
206                     }
207                     break;
208 
209                 case 4:
210                     if (nvds_put(NVDS_TAG_LTK4, NVDS_LEN_LTK4, (uint8_t *)&cfm->data.ltk) != NVDS_OK)
211                     {
212                         ASSERT_ERR(0);
213                     }
214                     break;
215                 default:
216                     break;
217             }
218             app_sec_env.device_num = (app_sec_env.device_num + 1) % 5;
219 
220             uint8_t device_num[1]={0};
221             uint8_t length = NVDS_LEN_DEVICE_NUM;
222             nvds_get(NVDS_TAG_DEVICE_NUM, &length, device_num);
223 
224             if (device_num[0]<app_sec_env.device_num)
225             {
226                 if (nvds_put(NVDS_TAG_DEVICE_NUM, NVDS_LEN_DEVICE_NUM,&app_sec_env.device_num) != NVDS_OK)
227                 {
228                     // An error has occurred during access to the NVDS
229                     ASSERT_ERR(0);
230                 }
231             }
232 #endif // #if (NVDS_SUPPORT)
233         }
234         break;
235 
236 
237         case (GAPC_IRK_EXCH):
238         {
239             #if (NVDS_SUPPORT)
240             uint8_t addr_len = BD_ADDR_LEN;
241             #endif //(NVDS_SUPPORT)
242 
243             cfm->request = GAPC_IRK_EXCH;
244             cfm->accept  = true;
245 
246             // Load IRK
247             memcpy(cfm->data.irk.irk.key, app_env.loc_irk, KEY_LEN);
248             // load device address
249             cfm->data.irk.addr.addr_type = ADDR_PUBLIC;
250             #if (NVDS_SUPPORT)
251             if (nvds_get(NVDS_TAG_BD_ADDRESS, &addr_len, cfm->data.irk.addr.addr.addr) != NVDS_OK)
252             #endif //(NVDS_SUPPORT)
253             {
254                 ASSERT_ERR(0);
255             }
256         }
257         break;
258 
259 
260         case (GAPC_TK_EXCH):
261         {
262             if (param->data.tk_type == GAP_TK_DISPLAY)
263             {
264                 cfm->request = GAPC_TK_EXCH;
265                 cfm->accept = true;
266 
267                 memset(cfm->data.tk.key, 0, KEY_LEN);
268                 cfm->data.tk.key[0] = (uint8_t)((app_env.pin_code & 0x000000FF) >>  0);
269                 cfm->data.tk.key[1] = (uint8_t)((app_env.pin_code & 0x0000FF00) >>  8);
270                 cfm->data.tk.key[2] = (uint8_t)((app_env.pin_code & 0x00FF0000) >> 16);
271                 cfm->data.tk.key[3] = (uint8_t)((app_env.pin_code & 0xFF000000) >> 24);
272 
273             }
274             else
275             {
276                 ASSERT_ERR(0);
277             }
278 
279         }
280         break;
281 
282         default:
283         {
284             ASSERT_ERR(0);
285         }
286         break;
287     }
288 
289     // Send the message
290    // interface_env.delay_ms(5);
291     ke_msg_send(cfm);
292 
293     return (KE_MSG_CONSUMED);
294 }
295 
296 
297 
298 /**
299  ****************************************************************************************
300  * @brief Handles reception of bond indication
301  *
302  * @param[in] msgid     Id of the message received.
303  * @param[in] param     Pointer to the parameters of the message.
304  * @param[in] dest_id   ID of the receiving task instance (TASK_GAP).
305  * @param[in] src_id    ID of the sending task instance.
306  *
307  * @return If the message was consumed or not.
308  ****************************************************************************************
309  */
gapc_bond_ind_handler(ke_msg_id_t const msgid,struct gapc_bond_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)310 static int gapc_bond_ind_handler(ke_msg_id_t const msgid,struct gapc_bond_ind const *param,ke_task_id_t const dest_id,ke_task_id_t const src_id)
311 {
312     switch (param->info)
313     {
314         case (GAPC_PAIRING_SUCCEED):
315         {
316             // Update the bonding status in the environment
317             app_sec_env.bonded = true;
318             ke_state_set(TASK_APP, APPM_ENCRYPTED);//lizhk add
319             // Update the bonding status in the environment
320             #if (PLF_NVDS)
321 //          if (nvds_put(NVDS_TAG_PERIPH_BONDED, NVDS_LEN_PERIPH_BONDED,(uint8_t *)&app_sec_env.bonded) != NVDS_OK)
322 //            {
323 //                // An error has occurred during access to the NVDS
324 //                ASSERT_ERR(0);
325 //            }
326 //           gapc_save_bond_info();
327 
328             #endif //(PLF_NVDS)
329 
330         }
331         break;
332 
333         case (GAPC_REPEATED_ATTEMPT):
334         {
335             appm_disconnect();
336         }
337         break;
338 
339         case (GAPC_IRK_EXCH):
340         {
341         }
342         break;
343 
344         case (GAPC_PAIRING_FAILED):
345         {
346             app_sec_send_security_req(0);
347         }
348         break;
349 
350         // In Secure Connections we get BOND_IND with SMPC calculated LTK
351         case (GAPC_LTK_EXCH) :
352         {
353 
354         }
355         break;
356 
357         case (GAPC_CSRK_EXCH) :
358         {
359 
360         }
361         break;
362 
363         default:
364         {
365             ASSERT_ERR(0);
366         }
367         break;
368     }
369 
370     return (KE_MSG_CONSUMED);
371 }
372 extern void BT_handle(void);
gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid,struct gapc_encrypt_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)373 static int gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid,
374                                         struct gapc_encrypt_req_ind const *param,
375                                         ke_task_id_t const dest_id,
376                                         ke_task_id_t const src_id)
377 {
378     #if (NVDS_SUPPORT)
379     // LTK value
380     struct gapc_ltk ltk;
381     // Length
382     uint8_t length = NVDS_LEN_LTK;
383 
384     #endif // #if (NVDS_SUPPORT)
385 
386     // Prepare the GAPC_ENCRYPT_CFM message
387     struct gapc_encrypt_cfm *cfm = KE_MSG_ALLOC(GAPC_ENCRYPT_CFM,src_id, TASK_APP,gapc_encrypt_cfm);
388     cfm->found    = false;
389     //移出未使用变量 app_sec_env.bonded
390 
391 
392     #if (NVDS_SUPPORT)
393     // Retrieve the required informations from NVD
394     uint8_t err = 1;
395 
396     uint8_t device_num[1]={0};
397     uint8_t length1 = NVDS_LEN_DEVICE_NUM;
398     nvds_get(NVDS_TAG_DEVICE_NUM, &length1, device_num);
399 
400     for(uint8_t i=0;i<device_num[0];i++)
401     {
402         switch (i+1)
403             {
404         case 1:
405          err = nvds_get(NVDS_TAG_LTK, &length, (uint8_t *)&ltk);
406         break;
407 
408         case 2:
409          err = nvds_get(NVDS_TAG_LTK1, &length, (uint8_t *)&ltk);
410         break;
411 
412         case 3:
413          err = nvds_get(NVDS_TAG_LTK2, &length, (uint8_t *)&ltk);
414         break;
415 
416         case 4:
417          err = nvds_get(NVDS_TAG_LTK3, &length, (uint8_t *)&ltk);
418         break;
419 
420         case 5:
421          err = nvds_get(NVDS_TAG_LTK4, &length, (uint8_t *)&ltk);
422         break;
423 
424         default:
425             break;
426 
427         }
428 
429         if (err == NVDS_OK)
430         {
431             // Check if the provided EDIV and Rand Nb values match with the stored values
432 
433             if ((param->ediv == ltk.ediv) &&!memcmp(&param->rand_nb.nb[0], &ltk.randnb.nb[0], sizeof(struct rand_nb)))
434             {
435                 cfm->found    = true;
436                 cfm->key_size = 16;
437                 memcpy(&cfm->ltk, &ltk.ltk, sizeof(struct gap_sec_key));
438                 app_env.con_device_num = i;
439                 ke_state_set(TASK_APP,APPM_ENCRYPTED);
440 
441                 break;
442             }
443 
444         }
445     }
446     uint8_t found_flag = cfm->found;
447     #endif // #if (NVDS_SUPPORT)
448     ke_msg_send(cfm);
449 
450     if (found_flag == false)
451     {
452         uint8_t schedule_num = 10;
453         while (schedule_num--)
454         {
455             BT_handle();
456         }
457         eif_delay_ms(200);
458         app_sec_send_security_req(0);
459     }
460 
461 
462     return (KE_MSG_CONSUMED);
463 }
464 
465 
gapc_encrypt_ind_handler(ke_msg_id_t const msgid,struct gapc_encrypt_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)466 static int gapc_encrypt_ind_handler(ke_msg_id_t const msgid,
467                                     struct gapc_encrypt_ind const *param,
468                                     ke_task_id_t const dest_id,
469                                     ke_task_id_t const src_id)
470 {
471     ke_state_set(TASK_APP, APPM_ENCRYPTED);
472     return (KE_MSG_CONSUMED);
473 }
474 
475 
476 
477  /*
478   * LOCAL VARIABLE DEFINITIONS
479   ****************************************************************************************
480   */
481 
482 /// Default State handlers definition
483 const struct ke_msg_handler app_sec_msg_handler_list[] =
484 {
485     // Note: first message is latest message checked by kernel so default is put on top.
486     {KE_MSG_DEFAULT_HANDLER,  (ke_msg_func_t)app_sec_msg_dflt_handler},
487 
488     {GAPC_BOND_REQ_IND,       (ke_msg_func_t)gapc_bond_req_ind_handler},
489     {GAPC_BOND_IND,           (ke_msg_func_t)gapc_bond_ind_handler},
490 
491     {GAPC_ENCRYPT_REQ_IND,    (ke_msg_func_t)gapc_encrypt_req_ind_handler},
492     {GAPC_ENCRYPT_IND,        (ke_msg_func_t)gapc_encrypt_ind_handler},
493 };
494 
495 const struct ke_state_handler app_sec_table_handler ={&app_sec_msg_handler_list[0], (sizeof(app_sec_msg_handler_list) / sizeof(struct ke_msg_handler))};
496 
497 #endif //(BLE_APP_SEC)
498 
499 
500 
501 /// @} APP
502