smp_api.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2008-2012 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /******************************************************************************
  19. *
  20. * This file contains the implementation of the SMP interface used by
  21. * applications that can run over an SMP.
  22. *
  23. ******************************************************************************/
  24. #include <string.h>
  25. #include "bt_target.h"
  26. //#include "bt_utils.h"
  27. #if SMP_INCLUDED == TRUE
  28. #include "smp_int.h"
  29. #include "smp_api.h"
  30. #include "l2cdefs.h"
  31. #include "l2c_int.h"
  32. #include "btm_int.h"
  33. #include "hcimsgs.h"
  34. #include "btu.h"
  35. #include "p_256_ecc_pp.h"
  36. /*******************************************************************************
  37. **
  38. ** Function SMP_Init
  39. **
  40. ** Description This function initializes the SMP unit.
  41. **
  42. ** Returns void
  43. **
  44. *******************************************************************************/
  45. void SMP_Init(void)
  46. {
  47. memset(&smp_cb, 0, sizeof(tSMP_CB));
  48. #if defined(SMP_INITIAL_TRACE_LEVEL)
  49. smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
  50. #else
  51. smp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  52. #endif
  53. SMP_TRACE_EVENT ("%s", __FUNCTION__);
  54. smp_l2cap_if_init();
  55. /* initialization of P-256 parameters */
  56. p_256_init_curve(KEY_LENGTH_DWORDS_P256);
  57. }
  58. /*******************************************************************************
  59. **
  60. ** Function SMP_SetTraceLevel
  61. **
  62. ** Description This function sets the trace level for SMP. If called with
  63. ** a value of 0xFF, it simply returns the current trace level.
  64. **
  65. ** Input Parameters:
  66. ** level: The level to set the GATT tracing to:
  67. ** 0xff-returns the current setting.
  68. ** 0-turns off tracing.
  69. ** >= 1-Errors.
  70. ** >= 2-Warnings.
  71. ** >= 3-APIs.
  72. ** >= 4-Events.
  73. ** >= 5-Debug.
  74. **
  75. ** Returns The new or current trace level
  76. **
  77. *******************************************************************************/
  78. extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
  79. {
  80. if (new_level != 0xFF) {
  81. smp_cb.trace_level = new_level;
  82. }
  83. return (smp_cb.trace_level);
  84. }
  85. /*******************************************************************************
  86. **
  87. ** Function SMP_Register
  88. **
  89. ** Description This function register for the SMP services callback.
  90. **
  91. ** Returns void
  92. **
  93. *******************************************************************************/
  94. BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
  95. {
  96. SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state);
  97. if (smp_cb.p_callback != NULL) {
  98. SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it");
  99. }
  100. smp_cb.p_callback = p_cback;
  101. return (TRUE);
  102. }
  103. /*******************************************************************************
  104. **
  105. ** Function SMP_Pair
  106. **
  107. ** Description This function call to perform a SMP pairing with peer device.
  108. ** Device support one SMP pairing at one time.
  109. **
  110. ** Parameters bd_addr - peer device bd address.
  111. **
  112. ** Returns None
  113. **
  114. *******************************************************************************/
  115. tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
  116. {
  117. tSMP_CB *p_cb = &smp_cb;
  118. UINT8 status = SMP_PAIR_INTERNAL_ERR;
  119. SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x \n",
  120. __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
  121. if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
  122. p_cb->smp_over_br) {
  123. /* pending security on going, reject this one */
  124. return SMP_BUSY;
  125. } else {
  126. p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
  127. memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
  128. if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr)) {
  129. SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.\n", __FUNCTION__);
  130. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
  131. return status;
  132. }
  133. return SMP_STARTED;
  134. }
  135. }
  136. /*******************************************************************************
  137. **
  138. ** Function SMP_BR_PairWith
  139. **
  140. ** Description This function is called to start a SMP pairing over BR/EDR.
  141. ** Device support one SMP pairing at one time.
  142. **
  143. ** Parameters bd_addr - peer device bd address.
  144. **
  145. ** Returns SMP_STARTED if pairing started, otherwise reason for failure.
  146. **
  147. *******************************************************************************/
  148. tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
  149. {
  150. tSMP_CB *p_cb = &smp_cb;
  151. UINT8 status = SMP_PAIR_INTERNAL_ERR;
  152. SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
  153. __func__, p_cb->state, p_cb->br_state, p_cb->flags);
  154. if (p_cb->state != SMP_STATE_IDLE ||
  155. p_cb->smp_over_br ||
  156. p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
  157. /* pending security on going, reject this one */
  158. return SMP_BUSY;
  159. }
  160. p_cb->role = HCI_ROLE_MASTER;
  161. p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
  162. p_cb->smp_over_br = TRUE;
  163. memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
  164. if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr)) {
  165. SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
  166. smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
  167. return status;
  168. }
  169. return SMP_STARTED;
  170. }
  171. /*******************************************************************************
  172. **
  173. ** Function SMP_PairCancel
  174. **
  175. ** Description This function call to cancel a SMP pairing with peer device.
  176. **
  177. ** Parameters bd_addr - peer device bd address.
  178. **
  179. ** Returns TRUE - Pairining is cancelled
  180. **
  181. *******************************************************************************/
  182. BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
  183. {
  184. tSMP_CB *p_cb = &smp_cb;
  185. UINT8 err_code = SMP_PAIR_FAIL_UNKNOWN;
  186. BOOLEAN status = FALSE;
  187. BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
  188. if ( (p_cb->state != SMP_STATE_IDLE) &&
  189. (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) ) {
  190. p_cb->is_pair_cancel = TRUE;
  191. SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown");
  192. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
  193. status = TRUE;
  194. }
  195. return status;
  196. }
  197. /*******************************************************************************
  198. **
  199. ** Function SMP_SecurityGrant
  200. **
  201. ** Description This function is called to grant security process.
  202. **
  203. ** Parameters bd_addr - peer device bd address.
  204. ** res - result of the operation SMP_SUCCESS if success.
  205. ** Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
  206. **
  207. ** Returns None
  208. **
  209. *******************************************************************************/
  210. void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
  211. {
  212. SMP_TRACE_EVENT ("SMP_SecurityGrant ");
  213. if (smp_cb.smp_over_br) {
  214. if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
  215. smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
  216. memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
  217. return;
  218. }
  219. /* clear the SMP_SEC_REQUEST_EVT event after get grant */
  220. /* avoid generating duplicate pair request */
  221. smp_cb.cb_evt = 0;
  222. smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
  223. return;
  224. }
  225. if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
  226. smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
  227. memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
  228. return;
  229. }
  230. /* clear the SMP_SEC_REQUEST_EVT event after get grant */
  231. /* avoid generate duplicate pair request */
  232. smp_cb.cb_evt = 0;
  233. smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
  234. }
  235. /*******************************************************************************
  236. **
  237. ** Function SMP_PasskeyReply
  238. **
  239. ** Description This function is called after Security Manager submitted
  240. ** passkey request to the application.
  241. **
  242. ** Parameters: bd_addr - Address of the device for which passkey was requested
  243. ** res - result of the operation SMP_SUCCESS if success
  244. ** passkey - numeric value in the range of
  245. ** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
  246. **
  247. *******************************************************************************/
  248. void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
  249. {
  250. tSMP_CB *p_cb = & smp_cb;
  251. UINT8 failure = SMP_PASSKEY_ENTRY_FAIL;
  252. SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d Result:%d",
  253. passkey, res);
  254. /* If timeout already expired or has been canceled, ignore the reply */
  255. if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT) {
  256. SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
  257. return;
  258. }
  259. if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
  260. SMP_TRACE_ERROR ("SMP_PasskeyReply() - Wrong BD Addr");
  261. return;
  262. }
  263. if (btm_find_dev (bd_addr) == NULL) {
  264. SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB");
  265. return;
  266. }
  267. if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS) {
  268. SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
  269. /* send pairing failure */
  270. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  271. } else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT) {
  272. smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey);
  273. } else {
  274. smp_convert_string_to_tk(p_cb->tk, passkey);
  275. }
  276. return;
  277. }
  278. /*******************************************************************************
  279. **
  280. ** Function SMP_ConfirmReply
  281. **
  282. ** Description This function is called after Security Manager submitted
  283. ** numeric comparison request to the application.
  284. **
  285. ** Parameters: bd_addr - Address of the device with which numeric
  286. ** comparison was requested
  287. ** res - comparison result SMP_SUCCESS if success
  288. **
  289. *******************************************************************************/
  290. void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res)
  291. {
  292. tSMP_CB *p_cb = & smp_cb;
  293. UINT8 failure = SMP_NUMERIC_COMPAR_FAIL;
  294. SMP_TRACE_EVENT ("%s: Result:%d", __FUNCTION__, res);
  295. /* If timeout already expired or has been canceled, ignore the reply */
  296. if (p_cb->cb_evt != SMP_NC_REQ_EVT) {
  297. SMP_TRACE_WARNING ("%s() - Wrong State: %d", __FUNCTION__, p_cb->state);
  298. return;
  299. }
  300. if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
  301. SMP_TRACE_ERROR ("%s() - Wrong BD Addr", __FUNCTION__);
  302. return;
  303. }
  304. if (btm_find_dev (bd_addr) == NULL) {
  305. SMP_TRACE_ERROR ("%s() - no dev CB", __FUNCTION__);
  306. return;
  307. }
  308. if (res != SMP_SUCCESS) {
  309. SMP_TRACE_WARNING ("%s() - Numeric Comparison fails", __FUNCTION__);
  310. /* send pairing failure */
  311. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  312. } else {
  313. smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL);
  314. }
  315. }
  316. /*******************************************************************************
  317. **
  318. ** Function SMP_OobDataReply
  319. **
  320. ** Description This function is called to provide the OOB data for
  321. ** SMP in response to SMP_OOB_REQ_EVT
  322. **
  323. ** Parameters: bd_addr - Address of the peer device
  324. ** res - result of the operation SMP_SUCCESS if success
  325. ** p_data - simple pairing Randomizer C.
  326. **
  327. *******************************************************************************/
  328. void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
  329. {
  330. tSMP_CB *p_cb = & smp_cb;
  331. UINT8 failure = SMP_OOB_FAIL;
  332. tSMP_KEY key;
  333. SMP_TRACE_EVENT ("%s State: %d res:%d", __FUNCTION__, smp_cb.state, res);
  334. /* If timeout already expired or has been canceled, ignore the reply */
  335. if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT) {
  336. return;
  337. }
  338. if (res != SMP_SUCCESS || len == 0 || !p_data) {
  339. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  340. } else {
  341. if (len > BT_OCTET16_LEN) {
  342. len = BT_OCTET16_LEN;
  343. }
  344. memcpy(p_cb->tk, p_data, len);
  345. key.key_type = SMP_KEY_TYPE_TK;
  346. key.p_data = p_cb->tk;
  347. smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
  348. }
  349. }
  350. /*******************************************************************************
  351. **
  352. ** Function SMP_SecureConnectionOobDataReply
  353. **
  354. ** Description This function is called to provide the SC OOB data for
  355. ** SMP in response to SMP_SC_OOB_REQ_EVT
  356. **
  357. ** Parameters: p_data - pointer to the data
  358. **
  359. *******************************************************************************/
  360. void SMP_SecureConnectionOobDataReply(UINT8 *p_data)
  361. {
  362. tSMP_CB *p_cb = &smp_cb;
  363. UINT8 failure = SMP_OOB_FAIL;
  364. tSMP_SC_OOB_DATA *p_oob = (tSMP_SC_OOB_DATA *) p_data;
  365. if (!p_oob) {
  366. SMP_TRACE_ERROR("%s received no data", __FUNCTION__);
  367. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  368. return;
  369. }
  370. SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, "
  371. "peer_oob_data.present: %d",
  372. __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present,
  373. p_oob->peer_oob_data.present);
  374. if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_SC_OOB_REQ_EVT) {
  375. return;
  376. }
  377. BOOLEAN data_missing = FALSE;
  378. switch (p_cb->req_oob_type) {
  379. case SMP_OOB_PEER:
  380. if (!p_oob->peer_oob_data.present) {
  381. data_missing = TRUE;
  382. }
  383. break;
  384. case SMP_OOB_LOCAL:
  385. if (!p_oob->loc_oob_data.present) {
  386. data_missing = TRUE;
  387. }
  388. break;
  389. case SMP_OOB_BOTH:
  390. if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present) {
  391. data_missing = TRUE;
  392. }
  393. break;
  394. default:
  395. SMP_TRACE_EVENT ("Unexpected OOB data type requested. Fail OOB");
  396. data_missing = TRUE;
  397. break;
  398. }
  399. if (data_missing) {
  400. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  401. return;
  402. }
  403. p_cb->sc_oob_data = *p_oob;
  404. smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data);
  405. }
  406. /*******************************************************************************
  407. **
  408. ** Function SMP_Encrypt
  409. **
  410. ** Description This function is called to encrypt the data with the specified
  411. ** key
  412. **
  413. ** Parameters: key - Pointer to key key[0] conatins the MSB
  414. ** key_len - key length
  415. ** plain_text - Pointer to data to be encrypted
  416. ** plain_text[0] conatins the MSB
  417. ** pt_len - plain text length
  418. ** p_out - output of the encrypted texts
  419. **
  420. ** Returns Boolean - request is successful
  421. *******************************************************************************/
  422. BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
  423. UINT8 *plain_text, UINT8 pt_len,
  424. tSMP_ENC *p_out)
  425. {
  426. BOOLEAN status = FALSE;
  427. status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
  428. return status;
  429. }
  430. /*******************************************************************************
  431. **
  432. ** Function SMP_KeypressNotification
  433. **
  434. ** Description This function is called to notify Security Manager about Keypress Notification.
  435. **
  436. ** Parameters: bd_addr Address of the device to send keypress notification to
  437. ** value Keypress notification parameter value
  438. **
  439. *******************************************************************************/
  440. void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value)
  441. {
  442. tSMP_CB *p_cb = &smp_cb;
  443. SMP_TRACE_EVENT ("%s: Value: %d", __FUNCTION__, value);
  444. if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
  445. SMP_TRACE_ERROR ("%s() - Wrong BD Addr", __FUNCTION__);
  446. return;
  447. }
  448. if (btm_find_dev (bd_addr) == NULL) {
  449. SMP_TRACE_ERROR ("%s() - no dev CB", __FUNCTION__);
  450. return;
  451. }
  452. /* Keypress Notification is used by a device with KeyboardOnly IO capabilities */
  453. /* during the passkey entry protocol */
  454. if (p_cb->local_io_capability != SMP_IO_CAP_IN) {
  455. SMP_TRACE_ERROR ("%s() - wrong local IO capabilities %d",
  456. __FUNCTION__, p_cb->local_io_capability);
  457. return;
  458. }
  459. if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT) {
  460. SMP_TRACE_ERROR ("%s() - wrong protocol %d", __FUNCTION__,
  461. p_cb->selected_association_model);
  462. return;
  463. }
  464. smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value);
  465. }
  466. /*******************************************************************************
  467. **
  468. ** Function SMP_CreateLocalSecureConnectionsOobData
  469. **
  470. ** Description This function is called to start creation of local SC OOB
  471. ** data set (tSMP_LOC_OOB_DATA).
  472. **
  473. ** Parameters: bd_addr - Address of the device to send OOB data block to
  474. **
  475. ** Returns Boolean - TRUE: creation of local SC OOB data set started.
  476. *******************************************************************************/
  477. BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to)
  478. {
  479. tSMP_CB *p_cb = &smp_cb;
  480. UINT8 *bd_addr;
  481. if (addr_to_send_to == NULL) {
  482. SMP_TRACE_ERROR ("%s addr_to_send_to is not provided", __FUNCTION__);
  483. return FALSE;
  484. }
  485. bd_addr = addr_to_send_to->bda;
  486. SMP_TRACE_EVENT ("%s addr type: %u, BDA: %08x%04x, state: %u, br_state: %u",
  487. __FUNCTION__, addr_to_send_to->type,
  488. (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
  489. (bd_addr[4] << 8) + bd_addr[5],
  490. p_cb->state,
  491. p_cb->br_state);
  492. if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br)) {
  493. SMP_TRACE_WARNING ("%s creation of local OOB data set "\
  494. "starts only in IDLE state", __FUNCTION__);
  495. return FALSE;
  496. }
  497. p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to;
  498. smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL);
  499. return TRUE;
  500. }
  501. #endif /* SMP_INCLUDED */