security_dispatcher.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "security_dispatcher.h"
  13. #include <string.h>
  14. #include "ble.h"
  15. #include "ble_gap.h"
  16. #include "ble_conn_state.h"
  17. #include "peer_manager_types.h"
  18. #include "peer_database.h"
  19. #include "id_manager.h"
  20. #include "sdk_common.h"
  21. #define MAX_REGISTRANTS 3 /**< The number of user that can register with the module. */
  22. typedef struct
  23. {
  24. smd_evt_handler_t evt_handlers[MAX_REGISTRANTS];
  25. uint8_t n_registrants;
  26. ble_conn_state_user_flag_id_t flag_id_sec_proc;
  27. ble_conn_state_user_flag_id_t flag_id_sec_proc_pairing;
  28. ble_conn_state_user_flag_id_t flag_id_sec_proc_new_peer;
  29. ble_gap_lesc_p256_pk_t peer_pk;
  30. } smd_t;
  31. static smd_t m_smd =
  32. {
  33. .flag_id_sec_proc = BLE_CONN_STATE_USER_FLAG_INVALID,
  34. .flag_id_sec_proc_pairing = BLE_CONN_STATE_USER_FLAG_INVALID,
  35. .flag_id_sec_proc_new_peer = BLE_CONN_STATE_USER_FLAG_INVALID,
  36. };
  37. #define MODULE_INITIALIZED (m_smd.n_registrants > 0) /**< Expression which is true when the module is initialized. */
  38. #include "sdk_macros.h"
  39. static void evt_send(smd_evt_t * p_event)
  40. {
  41. for (int i = 0; i < m_smd.n_registrants; i++)
  42. {
  43. m_smd.evt_handlers[i](p_event);
  44. }
  45. }
  46. static void sec_start_send(uint16_t conn_handle, pm_conn_sec_procedure_t procedure)
  47. {
  48. smd_evt_t evt =
  49. {
  50. .evt_id = SMD_EVT_SEC_PROCEDURE_START,
  51. .conn_handle = conn_handle,
  52. .params = {.sec_procedure_start = {.procedure = procedure}}
  53. };
  54. evt_send(&evt);
  55. }
  56. /**@brief Event handler for events from the peer_database module.
  57. *
  58. * @param[in] p_event The event that has happened.
  59. */
  60. static void pdb_evt_handler(pdb_evt_t const * p_event)
  61. {
  62. if ((p_event->evt_id == PDB_EVT_WRITE_BUF_STORED) && (p_event->data_id == PM_PEER_DATA_ID_BONDING))
  63. {
  64. smd_evt_t evt =
  65. {
  66. .evt_id = SMD_EVT_BONDING_INFO_STORED,
  67. .conn_handle = im_conn_handle_get(p_event->peer_id),
  68. .params = {.bonding_info_stored =
  69. {
  70. .peer_id = p_event->peer_id,
  71. }}
  72. };
  73. evt_send(&evt);
  74. }
  75. }
  76. /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST event from the SoftDevice.
  77. *
  78. * @param[in] p_gap_evt The event from the SoftDevice.
  79. */
  80. static void sec_params_request_process(ble_gap_evt_t * p_gap_evt)
  81. {
  82. smd_evt_t evt =
  83. {
  84. .evt_id = SMD_EVT_PARAMS_REQ,
  85. .conn_handle = p_gap_evt->conn_handle
  86. };
  87. evt_send(&evt);
  88. return;
  89. }
  90. /**@brief Function for administrative actions to be taken when a security process has been attempted.
  91. *
  92. * @param[in] conn_handle The connection the security process was attempted on.
  93. * @param[in] peer_id The peer ID given to the connected peer.
  94. * @param[in] success Whether the process was started successfully.
  95. * @param[in] pairing Whether the process was a pairing process.
  96. * @param[in] new_peer_created Whether a new peer was created during the process attempt.
  97. */
  98. static void sec_proc_start(uint16_t conn_handle,
  99. pm_peer_id_t peer_id,
  100. bool success,
  101. bool pairing,
  102. bool new_peer_created)
  103. {
  104. ble_conn_state_user_flag_set(conn_handle, m_smd.flag_id_sec_proc, success);
  105. if (success)
  106. {
  107. ble_conn_state_user_flag_set(conn_handle, m_smd.flag_id_sec_proc_pairing, pairing);
  108. ble_conn_state_user_flag_set(conn_handle, m_smd.flag_id_sec_proc_new_peer, new_peer_created);
  109. if(new_peer_created)
  110. {
  111. im_new_peer_id(conn_handle, peer_id);
  112. }
  113. }
  114. else
  115. {
  116. if(new_peer_created)
  117. {
  118. ret_code_t err_code = im_peer_free(peer_id); // Attempt to free allocated peer.
  119. UNUSED_VARIABLE(err_code);
  120. }
  121. }
  122. }
  123. /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_INFO_REQUEST event from the SoftDevice.
  124. *
  125. * @param[in] p_gap_evt The event from the SoftDevice.
  126. */
  127. static void sec_info_request_process(ble_gap_evt_t * p_gap_evt)
  128. {
  129. ret_code_t err_code;
  130. ble_gap_enc_info_t const * p_enc_info = NULL;
  131. pm_peer_data_flash_t peer_data;
  132. pm_peer_id_t peer_id = im_peer_id_get_by_master_id(&p_gap_evt->params.sec_info_request.master_id);
  133. smd_evt_t evt;
  134. evt.conn_handle = p_gap_evt->conn_handle;
  135. if (peer_id == PM_PEER_ID_INVALID)
  136. {
  137. peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle);
  138. }
  139. if (peer_id != PM_PEER_ID_INVALID)
  140. {
  141. err_code = pdb_read_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data, NULL);
  142. if (err_code == NRF_SUCCESS)
  143. {
  144. // There is stored bonding data for this peer.
  145. ble_gap_enc_key_t const * p_existing_key = &peer_data.p_bonding_data->own_ltk;
  146. if ( p_existing_key->enc_info.lesc
  147. || (im_master_ids_compare(&p_existing_key->master_id,
  148. &p_gap_evt->params.sec_info_request.master_id)))
  149. {
  150. p_enc_info = &p_existing_key->enc_info;
  151. }
  152. }
  153. }
  154. // All return values from the following can be safely ignored.
  155. err_code = sd_ble_gap_sec_info_reply(p_gap_evt->conn_handle, p_enc_info, NULL, NULL);
  156. if (err_code != NRF_SUCCESS)
  157. {
  158. evt.evt_id = SMD_EVT_ERROR_UNEXPECTED;
  159. evt.params.error_unexpected.error = err_code;
  160. evt_send(&evt);
  161. }
  162. else if (p_enc_info == NULL)
  163. {
  164. evt.evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED;
  165. evt.params.link_encryption_failed.error = PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING;
  166. evt.params.link_encryption_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL;
  167. evt_send(&evt);
  168. sec_proc_start(p_gap_evt->conn_handle, peer_id, false, false, false);
  169. }
  170. else
  171. {
  172. sec_start_send(p_gap_evt->conn_handle, PM_LINK_SECURED_PROCEDURE_ENCRYPTION);
  173. sec_proc_start(p_gap_evt->conn_handle, peer_id, err_code == NRF_SUCCESS, false, false);
  174. }
  175. return;
  176. }
  177. /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_REQUEST event from the SoftDevice.
  178. *
  179. * @param[in] p_gap_evt The event from the SoftDevice.
  180. */
  181. static void sec_request_process(ble_gap_evt_t * p_gap_evt)
  182. {
  183. smd_evt_t evt =
  184. {
  185. .evt_id = SMD_EVT_SLAVE_SECURITY_REQ,
  186. .conn_handle = p_gap_evt->conn_handle,
  187. .params =
  188. {
  189. .slave_security_req =
  190. {
  191. .bond = p_gap_evt->params.sec_request.bond,
  192. .mitm = p_gap_evt->params.sec_request.mitm,
  193. }
  194. }
  195. };
  196. evt_send(&evt);
  197. return;
  198. }
  199. /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when
  200. * the auth_status is success.
  201. *
  202. * @param[in] p_gap_evt The event from the SoftDevice.
  203. */
  204. static void auth_status_success_process(ble_gap_evt_t * p_gap_evt)
  205. {
  206. ret_code_t err_code = NRF_SUCCESS;
  207. uint8_t role = ble_conn_state_role(p_gap_evt->conn_handle);
  208. pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle);
  209. ble_gap_sec_kdist_t kdist_own = p_gap_evt->params.auth_status.kdist_own;
  210. ble_gap_sec_kdist_t kdist_peer = p_gap_evt->params.auth_status.kdist_peer;
  211. ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_smd.flag_id_sec_proc, false);
  212. if (role == BLE_GAP_ROLE_INVALID)
  213. {
  214. /* Unlikely, but maybe possible? */
  215. return;
  216. }
  217. if (p_gap_evt->params.auth_status.bonded)
  218. {
  219. err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_BONDING);
  220. if (err_code != NRF_SUCCESS)
  221. {
  222. /* Unexpected */
  223. smd_evt_t error_evt;
  224. error_evt.evt_id = SMD_EVT_ERROR_BONDING_INFO;
  225. error_evt.conn_handle = p_gap_evt->conn_handle;
  226. error_evt.params.error_bonding_info.peer_id = peer_id;
  227. error_evt.params.error_bonding_info.error = err_code;
  228. evt_send(&error_evt);
  229. }
  230. }
  231. else if (ble_conn_state_user_flag_get(p_gap_evt->conn_handle, m_smd.flag_id_sec_proc_new_peer))
  232. {
  233. ret_code_t err_code_free = im_peer_free(peer_id);
  234. UNUSED_VARIABLE(err_code_free); // Errors can be safely ignored.
  235. }
  236. smd_evt_t pairing_success_evt;
  237. pairing_success_evt.evt_id = SMD_EVT_PAIRING_SUCCESS;
  238. pairing_success_evt.conn_handle = p_gap_evt->conn_handle;
  239. pairing_success_evt.params.pairing_success.bonded = p_gap_evt->params.auth_status.bonded;
  240. pairing_success_evt.params.pairing_success.mitm = p_gap_evt->params.auth_status.sm1_levels.lv3;
  241. pairing_success_evt.params.pairing_success.kdist_own = kdist_own;
  242. pairing_success_evt.params.pairing_success.kdist_peer = kdist_peer;
  243. evt_send(&pairing_success_evt);
  244. return;
  245. }
  246. /**@brief Function for cleaning up after a failed pairing procedure.
  247. *
  248. * @param[in] conn_handle The handle of the connection the pairing procedure happens on.
  249. * @param[in] peer_id The peer id used in the pairing procedure.
  250. * @param[in] error The error the procedure failed with.
  251. * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
  252. */
  253. static void pairing_failure(uint16_t conn_handle,
  254. pm_peer_id_t peer_id,
  255. pm_sec_error_code_t error,
  256. uint8_t error_src)
  257. {
  258. ret_code_t err_code = NRF_SUCCESS;
  259. smd_evt_t evt =
  260. {
  261. .evt_id = SMD_EVT_PAIRING_FAIL,
  262. .conn_handle = conn_handle,
  263. .params =
  264. {
  265. .pairing_failed =
  266. {
  267. .error = error,
  268. .error_src = error_src,
  269. }
  270. }
  271. };
  272. if(ble_conn_state_user_flag_get(conn_handle, m_smd.flag_id_sec_proc_new_peer))
  273. {
  274. // The peer_id was created during the procedure, and should be freed, because no data is
  275. // stored under it.
  276. err_code = im_peer_free(peer_id); // Attempt to free allocated peer.
  277. UNUSED_VARIABLE(err_code);
  278. }
  279. else
  280. {
  281. err_code = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING);
  282. if ((err_code != NRF_SUCCESS) && (err_code == NRF_ERROR_NOT_FOUND /* No buffer was allocated */))
  283. {
  284. smd_evt_t error_evt;
  285. error_evt.evt_id = SMD_EVT_ERROR_UNEXPECTED;
  286. error_evt.conn_handle = conn_handle;
  287. error_evt.params.error_unexpected.error = err_code;
  288. evt_send(&error_evt);
  289. }
  290. }
  291. ble_conn_state_user_flag_set(conn_handle, m_smd.flag_id_sec_proc, false);
  292. evt_send(&evt);
  293. return;
  294. }
  295. /**@brief Function for cleaning up after a failed encryption procedure.
  296. *
  297. * @param[in] conn_handle The handle of the connection the encryption procedure happens on.
  298. * @param[in] error The error the procedure failed with.
  299. * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
  300. */
  301. static void encryption_failure(uint16_t conn_handle,
  302. pm_sec_error_code_t error,
  303. uint8_t error_src)
  304. {
  305. smd_evt_t evt =
  306. {
  307. .evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED,
  308. .conn_handle = conn_handle,
  309. .params =
  310. {
  311. .link_encryption_failed =
  312. {
  313. .error = error,
  314. .error_src = error_src,
  315. }
  316. }
  317. };
  318. ble_conn_state_user_flag_set(conn_handle, m_smd.flag_id_sec_proc, false);
  319. evt_send(&evt);
  320. return;
  321. }
  322. /**@brief Function for possibly cleaning up after a failed pairing or encryption procedure.
  323. *
  324. * @param[in] conn_handle The handle of the connection the pairing procedure happens on.
  325. * @param[in] peer_id The peer id used in the pairing procedure.
  326. * @param[in] error The error the procedure failed with.
  327. * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
  328. */
  329. static void link_secure_failure(uint16_t conn_handle,
  330. pm_sec_error_code_t error,
  331. uint8_t error_src)
  332. {
  333. if (ble_conn_state_user_flag_get(conn_handle, m_smd.flag_id_sec_proc))
  334. {
  335. pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  336. if (peer_id != PM_PEER_ID_INVALID)
  337. {
  338. if (ble_conn_state_user_flag_get(conn_handle, m_smd.flag_id_sec_proc_pairing))
  339. {
  340. pairing_failure(conn_handle, peer_id, error, error_src);
  341. }
  342. else
  343. {
  344. encryption_failure(conn_handle, error, error_src);
  345. }
  346. }
  347. }
  348. }
  349. /**@brief Function for processing the @ref BLE_GAP_EVT_DISCONNECT event from the SoftDevice.
  350. *
  351. * @param[in] p_gap_evt The event from the SoftDevice.
  352. */
  353. static void disconnect_process(ble_gap_evt_t * p_gap_evt)
  354. {
  355. pm_sec_error_code_t error = (p_gap_evt->params.disconnected.reason
  356. == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE)
  357. ? PM_CONN_SEC_ERROR_MIC_FAILURE : PM_CONN_SEC_ERROR_DISCONNECT;
  358. link_secure_failure(p_gap_evt->conn_handle, error, BLE_GAP_SEC_STATUS_SOURCE_LOCAL);
  359. }
  360. /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when
  361. * the auth_status is failure.
  362. *
  363. * @param[in] p_gap_evt The event from the SoftDevice.
  364. */
  365. static void auth_status_failure_process(ble_gap_evt_t * p_gap_evt)
  366. {
  367. link_secure_failure(p_gap_evt->conn_handle,
  368. p_gap_evt->params.auth_status.auth_status,
  369. p_gap_evt->params.auth_status.error_src);
  370. }
  371. /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice.
  372. *
  373. * @param[in] p_gap_evt The event from the SoftDevice.
  374. */
  375. static void auth_status_process(ble_gap_evt_t * p_gap_evt)
  376. {
  377. switch (p_gap_evt->params.auth_status.auth_status)
  378. {
  379. case BLE_GAP_SEC_STATUS_SUCCESS:
  380. auth_status_success_process(p_gap_evt);
  381. break;
  382. default:
  383. auth_status_failure_process(p_gap_evt);
  384. break;
  385. }
  386. }
  387. /**@brief Function for processing the @ref BLE_GAP_EVT_CONN_SEC_UPDATE event from the SoftDevice.
  388. *
  389. * @param[in] p_gap_evt The event from the SoftDevice.
  390. */
  391. static void conn_sec_update_process(ble_gap_evt_t * p_gap_evt)
  392. {
  393. if (ble_conn_state_encrypted(p_gap_evt->conn_handle))
  394. {
  395. if (!ble_conn_state_user_flag_get(p_gap_evt->conn_handle, m_smd.flag_id_sec_proc_pairing))
  396. {
  397. ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_smd.flag_id_sec_proc, false);
  398. }
  399. smd_evt_t evt;
  400. evt.conn_handle = p_gap_evt->conn_handle;
  401. evt.evt_id = SMD_EVT_LINK_ENCRYPTION_UPDATE;
  402. evt.params.link_encryption_update.mitm_protected
  403. = ble_conn_state_mitm_protected(p_gap_evt->conn_handle);
  404. evt_send(&evt);
  405. }
  406. else
  407. {
  408. encryption_failure(p_gap_evt->conn_handle,
  409. PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING,
  410. BLE_GAP_SEC_STATUS_SOURCE_REMOTE);
  411. }
  412. }
  413. /**@brief Funtion for initializing a BLE Connection State user flag.
  414. *
  415. * @param[out] flag_id The flag to initialize.
  416. */
  417. static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id)
  418. {
  419. if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
  420. {
  421. *p_flag_id = ble_conn_state_user_flag_acquire();
  422. }
  423. }
  424. ret_code_t smd_register(smd_evt_handler_t evt_handler)
  425. {
  426. ret_code_t err_code = NRF_SUCCESS;
  427. if (evt_handler == NULL)
  428. {
  429. err_code = NRF_ERROR_NULL;
  430. }
  431. else
  432. {
  433. if (!MODULE_INITIALIZED)
  434. {
  435. flag_id_init(&m_smd.flag_id_sec_proc);
  436. flag_id_init(&m_smd.flag_id_sec_proc_pairing);
  437. flag_id_init(&m_smd.flag_id_sec_proc_new_peer);
  438. if (m_smd.flag_id_sec_proc_new_peer == BLE_CONN_STATE_USER_FLAG_INVALID)
  439. {
  440. err_code = NRF_ERROR_INTERNAL;
  441. }
  442. else
  443. {
  444. err_code = pdb_register(pdb_evt_handler);
  445. }
  446. }
  447. if ((err_code == NRF_SUCCESS))
  448. {
  449. if ((m_smd.n_registrants < MAX_REGISTRANTS))
  450. {
  451. m_smd.evt_handlers[m_smd.n_registrants++] = evt_handler;
  452. }
  453. else
  454. {
  455. err_code = NRF_ERROR_NO_MEM;
  456. }
  457. }
  458. }
  459. return err_code;
  460. }
  461. ret_code_t smd_params_reply(uint16_t conn_handle,
  462. ble_gap_sec_params_t * p_sec_params,
  463. ble_gap_lesc_p256_pk_t * p_public_key)
  464. {
  465. VERIFY_MODULE_INITIALIZED();
  466. uint8_t role = ble_conn_state_role(conn_handle);
  467. pm_peer_id_t peer_id = PM_PEER_ID_INVALID;
  468. ret_code_t err_code = NRF_SUCCESS;
  469. uint8_t sec_status = BLE_GAP_SEC_STATUS_SUCCESS;
  470. ble_gap_sec_keyset_t sec_keyset;
  471. bool new_peer_created = false;
  472. memset(&sec_keyset, 0, sizeof(ble_gap_sec_keyset_t));
  473. if (role == BLE_GAP_ROLE_INVALID)
  474. {
  475. return BLE_ERROR_INVALID_CONN_HANDLE;
  476. }
  477. if (p_sec_params == NULL)
  478. {
  479. // NULL params means reject pairing.
  480. sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP;
  481. }
  482. else if (p_sec_params->bond)
  483. {
  484. // Bonding is to be performed, prepare to receive bonding data.
  485. pm_peer_data_t peer_data;
  486. peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  487. if (peer_id == PM_PEER_ID_INVALID)
  488. {
  489. // Peer is unknown to us, allocate a new peer ID for it.
  490. peer_id = pdb_peer_allocate();
  491. if (peer_id != PM_PEER_ID_INVALID)
  492. {
  493. new_peer_created = true;
  494. }
  495. else
  496. {
  497. err_code = NRF_ERROR_INTERNAL;
  498. }
  499. }
  500. if (err_code == NRF_SUCCESS)
  501. {
  502. // Peer ID is ready, acquire a memory buffer to receive bonding data into.
  503. err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &peer_data);
  504. if (err_code == NRF_SUCCESS)
  505. {
  506. memset(peer_data.p_bonding_data, 0, sizeof(pm_peer_data_bonding_t));
  507. peer_data.p_bonding_data->own_role = role;
  508. sec_keyset.keys_own.p_enc_key = &peer_data.p_bonding_data->own_ltk;
  509. sec_keyset.keys_own.p_pk = p_public_key;
  510. sec_keyset.keys_peer.p_enc_key = &peer_data.p_bonding_data->peer_ltk;
  511. sec_keyset.keys_peer.p_id_key = &peer_data.p_bonding_data->peer_id;
  512. sec_keyset.keys_peer.p_pk = &m_smd.peer_pk;
  513. ret_code_t err_code_addr = im_ble_addr_get(conn_handle, &peer_data.p_bonding_data->peer_id.id_addr_info); // Retrieve the address the peer used during connection establishment. This address will be overwritten if ID is shared. Should not fail.
  514. UNUSED_VARIABLE(err_code_addr);
  515. // Buffer is OK, reserve room in flash for the data.
  516. err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING);
  517. }
  518. }
  519. }
  520. else
  521. {
  522. // Pairing only, no action needed.
  523. }
  524. if (err_code == NRF_SUCCESS)
  525. {
  526. // Everything OK, reply to SoftDevice. If an error happened, the user is given an
  527. // opportunity to change the parameters and retry the call.
  528. if (role == BLE_GAP_ROLE_CENTRAL)
  529. {
  530. err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, NULL, &sec_keyset);
  531. }
  532. else
  533. {
  534. err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, p_sec_params, &sec_keyset);
  535. if ((p_sec_params != NULL) && (err_code == NRF_SUCCESS))
  536. {
  537. pm_conn_sec_procedure_t procedure = p_sec_params->bond
  538. ? PM_LINK_SECURED_PROCEDURE_BONDING
  539. : PM_LINK_SECURED_PROCEDURE_PAIRING;
  540. sec_start_send(conn_handle, procedure);
  541. }
  542. }
  543. }
  544. sec_proc_start(conn_handle,
  545. peer_id,
  546. (err_code == NRF_SUCCESS) && (sec_status != BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP),
  547. true,
  548. new_peer_created);
  549. return err_code;
  550. }
  551. static ret_code_t link_secure_central_existing_peer(uint16_t conn_handle,
  552. ble_gap_sec_params_t * p_sec_params,
  553. bool force_repairing,
  554. pm_peer_id_t peer_id,
  555. pm_conn_sec_procedure_t * procedure)
  556. {
  557. pm_peer_data_flash_t peer_data;
  558. pm_peer_data_t dummy_peer_data;
  559. ret_code_t err_code;
  560. ble_gap_enc_key_t const * p_existing_key = NULL;
  561. bool lesc = false;
  562. err_code = pdb_read_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data, NULL);
  563. if (err_code == NRF_SUCCESS)
  564. {
  565. // Use peer's key since they are peripheral.
  566. p_existing_key = &(peer_data.p_bonding_data->peer_ltk);
  567. lesc = peer_data.p_bonding_data->own_ltk.enc_info.lesc;
  568. if (lesc) // LESC was used during bonding.
  569. {
  570. // For LESC, always use own key.
  571. p_existing_key = &(peer_data.p_bonding_data->own_ltk);
  572. }
  573. }
  574. if (!force_repairing
  575. && (err_code == NRF_SUCCESS)
  576. && (p_existing_key != NULL)
  577. && (lesc || im_master_id_is_valid(&(p_existing_key->master_id)))) /* There is a valid LTK stored. */
  578. //&& (p_existing_key->enc_info.auth >= p_sec_params->mitm) /* The requested MITM security is at or below the existing level. */
  579. //&& (!p_sec_params->mitm || (lesc >= p_sec_params->lesc))) /* The requested LESC security is at or below the existing level. We only care about LESC if MITM is required. */
  580. {
  581. err_code = sd_ble_gap_encrypt(conn_handle, &(p_existing_key->master_id), &(p_existing_key->enc_info));
  582. *procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
  583. }
  584. else if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND))
  585. {
  586. /* Re-pairing is needed, because there is no LTK available or the existing key is not
  587. secure enough */
  588. err_code = NRF_SUCCESS;
  589. if (p_sec_params->bond)
  590. {
  591. err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &dummy_peer_data);
  592. if (err_code == NRF_SUCCESS)
  593. {
  594. err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING);
  595. }
  596. }
  597. if (err_code == NRF_SUCCESS)
  598. {
  599. err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
  600. }
  601. if (err_code != NRF_SUCCESS)
  602. {
  603. ret_code_t err_code_release = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING);
  604. if ((err_code_release != NRF_SUCCESS) && (err_code_release != NRF_ERROR_NOT_FOUND))
  605. {
  606. err_code = NRF_ERROR_INTERNAL;
  607. }
  608. }
  609. }
  610. sec_proc_start(conn_handle,
  611. peer_id,
  612. err_code == NRF_SUCCESS,
  613. *procedure != PM_LINK_SECURED_PROCEDURE_ENCRYPTION,
  614. false);
  615. return err_code;
  616. }
  617. static ret_code_t link_secure_central_new_peer(uint16_t conn_handle,
  618. ble_gap_sec_params_t * p_sec_params)
  619. {
  620. pm_peer_id_t peer_id = pdb_peer_allocate();
  621. pm_peer_data_t dummy_peer_data;
  622. ret_code_t err_code;
  623. if (peer_id != PM_PEER_ID_INVALID)
  624. {
  625. err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &dummy_peer_data);
  626. if (err_code == NRF_SUCCESS)
  627. {
  628. err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING);
  629. }
  630. if (err_code == NRF_SUCCESS)
  631. {
  632. err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
  633. }
  634. if (err_code != NRF_SUCCESS)
  635. {
  636. ret_code_t err_code_free = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING);
  637. if ((err_code_free != NRF_SUCCESS) && (err_code_free != NRF_ERROR_NOT_FOUND))
  638. {
  639. err_code = NRF_ERROR_INTERNAL;
  640. }
  641. }
  642. }
  643. else
  644. {
  645. err_code = NRF_ERROR_INTERNAL;
  646. }
  647. sec_proc_start(conn_handle,
  648. peer_id,
  649. err_code == NRF_SUCCESS,
  650. true,
  651. peer_id != PM_PEER_ID_INVALID);
  652. return err_code;
  653. }
  654. static ret_code_t link_secure_central(uint16_t conn_handle,
  655. ble_gap_sec_params_t * p_sec_params,
  656. bool force_repairing)
  657. {
  658. ret_code_t err_code;
  659. pm_peer_id_t peer_id;
  660. if (p_sec_params == NULL)
  661. {
  662. return sd_ble_gap_authenticate(conn_handle, NULL);
  663. }
  664. pm_conn_sec_procedure_t procedure = p_sec_params->bond ? PM_LINK_SECURED_PROCEDURE_BONDING
  665. : PM_LINK_SECURED_PROCEDURE_PAIRING;
  666. peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  667. if (peer_id != PM_PEER_ID_INVALID)
  668. {
  669. // There is already data in flash for this peer.
  670. err_code = link_secure_central_existing_peer(conn_handle,
  671. p_sec_params,
  672. force_repairing,
  673. peer_id,
  674. &procedure);
  675. }
  676. else if (p_sec_params->bond)
  677. {
  678. // New peer is required.
  679. err_code = link_secure_central_new_peer(conn_handle, p_sec_params);
  680. }
  681. else
  682. {
  683. // No bonding, only pairing.
  684. err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
  685. sec_proc_start(conn_handle, peer_id, err_code == NRF_SUCCESS, true, false);
  686. }
  687. if (err_code == NRF_SUCCESS)
  688. {
  689. sec_start_send(conn_handle, procedure);
  690. }
  691. return err_code;
  692. }
  693. static ret_code_t link_secure_peripheral(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params)
  694. {
  695. VERIFY_PARAM_NOT_NULL(p_sec_params);
  696. ret_code_t err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
  697. return err_code;
  698. }
  699. ret_code_t smd_link_secure(uint16_t conn_handle,
  700. ble_gap_sec_params_t * p_sec_params,
  701. bool force_repairing)
  702. {
  703. VERIFY_MODULE_INITIALIZED();
  704. uint8_t role = ble_conn_state_role(conn_handle);
  705. switch (role)
  706. {
  707. case BLE_GAP_ROLE_CENTRAL:
  708. return link_secure_central(conn_handle, p_sec_params, force_repairing);
  709. case BLE_GAP_ROLE_PERIPH:
  710. return link_secure_peripheral(conn_handle, p_sec_params);
  711. default:
  712. return BLE_ERROR_INVALID_CONN_HANDLE;
  713. }
  714. }
  715. void smd_ble_evt_handler(ble_evt_t * p_ble_evt)
  716. {
  717. switch (p_ble_evt->header.evt_id)
  718. {
  719. case BLE_GAP_EVT_DISCONNECTED:
  720. disconnect_process(&(p_ble_evt->evt.gap_evt));
  721. break;
  722. case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
  723. sec_params_request_process(&(p_ble_evt->evt.gap_evt));
  724. break;
  725. case BLE_GAP_EVT_SEC_INFO_REQUEST:
  726. sec_info_request_process(&(p_ble_evt->evt.gap_evt));
  727. break;
  728. case BLE_GAP_EVT_SEC_REQUEST:
  729. sec_request_process(&(p_ble_evt->evt.gap_evt));
  730. break;
  731. case BLE_GAP_EVT_AUTH_STATUS:
  732. auth_status_process(&(p_ble_evt->evt.gap_evt));
  733. break;
  734. case BLE_GAP_EVT_CONN_SEC_UPDATE:
  735. conn_sec_update_process(&(p_ble_evt->evt.gap_evt));
  736. break;
  737. };
  738. }