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 *)<k);
406 break;
407
408 case 2:
409 err = nvds_get(NVDS_TAG_LTK1, &length, (uint8_t *)<k);
410 break;
411
412 case 3:
413 err = nvds_get(NVDS_TAG_LTK2, &length, (uint8_t *)<k);
414 break;
415
416 case 4:
417 err = nvds_get(NVDS_TAG_LTK3, &length, (uint8_t *)<k);
418 break;
419
420 case 5:
421 err = nvds_get(NVDS_TAG_LTK4, &length, (uint8_t *)<k);
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(¶m->rand_nb.nb[0], <k.randnb.nb[0], sizeof(struct rand_nb)))
434 {
435 cfm->found = true;
436 cfm->key_size = 16;
437 memcpy(&cfm->ltk, <k.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