security_dispatcher.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. /**
  2. * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "sdk_common.h"
  41. #if NRF_MODULE_ENABLED(PEER_MANAGER)
  42. #include "security_dispatcher.h"
  43. #include <string.h>
  44. #include "ble.h"
  45. #include "ble_gap.h"
  46. #include "ble_err.h"
  47. #include "ble_conn_state.h"
  48. #include "peer_manager_types.h"
  49. #include "peer_data_storage.h"
  50. #include "peer_database.h"
  51. #include "id_manager.h"
  52. #if PM_RA_PROTECTION_ENABLED
  53. #include "auth_status_tracker.h"
  54. #endif // PM_RA_PROTECTION_ENABLED
  55. #define NRF_LOG_MODULE_NAME peer_manager_smd
  56. #if PM_LOG_ENABLED
  57. #define NRF_LOG_LEVEL PM_LOG_LEVEL
  58. #define NRF_LOG_INFO_COLOR PM_LOG_INFO_COLOR
  59. #define NRF_LOG_DEBUG_COLOR PM_LOG_DEBUG_COLOR
  60. #else
  61. #define NRF_LOG_LEVEL 0
  62. #endif // PM_LOG_ENABLED
  63. #include "nrf_log.h"
  64. #include "nrf_log_ctrl.h"
  65. NRF_LOG_MODULE_REGISTER();
  66. #include "nrf_strerror.h"
  67. #ifndef PM_CENTRAL_ENABLED
  68. #define PM_CENTRAL_ENABLED 1
  69. #endif
  70. // The number of registered event handlers.
  71. #define SMD_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
  72. STATIC_ASSERT((NRF_SDH_BLE_CENTRAL_LINK_COUNT == 0) || PM_CENTRAL_ENABLED,
  73. "Peer Manager Central operation must be enabled when using central links.");
  74. // Security Dispacher event handlers in Security Manager and GATT Cache Manager.
  75. extern void sm_smd_evt_handler(pm_evt_t * p_event);
  76. // Security Dispatcher events' handlers.
  77. // The number of elements in this array is SMD_EVENT_HANDLERS_CNT.
  78. static pm_evt_handler_internal_t const m_evt_handlers[] =
  79. {
  80. sm_smd_evt_handler
  81. };
  82. static bool m_module_initialized;
  83. static ble_conn_state_user_flag_id_t m_flag_sec_proc = BLE_CONN_STATE_USER_FLAG_INVALID;
  84. static ble_conn_state_user_flag_id_t m_flag_sec_proc_pairing = BLE_CONN_STATE_USER_FLAG_INVALID;
  85. static ble_conn_state_user_flag_id_t m_flag_sec_proc_bonding = BLE_CONN_STATE_USER_FLAG_INVALID;
  86. static ble_conn_state_user_flag_id_t m_flag_allow_repairing = BLE_CONN_STATE_USER_FLAG_INVALID;
  87. static ble_gap_lesc_p256_pk_t m_peer_pk;
  88. static __INLINE bool sec_procedure(uint16_t conn_handle)
  89. {
  90. return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc);
  91. }
  92. static __INLINE bool pairing(uint16_t conn_handle)
  93. {
  94. return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_pairing);
  95. }
  96. static __INLINE bool bonding(uint16_t conn_handle)
  97. {
  98. return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_bonding);
  99. }
  100. static __INLINE bool allow_repairing(uint16_t conn_handle)
  101. {
  102. return ble_conn_state_user_flag_get(conn_handle, m_flag_allow_repairing);
  103. }
  104. /**@brief Function for sending an SMD event to all event handlers.
  105. *
  106. * @param[in] p_event The event to pass to all event handlers.
  107. */
  108. static void evt_send(pm_evt_t * p_event)
  109. {
  110. p_event->peer_id = im_peer_id_get_by_conn_handle(p_event->conn_handle);
  111. for (uint32_t i = 0; i < SMD_EVENT_HANDLERS_CNT; i++)
  112. {
  113. m_evt_handlers[i](p_event);
  114. }
  115. }
  116. /**@brief Function for sending a PM_EVT_CONN_SEC_START event.
  117. *
  118. * @param[in] conn_handle The connection handle the event pertains to.
  119. * @param[in] procedure The procedure that has started on the connection.
  120. */
  121. static void sec_start_send(uint16_t conn_handle,
  122. pm_conn_sec_procedure_t procedure)
  123. {
  124. pm_evt_t evt =
  125. {
  126. .evt_id = PM_EVT_CONN_SEC_START,
  127. .conn_handle = conn_handle,
  128. .params = {.conn_sec_start = {.procedure = procedure}}
  129. };
  130. evt_send(&evt);
  131. }
  132. /**@brief Function for sending a PM_EVT_ERROR_UNEXPECTED event.
  133. *
  134. * @param[in] conn_handle The connection handle the event pertains to.
  135. * @param[in] err_code The unexpected error that occurred.
  136. */
  137. static void send_unexpected_error(uint16_t conn_handle, ret_code_t err_code)
  138. {
  139. pm_evt_t error_evt =
  140. {
  141. .evt_id = PM_EVT_ERROR_UNEXPECTED,
  142. .conn_handle = conn_handle,
  143. .params =
  144. {
  145. .error_unexpected =
  146. {
  147. .error = err_code,
  148. }
  149. }
  150. };
  151. evt_send(&error_evt);
  152. }
  153. /**@brief Function for sending a PM_EVT_STORAGE_FULL event.
  154. *
  155. * @param[in] conn_handle The connection handle the event pertains to.
  156. */
  157. static void send_storage_full_evt(uint16_t conn_handle)
  158. {
  159. pm_evt_t evt =
  160. {
  161. .evt_id = PM_EVT_STORAGE_FULL,
  162. .conn_handle = conn_handle
  163. };
  164. evt_send(&evt);
  165. }
  166. /**@brief Function for cleaning up after a failed security procedure.
  167. *
  168. * @param[in] conn_handle The handle of the connection the security procedure happens on.
  169. * @param[in] procedure The procedure that failed.
  170. * @param[in] error The error the procedure failed with.
  171. * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
  172. */
  173. static void conn_sec_failure(uint16_t conn_handle,
  174. pm_conn_sec_procedure_t procedure,
  175. pm_sec_error_code_t error,
  176. uint8_t error_src)
  177. {
  178. pm_evt_t evt =
  179. {
  180. .evt_id = PM_EVT_CONN_SEC_FAILED,
  181. .conn_handle = conn_handle,
  182. .params =
  183. {
  184. .conn_sec_failed =
  185. {
  186. .procedure = procedure,
  187. .error = error,
  188. .error_src = error_src,
  189. }
  190. }
  191. };
  192. ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false);
  193. evt_send(&evt);
  194. return;
  195. }
  196. /**@brief Function for cleaning up after a failed pairing procedure.
  197. *
  198. * @param[in] conn_handle The handle of the connection the pairing procedure happens on.
  199. * @param[in] error The error the procedure failed with.
  200. * @param[in] error_src The source of the error (local or remote). See @ref
  201. * BLE_GAP_SEC_STATUS_SOURCES.
  202. */
  203. static void pairing_failure(uint16_t conn_handle,
  204. pm_sec_error_code_t error,
  205. uint8_t error_src)
  206. {
  207. ret_code_t err_code = NRF_SUCCESS;
  208. pm_conn_sec_procedure_t procedure = bonding(conn_handle) ? PM_CONN_SEC_PROCEDURE_BONDING
  209. : PM_CONN_SEC_PROCEDURE_PAIRING;
  210. err_code = pdb_write_buf_release(PDB_TEMP_PEER_ID(conn_handle), PM_PEER_DATA_ID_BONDING);
  211. if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_NOT_FOUND /* No buffer was allocated */))
  212. {
  213. NRF_LOG_ERROR("Could not clean up after failed bonding procedure. "\
  214. "pdb_write_buf_release() returned %s. conn_handle: %d.",
  215. nrf_strerror_get(err_code),
  216. conn_handle);
  217. send_unexpected_error(conn_handle, err_code);
  218. }
  219. conn_sec_failure(conn_handle, procedure, error, error_src);
  220. return;
  221. }
  222. /**@brief Function for cleaning up after a failed encryption procedure.
  223. *
  224. * @param[in] conn_handle The handle of the connection the encryption procedure happens on.
  225. * @param[in] error The error the procedure failed with.
  226. * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
  227. */
  228. static __INLINE void encryption_failure(uint16_t conn_handle,
  229. pm_sec_error_code_t error,
  230. uint8_t error_src)
  231. {
  232. conn_sec_failure(conn_handle, PM_CONN_SEC_PROCEDURE_ENCRYPTION, error, error_src);
  233. return;
  234. }
  235. /**@brief Function for possibly cleaning up after a failed pairing or encryption procedure.
  236. *
  237. * @param[in] conn_handle The handle of the connection the pairing procedure happens on.
  238. * @param[in] error The error the procedure failed with.
  239. * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
  240. */
  241. static void link_secure_failure(uint16_t conn_handle,
  242. pm_sec_error_code_t error,
  243. uint8_t error_src)
  244. {
  245. if (sec_procedure(conn_handle))
  246. {
  247. if (pairing(conn_handle))
  248. {
  249. pairing_failure(conn_handle, error, error_src);
  250. }
  251. else
  252. {
  253. encryption_failure(conn_handle, error, error_src);
  254. }
  255. }
  256. }
  257. /**@brief Function for administrative actions to be taken when a security process has started.
  258. *
  259. * @param[in] conn_handle The connection the security process was attempted on.
  260. * @param[in] success Whether the procedure was started successfully.
  261. * @param[in] procedure The procedure that was started.
  262. */
  263. static void sec_proc_start(uint16_t conn_handle,
  264. bool success,
  265. pm_conn_sec_procedure_t procedure)
  266. {
  267. ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, success);
  268. if (success)
  269. {
  270. ble_conn_state_user_flag_set(conn_handle,
  271. m_flag_sec_proc_pairing,
  272. (procedure != PM_CONN_SEC_PROCEDURE_ENCRYPTION));
  273. ble_conn_state_user_flag_set(conn_handle,
  274. m_flag_sec_proc_bonding,
  275. (procedure == PM_CONN_SEC_PROCEDURE_BONDING));
  276. sec_start_send(conn_handle, procedure);
  277. }
  278. }
  279. #ifdef BLE_GAP_ROLE_PERIPH
  280. /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_INFO_REQUEST event from the SoftDevice.
  281. *
  282. * @param[in] p_gap_evt The event from the SoftDevice.
  283. */
  284. static void sec_info_request_process(ble_gap_evt_t const * p_gap_evt)
  285. {
  286. ret_code_t err_code;
  287. ble_gap_enc_info_t const * p_enc_info = NULL;
  288. pm_peer_data_flash_t peer_data;
  289. pm_peer_id_t peer_id = im_peer_id_get_by_master_id(
  290. &p_gap_evt->params.sec_info_request.master_id);
  291. if (peer_id == PM_PEER_ID_INVALID)
  292. {
  293. peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle);
  294. }
  295. else
  296. {
  297. // The peer might have been unrecognized until now (since connecting). E.g. if using a
  298. // random non-resolvable advertising address. Report the discovered peer ID just in case.
  299. im_new_peer_id(p_gap_evt->conn_handle, peer_id);
  300. }
  301. sec_proc_start(p_gap_evt->conn_handle, true, PM_CONN_SEC_PROCEDURE_ENCRYPTION);
  302. if (peer_id != PM_PEER_ID_INVALID)
  303. {
  304. err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data);
  305. if (err_code == NRF_SUCCESS)
  306. {
  307. // There is stored bonding data for this peer.
  308. ble_gap_enc_key_t const * p_existing_key = &peer_data.p_bonding_data->own_ltk;
  309. if (p_gap_evt->params.sec_info_request.enc_info
  310. && (p_existing_key->enc_info.lesc
  311. || im_master_ids_compare(&p_existing_key->master_id,
  312. &p_gap_evt->params.sec_info_request.master_id)))
  313. {
  314. p_enc_info = &p_existing_key->enc_info;
  315. }
  316. }
  317. }
  318. err_code = sd_ble_gap_sec_info_reply(p_gap_evt->conn_handle, p_enc_info, NULL, NULL);
  319. if (err_code == NRF_ERROR_INVALID_STATE)
  320. {
  321. // Do nothing. If disconnecting, it will be caught later by the handling of the DISCONNECTED
  322. // event. If there is no SEC_INFO_REQ pending, there is either a logic error, or the user
  323. // is also calling sd_ble_gap_sec_info_reply(), but there is no way for the present code to
  324. // detect which one is the case.
  325. NRF_LOG_WARNING("sd_ble_gap_sec_info_reply() returned NRF_EROR_INVALID_STATE, which is an"\
  326. "error unless the link is disconnecting.");
  327. }
  328. else if (err_code != NRF_SUCCESS)
  329. {
  330. NRF_LOG_ERROR("Could not complete encryption procedure. sd_ble_gap_sec_info_reply() "\
  331. "returned %s. conn_handle: %d, peer_id: %d.",
  332. nrf_strerror_get(err_code),
  333. p_gap_evt->conn_handle,
  334. peer_id);
  335. send_unexpected_error(p_gap_evt->conn_handle, err_code);
  336. }
  337. else if (p_gap_evt->params.sec_info_request.enc_info && (p_enc_info == NULL))
  338. {
  339. encryption_failure(p_gap_evt->conn_handle,
  340. PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING,
  341. BLE_GAP_SEC_STATUS_SOURCE_LOCAL);
  342. }
  343. return;
  344. }
  345. #endif // BLE_GAP_ROLE_PERIPH
  346. /**@brief Function for sending a CONFIG_REQ event.
  347. *
  348. * @param[in] conn_handle The connection the sec parameters are needed for.
  349. */
  350. static void send_config_req(uint16_t conn_handle)
  351. {
  352. pm_evt_t evt;
  353. memset(&evt, 0, sizeof(evt));
  354. evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ;
  355. evt.conn_handle = conn_handle;
  356. evt_send(&evt);
  357. }
  358. void smd_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
  359. {
  360. NRF_PM_DEBUG_CHECK(m_module_initialized);
  361. NRF_PM_DEBUG_CHECK(p_conn_sec_config != NULL);
  362. ble_conn_state_user_flag_set(conn_handle,
  363. m_flag_allow_repairing,
  364. p_conn_sec_config->allow_repairing);
  365. }
  366. /**@brief Function for processing the @ref BLE_GAP_EVT_DISCONNECT event from the SoftDevice.
  367. *
  368. * @param[in] p_gap_evt The event from the SoftDevice.
  369. */
  370. static void disconnect_process(ble_gap_evt_t const * p_gap_evt)
  371. {
  372. pm_sec_error_code_t error = (p_gap_evt->params.disconnected.reason
  373. == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE)
  374. ? PM_CONN_SEC_ERROR_MIC_FAILURE : PM_CONN_SEC_ERROR_DISCONNECT;
  375. link_secure_failure(p_gap_evt->conn_handle, error, BLE_GAP_SEC_STATUS_SOURCE_LOCAL);
  376. }
  377. /**@brief Function for sending a PARAMS_REQ event.
  378. *
  379. * @param[in] conn_handle The connection the security parameters are needed for.
  380. * @param[in] p_peer_params The security parameters from the peer. Can be NULL if the peer's parameters
  381. * are not yet available.
  382. */
  383. static void send_params_req(uint16_t conn_handle, ble_gap_sec_params_t const * p_peer_params)
  384. {
  385. pm_evt_t evt =
  386. {
  387. .evt_id = PM_EVT_CONN_SEC_PARAMS_REQ,
  388. .conn_handle = conn_handle,
  389. .params =
  390. {
  391. .conn_sec_params_req =
  392. {
  393. .p_peer_params = p_peer_params
  394. },
  395. },
  396. };
  397. evt_send(&evt);
  398. }
  399. /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST event from the SoftDevice.
  400. *
  401. * @param[in] p_gap_evt The event from the SoftDevice.
  402. */
  403. static void sec_params_request_process(ble_gap_evt_t const * p_gap_evt)
  404. {
  405. #ifdef BLE_GAP_ROLE_PERIPH
  406. if (ble_conn_state_role(p_gap_evt->conn_handle) == BLE_GAP_ROLE_PERIPH)
  407. {
  408. sec_proc_start(p_gap_evt->conn_handle,
  409. true,
  410. p_gap_evt->params.sec_params_request.peer_params.bond
  411. ? PM_CONN_SEC_PROCEDURE_BONDING
  412. : PM_CONN_SEC_PROCEDURE_PAIRING);
  413. }
  414. #endif // BLE_GAP_ROLE_PERIPH
  415. send_params_req(p_gap_evt->conn_handle, &p_gap_evt->params.sec_params_request.peer_params);
  416. return;
  417. }
  418. /**@brief Function for sending a Peer Manager event indicating that pairing has succeeded.
  419. *
  420. * @param[in] p_gap_evt The AUTH_STATUS event from the SoftDevice that triggered this.
  421. * @param[in] data_stored Whether bonding data was stored.
  422. */
  423. static void pairing_success_evt_send(ble_gap_evt_t const * p_gap_evt, bool data_stored)
  424. {
  425. pm_evt_t pairing_success_evt;
  426. pairing_success_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
  427. pairing_success_evt.conn_handle = p_gap_evt->conn_handle;
  428. pairing_success_evt.params.conn_sec_succeeded.procedure = p_gap_evt->params.auth_status.bonded
  429. ? PM_CONN_SEC_PROCEDURE_BONDING
  430. : PM_CONN_SEC_PROCEDURE_PAIRING;
  431. pairing_success_evt.params.conn_sec_succeeded.data_stored = data_stored;
  432. evt_send(&pairing_success_evt);
  433. }
  434. /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when
  435. * the auth_status is success.
  436. *
  437. * @param[in] p_gap_evt The event from the SoftDevice.
  438. */
  439. static void auth_status_success_process(ble_gap_evt_t const * p_gap_evt)
  440. {
  441. ret_code_t err_code;
  442. uint16_t conn_handle = p_gap_evt->conn_handle;
  443. pm_peer_id_t peer_id;
  444. pm_peer_data_t peer_data;
  445. bool new_peer_id = false;
  446. ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false);
  447. if (!p_gap_evt->params.auth_status.bonded)
  448. {
  449. pairing_success_evt_send(p_gap_evt, false);
  450. return;
  451. }
  452. err_code = pdb_write_buf_get(PDB_TEMP_PEER_ID(conn_handle), PM_PEER_DATA_ID_BONDING, 1, &peer_data);
  453. if (err_code != NRF_SUCCESS)
  454. {
  455. NRF_LOG_ERROR("RAM buffer for new bond was unavailable. pdb_write_buf_get() returned %s. conn_handle: %d.",
  456. nrf_strerror_get(err_code),
  457. conn_handle);
  458. send_unexpected_error(conn_handle, err_code);
  459. pairing_success_evt_send(p_gap_evt, false);
  460. return;
  461. }
  462. peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  463. if (peer_id == PM_PEER_ID_INVALID)
  464. {
  465. peer_id = im_find_duplicate_bonding_data(peer_data.p_bonding_data, PM_PEER_ID_INVALID);
  466. if (peer_id != PM_PEER_ID_INVALID)
  467. {
  468. // The peer has been identified as someone we have already bonded with.
  469. im_new_peer_id(conn_handle, peer_id);
  470. // If the flag is true, the configuration has been requested before.
  471. if (!allow_repairing(conn_handle))
  472. {
  473. send_config_req(conn_handle);
  474. if (!allow_repairing(conn_handle))
  475. {
  476. pairing_success_evt_send(p_gap_evt, false);
  477. return;
  478. }
  479. }
  480. }
  481. }
  482. if (peer_id == PM_PEER_ID_INVALID)
  483. {
  484. peer_id = pds_peer_id_allocate();
  485. if (peer_id == PM_PEER_ID_INVALID)
  486. {
  487. NRF_LOG_ERROR("Could not allocate new peer_id for incoming bond.");
  488. send_unexpected_error(conn_handle, NRF_ERROR_NO_MEM);
  489. pairing_success_evt_send(p_gap_evt, false);
  490. return;
  491. }
  492. im_new_peer_id(conn_handle, peer_id);
  493. new_peer_id = true;
  494. }
  495. err_code = pdb_write_buf_store(PDB_TEMP_PEER_ID(conn_handle), PM_PEER_DATA_ID_BONDING, peer_id);
  496. if (err_code == NRF_SUCCESS)
  497. {
  498. pairing_success_evt_send(p_gap_evt, true);
  499. }
  500. else if (err_code == NRF_ERROR_STORAGE_FULL)
  501. {
  502. send_storage_full_evt(conn_handle);
  503. pairing_success_evt_send(p_gap_evt, true);
  504. }
  505. else
  506. {
  507. /* Unexpected error */
  508. NRF_LOG_ERROR("Could not store bond. pdb_write_buf_store() returned %s. "\
  509. "conn_handle: %d, peer_id: %d",
  510. nrf_strerror_get(err_code),
  511. conn_handle,
  512. peer_id);
  513. send_unexpected_error(conn_handle, err_code);
  514. pairing_success_evt_send(p_gap_evt, false);
  515. if (new_peer_id)
  516. {
  517. UNUSED_RETURN_VALUE(im_peer_free(peer_id)); // We are already in a bad state.
  518. }
  519. }
  520. return;
  521. }
  522. /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when
  523. * the auth_status is failure.
  524. *
  525. * @param[in] p_gap_evt The event from the SoftDevice.
  526. */
  527. static void auth_status_failure_process(ble_gap_evt_t const * p_gap_evt)
  528. {
  529. link_secure_failure(p_gap_evt->conn_handle,
  530. p_gap_evt->params.auth_status.auth_status,
  531. p_gap_evt->params.auth_status.error_src);
  532. }
  533. /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice.
  534. *
  535. * @param[in] p_gap_evt The event from the SoftDevice.
  536. */
  537. static void auth_status_process(ble_gap_evt_t const * p_gap_evt)
  538. {
  539. switch (p_gap_evt->params.auth_status.auth_status)
  540. {
  541. case BLE_GAP_SEC_STATUS_SUCCESS:
  542. auth_status_success_process(p_gap_evt);
  543. break;
  544. default:
  545. auth_status_failure_process(p_gap_evt);
  546. #if PM_RA_PROTECTION_ENABLED
  547. ast_auth_error_notify(p_gap_evt->conn_handle);
  548. #endif // PM_RA_PROTECTION_ENABLED
  549. break;
  550. }
  551. }
  552. /**@brief Function for processing the @ref BLE_GAP_EVT_CONN_SEC_UPDATE event from the SoftDevice.
  553. *
  554. * @param[in] p_gap_evt The event from the SoftDevice.
  555. */
  556. static void conn_sec_update_process(ble_gap_evt_t const * p_gap_evt)
  557. {
  558. if (!pairing(p_gap_evt->conn_handle))
  559. {
  560. // This is an encryption procedure (not pairing), so this event marks the end of the procedure.
  561. if (!ble_conn_state_encrypted(p_gap_evt->conn_handle))
  562. {
  563. encryption_failure(p_gap_evt->conn_handle,
  564. PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING,
  565. BLE_GAP_SEC_STATUS_SOURCE_REMOTE);
  566. }
  567. else
  568. {
  569. ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_flag_sec_proc, false);
  570. pm_evt_t evt;
  571. evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
  572. evt.conn_handle = p_gap_evt->conn_handle;
  573. evt.params.conn_sec_succeeded.procedure = PM_CONN_SEC_PROCEDURE_ENCRYPTION;
  574. evt.params.conn_sec_succeeded.data_stored = false;
  575. evt_send(&evt);
  576. }
  577. }
  578. }
  579. /**@brief Funtion for initializing a BLE Connection State user flag.
  580. *
  581. * @param[out] flag_id The flag to initialize.
  582. */
  583. static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id)
  584. {
  585. if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
  586. {
  587. *p_flag_id = ble_conn_state_user_flag_acquire();
  588. }
  589. }
  590. ret_code_t smd_init(void)
  591. {
  592. NRF_PM_DEBUG_CHECK(!m_module_initialized);
  593. flag_id_init(&m_flag_sec_proc);
  594. flag_id_init(&m_flag_sec_proc_pairing);
  595. flag_id_init(&m_flag_sec_proc_bonding);
  596. flag_id_init(&m_flag_allow_repairing);
  597. if ((m_flag_sec_proc == BLE_CONN_STATE_USER_FLAG_INVALID) ||
  598. (m_flag_sec_proc_pairing == BLE_CONN_STATE_USER_FLAG_INVALID) ||
  599. (m_flag_sec_proc_bonding == BLE_CONN_STATE_USER_FLAG_INVALID) ||
  600. (m_flag_allow_repairing == BLE_CONN_STATE_USER_FLAG_INVALID))
  601. {
  602. NRF_LOG_ERROR("Could not acquire conn_state user flags. Increase "\
  603. "BLE_CONN_STATE_USER_FLAG_COUNT in the ble_conn_state module.");
  604. return NRF_ERROR_INTERNAL;
  605. }
  606. #if PM_RA_PROTECTION_ENABLED
  607. ret_code_t err_code = ast_init();
  608. if (err_code != NRF_SUCCESS)
  609. {
  610. return err_code;
  611. }
  612. #endif // PM_RA_PROTECTION_ENABLED
  613. m_module_initialized = true;
  614. return NRF_SUCCESS;
  615. }
  616. /**@brief Function for putting retrieving a buffer and putting pointers into a @ref ble_gap_sec_keyset_t.
  617. *
  618. * @param[in] conn_handle The connection the security procedure is happening on.
  619. * @param[in] role Our role in the connection.
  620. * @param[in] p_public_key Pointer to a buffer holding the public key, or NULL.
  621. * @param[out] p_sec_keyset Pointer to the keyset to be filled.
  622. *
  623. * @retval NRF_SUCCESS Success.
  624. * @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later.
  625. * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
  626. * @retval NRF_ERROR_INVALID_STATE The link is disconnected.
  627. * @retval NRF_ERROR_INTERNAL Fatal error.
  628. */
  629. static ret_code_t sec_keyset_fill(uint16_t conn_handle,
  630. uint8_t role,
  631. ble_gap_lesc_p256_pk_t * p_public_key,
  632. ble_gap_sec_keyset_t * p_sec_keyset)
  633. {
  634. ret_code_t err_code;
  635. pm_peer_data_t peer_data;
  636. if (p_sec_keyset == NULL)
  637. {
  638. NRF_LOG_ERROR("Internal error: %s received NULL for p_sec_keyset.", __func__);
  639. return NRF_ERROR_INTERNAL;
  640. }
  641. // Acquire a memory buffer to receive bonding data into.
  642. err_code = pdb_write_buf_get(PDB_TEMP_PEER_ID(conn_handle), PM_PEER_DATA_ID_BONDING, 1, &peer_data);
  643. if (err_code == NRF_ERROR_BUSY)
  644. {
  645. // No action.
  646. }
  647. else if (err_code != NRF_SUCCESS)
  648. {
  649. NRF_LOG_ERROR("Could not retrieve RAM buffer for incoming bond. pdb_write_buf_get() "\
  650. "returned %s. conn_handle: %d",
  651. nrf_strerror_get(err_code),
  652. conn_handle);
  653. err_code = NRF_ERROR_INTERNAL;
  654. }
  655. else /* if (err_code == NRF_SUCCESS) */
  656. {
  657. memset(peer_data.p_bonding_data, 0, sizeof(pm_peer_data_bonding_t));
  658. peer_data.p_bonding_data->own_role = role;
  659. p_sec_keyset->keys_own.p_enc_key = &peer_data.p_bonding_data->own_ltk;
  660. p_sec_keyset->keys_own.p_pk = p_public_key;
  661. p_sec_keyset->keys_peer.p_enc_key = &peer_data.p_bonding_data->peer_ltk;
  662. p_sec_keyset->keys_peer.p_id_key = &peer_data.p_bonding_data->peer_ble_id;
  663. p_sec_keyset->keys_peer.p_pk = &m_peer_pk;
  664. // Retrieve the address the peer used during connection establishment.
  665. // This address will be overwritten if ID is shared. Should not fail.
  666. err_code = im_ble_addr_get(conn_handle, &peer_data.p_bonding_data->peer_ble_id.id_addr_info);
  667. if (err_code != NRF_SUCCESS)
  668. {
  669. NRF_LOG_WARNING("im_ble_addr_get() returned %s. conn_handle: %d. Link was likely disconnected.",
  670. nrf_strerror_get(err_code),
  671. conn_handle);
  672. return NRF_ERROR_INVALID_STATE;
  673. }
  674. }
  675. return err_code;
  676. }
  677. ret_code_t smd_params_reply(uint16_t conn_handle,
  678. ble_gap_sec_params_t * p_sec_params,
  679. ble_gap_lesc_p256_pk_t * p_public_key)
  680. {
  681. NRF_PM_DEBUG_CHECK(m_module_initialized);
  682. uint8_t role = ble_conn_state_role(conn_handle);
  683. ret_code_t err_code = NRF_SUCCESS;
  684. uint8_t sec_status = BLE_GAP_SEC_STATUS_SUCCESS;
  685. ble_gap_sec_keyset_t sec_keyset;
  686. memset(&sec_keyset, 0, sizeof(ble_gap_sec_keyset_t));
  687. #ifdef BLE_GAP_ROLE_PERIPH
  688. if (role == BLE_GAP_ROLE_PERIPH)
  689. {
  690. // Set the default value for allowing repairing at the start of the sec proc. (for peripheral)
  691. ble_conn_state_user_flag_set(conn_handle, m_flag_allow_repairing, false);
  692. }
  693. #endif // BLE_GAP_ROLE_PERIPH
  694. if (role == BLE_GAP_ROLE_INVALID)
  695. {
  696. return BLE_ERROR_INVALID_CONN_HANDLE;
  697. }
  698. #if PM_RA_PROTECTION_ENABLED
  699. if (ast_peer_blacklisted(conn_handle)) //Check for repeated attempts here.
  700. {
  701. sec_status = BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS;
  702. }
  703. else
  704. #endif // PM_RA_PROTECTION_ENABLED
  705. if (p_sec_params == NULL)
  706. {
  707. // NULL params means reject pairing.
  708. sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP;
  709. }
  710. else
  711. {
  712. #ifdef BLE_GAP_ROLE_PERIPH
  713. if ((im_peer_id_get_by_conn_handle(conn_handle) != PM_PEER_ID_INVALID) &&
  714. (role == BLE_GAP_ROLE_PERIPH) &&
  715. !allow_repairing(conn_handle))
  716. {
  717. // Bond already exists. Reject the pairing request if the user doesn't intervene.
  718. send_config_req(conn_handle);
  719. if (!allow_repairing(conn_handle))
  720. {
  721. // Reject pairing.
  722. sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP;
  723. }
  724. }
  725. #endif // BLE_GAP_ROLE_PERIPH
  726. if (!p_sec_params->bond)
  727. {
  728. // Pairing, no bonding.
  729. sec_keyset.keys_own.p_pk = p_public_key;
  730. sec_keyset.keys_peer.p_pk = &m_peer_pk;
  731. }
  732. else if (sec_status != BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP)
  733. {
  734. // Bonding is to be performed, prepare to receive bonding data.
  735. err_code = sec_keyset_fill(conn_handle, role, p_public_key, &sec_keyset);
  736. }
  737. }
  738. if (err_code == NRF_SUCCESS)
  739. {
  740. // Everything OK, reply to SoftDevice. If an error happened, the user is given an
  741. // opportunity to change the parameters and retry the call.
  742. ble_gap_sec_params_t * p_aux_sec_params = NULL;
  743. #ifdef BLE_GAP_ROLE_PERIPH
  744. p_aux_sec_params = (role == BLE_GAP_ROLE_PERIPH) ? p_sec_params : NULL;
  745. #endif // BLE_GAP_ROLE_PERIPH
  746. err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, p_aux_sec_params, &sec_keyset);
  747. }
  748. return err_code;
  749. }
  750. /**@brief Function for initiating pairing as a central, or all security as a periheral.
  751. *
  752. * See @ref smd_link_secure and @ref sd_ble_gap_authenticate for more information.
  753. */
  754. static ret_code_t link_secure_authenticate(uint16_t conn_handle,
  755. ble_gap_sec_params_t * p_sec_params)
  756. {
  757. ret_code_t err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
  758. if (err_code == NRF_ERROR_NO_MEM)
  759. {
  760. // sd_ble_gap_authenticate() returned NRF_ERROR_NO_MEM. Too many other sec procedures running.
  761. err_code = NRF_ERROR_BUSY;
  762. }
  763. return err_code;
  764. }
  765. #if PM_CENTRAL_ENABLED
  766. /**@brief Function for initiating encryption as a central. See @ref smd_link_secure for more info.
  767. */
  768. static ret_code_t link_secure_central_encryption(uint16_t conn_handle,
  769. pm_peer_id_t peer_id)
  770. {
  771. pm_peer_data_flash_t peer_data;
  772. ret_code_t err_code;
  773. ble_gap_enc_key_t const * p_existing_key = NULL;
  774. bool lesc = false;
  775. err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data);
  776. if (err_code == NRF_SUCCESS)
  777. {
  778. // Use peer's key since they are peripheral.
  779. p_existing_key = &(peer_data.p_bonding_data->peer_ltk);
  780. lesc = peer_data.p_bonding_data->own_ltk.enc_info.lesc;
  781. if (lesc) // LESC was used during bonding.
  782. {
  783. // For LESC, always use own key.
  784. p_existing_key = &(peer_data.p_bonding_data->own_ltk);
  785. }
  786. }
  787. if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_NOT_FOUND))
  788. {
  789. if (err_code != NRF_ERROR_BUSY)
  790. {
  791. NRF_LOG_ERROR("Could not retrieve stored bond. pdb_peer_data_ptr_get() returned %s. "\
  792. "peer_id: %d",
  793. nrf_strerror_get(err_code),
  794. peer_id);
  795. err_code = NRF_ERROR_INTERNAL;
  796. }
  797. }
  798. else if (p_existing_key == NULL) /* There is no bonding data stored. This means that a bonding
  799. procedure is in ongoing, or that the records in flash are
  800. in a bad state. */
  801. {
  802. err_code = NRF_ERROR_BUSY;
  803. }
  804. else if (!lesc && !im_master_id_is_valid(&(p_existing_key->master_id))) /* There is no valid LTK stored. */
  805. {
  806. // No LTK to encrypt with.
  807. err_code = NRF_ERROR_INVALID_DATA;
  808. }
  809. else
  810. {
  811. // Encrypt with existing LTK.
  812. err_code = sd_ble_gap_encrypt(conn_handle,
  813. &(p_existing_key->master_id),
  814. &(p_existing_key->enc_info));
  815. }
  816. sec_proc_start(conn_handle, err_code == NRF_SUCCESS, PM_CONN_SEC_PROCEDURE_ENCRYPTION);
  817. return err_code;
  818. }
  819. /**@brief Function for intiating security as a central. See @ref smd_link_secure for more info.
  820. */
  821. static ret_code_t link_secure_central(uint16_t conn_handle,
  822. ble_gap_sec_params_t * p_sec_params,
  823. bool force_repairing)
  824. {
  825. ret_code_t err_code;
  826. pm_peer_id_t peer_id;
  827. if (p_sec_params == NULL)
  828. {
  829. return link_secure_authenticate(conn_handle, NULL);
  830. }
  831. // Set the default value for allowing repairing at the start of the sec proc. (for central)
  832. ble_conn_state_user_flag_set(conn_handle, m_flag_allow_repairing, force_repairing);
  833. peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  834. if ((peer_id != PM_PEER_ID_INVALID) && !force_repairing)
  835. {
  836. // There is already data in flash for this peer, and repairing has not been requested, so
  837. // the link will be encrypted with the existing keys.
  838. err_code = link_secure_central_encryption(conn_handle, peer_id);
  839. }
  840. else
  841. {
  842. // There are no existing keys, or repairing has been explicitly requested, so pairing
  843. // (possibly including bonding) will be performed to encrypt the link.
  844. err_code = link_secure_authenticate(conn_handle, p_sec_params);
  845. pm_conn_sec_procedure_t procedure = (p_sec_params && p_sec_params->bond) ?
  846. PM_CONN_SEC_PROCEDURE_BONDING :
  847. PM_CONN_SEC_PROCEDURE_PAIRING;
  848. sec_proc_start(conn_handle, err_code == NRF_SUCCESS, procedure);
  849. }
  850. return err_code;
  851. }
  852. /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_REQUEST event from the SoftDevice.
  853. *
  854. * @param[in] p_gap_evt The event from the SoftDevice.
  855. */
  856. static void sec_request_process(ble_gap_evt_t const * p_gap_evt)
  857. {
  858. if (sec_procedure(p_gap_evt->conn_handle))
  859. {
  860. // Ignore request as per spec.
  861. return;
  862. }
  863. pm_evt_t evt =
  864. {
  865. .evt_id = PM_EVT_SLAVE_SECURITY_REQ,
  866. .conn_handle = p_gap_evt->conn_handle
  867. };
  868. memcpy(&evt.params.slave_security_req, &p_gap_evt->params.sec_request, sizeof(ble_gap_evt_sec_request_t));
  869. evt_send(&evt);
  870. return;
  871. }
  872. #endif // PM_CENTRAL_ENABLED
  873. #ifdef BLE_GAP_ROLE_PERIPH
  874. /**@brief Function for asking the central to secure the link. See @ref smd_link_secure for more info.
  875. */
  876. static ret_code_t link_secure_peripheral(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params)
  877. {
  878. ret_code_t err_code = NRF_SUCCESS;
  879. if (p_sec_params != NULL)
  880. {
  881. err_code = link_secure_authenticate(conn_handle, p_sec_params);
  882. }
  883. return err_code;
  884. }
  885. #endif
  886. ret_code_t smd_link_secure(uint16_t conn_handle,
  887. ble_gap_sec_params_t * p_sec_params,
  888. bool force_repairing)
  889. {
  890. NRF_PM_DEBUG_CHECK(m_module_initialized);
  891. uint8_t role = ble_conn_state_role(conn_handle);
  892. switch (role)
  893. {
  894. #if PM_CENTRAL_ENABLED
  895. case BLE_GAP_ROLE_CENTRAL:
  896. return link_secure_central(conn_handle, p_sec_params, force_repairing);
  897. #endif
  898. #ifdef BLE_GAP_ROLE_PERIPH
  899. case BLE_GAP_ROLE_PERIPH:
  900. return link_secure_peripheral(conn_handle, p_sec_params);
  901. #endif // BLE_GAP_ROLE_PERIPH
  902. default:
  903. return BLE_ERROR_INVALID_CONN_HANDLE;
  904. }
  905. }
  906. void smd_ble_evt_handler(ble_evt_t const * p_ble_evt)
  907. {
  908. switch (p_ble_evt->header.evt_id)
  909. {
  910. case BLE_GAP_EVT_DISCONNECTED:
  911. disconnect_process(&(p_ble_evt->evt.gap_evt));
  912. break;
  913. case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
  914. sec_params_request_process(&(p_ble_evt->evt.gap_evt));
  915. break;
  916. #ifdef BLE_GAP_ROLE_PERIPH
  917. case BLE_GAP_EVT_SEC_INFO_REQUEST:
  918. sec_info_request_process(&(p_ble_evt->evt.gap_evt));
  919. break;
  920. #endif // BLE_GAP_ROLE_PERIPH
  921. #if PM_CENTRAL_ENABLED
  922. case BLE_GAP_EVT_SEC_REQUEST:
  923. sec_request_process(&(p_ble_evt->evt.gap_evt));
  924. break;
  925. #endif
  926. case BLE_GAP_EVT_AUTH_STATUS:
  927. auth_status_process(&(p_ble_evt->evt.gap_evt));
  928. break;
  929. case BLE_GAP_EVT_CONN_SEC_UPDATE:
  930. conn_sec_update_process(&(p_ble_evt->evt.gap_evt));
  931. break;
  932. };
  933. }
  934. #endif //NRF_MODULE_ENABLED(PEER_MANAGER)