oobtest.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2011-2012 Intel Corporation
  7. * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #include <getopt.h>
  15. #include "lib/bluetooth.h"
  16. #include "lib/mgmt.h"
  17. #include "src/shared/mainloop.h"
  18. #include "src/shared/util.h"
  19. #include "src/shared/mgmt.h"
  20. #include "src/shared/crypto.h"
  21. #define REMOTE_IRK "\x69\x30\xde\xc3\x8f\x84\x74\x14" \
  22. "\xe1\x23\x99\xc1\xca\x9a\xc3\x31"
  23. static bool use_bredr = false;
  24. static bool use_le = false;
  25. static bool use_sc = false;
  26. static bool use_sconly = false;
  27. static bool use_legacy = false;
  28. static bool use_random = false;
  29. static bool use_privacy = false;
  30. static bool use_debug = false;
  31. static bool use_cross = false;
  32. static bool provide_tk = false;
  33. static bool provide_p192 = false;
  34. static bool provide_p256 = false;
  35. static bool provide_initiator = false;
  36. static bool provide_acceptor = false;
  37. static struct mgmt *mgmt;
  38. static uint16_t index1 = MGMT_INDEX_NONE;
  39. static uint16_t index2 = MGMT_INDEX_NONE;
  40. static bdaddr_t bdaddr1;
  41. static bdaddr_t bdaddr2;
  42. static uint8_t oob_tk[16];
  43. static void pin_code_request_event(uint16_t index, uint16_t len,
  44. const void *param, void *user_data)
  45. {
  46. const struct mgmt_ev_pin_code_request *ev = param;
  47. struct mgmt_cp_pin_code_reply cp;
  48. char str[18];
  49. ba2str(&ev->addr.bdaddr, str);
  50. printf("[Index %u]\n", index);
  51. printf(" Pin code request: %s\n", str);
  52. memset(&cp, 0, sizeof(cp));
  53. memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
  54. cp.pin_len = 4;
  55. memset(cp.pin_code, '0', 4);
  56. mgmt_reply(mgmt, MGMT_OP_PIN_CODE_REPLY, index, sizeof(cp), &cp,
  57. NULL, NULL, NULL);
  58. }
  59. static void new_link_key_event(uint16_t index, uint16_t len,
  60. const void *param, void *user_data)
  61. {
  62. const struct mgmt_ev_new_link_key *ev = param;
  63. const char *type;
  64. char str[18];
  65. int i;
  66. ba2str(&ev->key.addr.bdaddr, str);
  67. switch (ev->key.type) {
  68. case 0x00:
  69. type = "Legacy";
  70. break;
  71. case 0x01:
  72. type = "Local Unit";
  73. break;
  74. case 0x02:
  75. type = "Remote Unit";
  76. break;
  77. case 0x03:
  78. type = "Debug";
  79. break;
  80. case 0x04:
  81. type = "Unauthenticated, P-192";
  82. break;
  83. case 0x05:
  84. type = "Authenticated, P-192";
  85. break;
  86. case 0x06:
  87. type = "Changed";
  88. break;
  89. case 0x07:
  90. type = "Unauthenticated, P-256";
  91. break;
  92. case 0x08:
  93. type = "Authenticated, P-256";
  94. break;
  95. default:
  96. type = "<unknown>";
  97. break;
  98. }
  99. printf("[Index %u]\n", index);
  100. printf(" New link key: %s\n", str);
  101. printf(" Type: %s (%u)\n", type, ev->key.type);
  102. printf(" Key: ");
  103. for (i = 0; i < 16; i++)
  104. printf("%02x", ev->key.val[i]);
  105. printf("\n");
  106. }
  107. static void new_long_term_key_event(uint16_t index, uint16_t len,
  108. const void *param, void *user_data)
  109. {
  110. const struct mgmt_ev_new_long_term_key *ev = param;
  111. const char *type;
  112. char str[18];
  113. int i;
  114. ba2str(&ev->key.addr.bdaddr, str);
  115. switch (ev->key.type) {
  116. case 0x00:
  117. if (ev->key.central)
  118. type = "Unauthenticated, Central";
  119. else
  120. type = "Unauthenticated, Peripheral";
  121. break;
  122. case 0x01:
  123. if (ev->key.central)
  124. type = "Authenticated, Central";
  125. else
  126. type = "Authenticated, Peripheral";
  127. break;
  128. case 0x02:
  129. type = "Unauthenticated, P-256";
  130. break;
  131. case 0x03:
  132. type = "Authenticated, P-256";
  133. break;
  134. case 0x04:
  135. type = "Debug";
  136. break;
  137. default:
  138. type = "<unknown>";
  139. break;
  140. }
  141. printf("[Index %u]\n", index);
  142. printf(" New long term key: %s\n", str);
  143. printf(" Type: %s (%u)\n", type, ev->key.type);
  144. printf(" Key: ");
  145. for (i = 0; i < 16; i++)
  146. printf("%02x", ev->key.val[i]);
  147. printf("\n");
  148. }
  149. static void pair_device_complete(uint8_t status, uint16_t len,
  150. const void *param, void *user_data)
  151. {
  152. uint16_t index = PTR_TO_UINT(user_data);
  153. if (status) {
  154. fprintf(stderr, "Pair device from index %u failed: %s\n",
  155. index, mgmt_errstr(status));
  156. }
  157. mainloop_quit();
  158. }
  159. static void pair_device(uint16_t index, const bdaddr_t *bdaddr)
  160. {
  161. struct mgmt_cp_pair_device cp;
  162. char str[18];
  163. ba2str(bdaddr, str);
  164. printf("[Index %u]\n", index);
  165. printf(" Starting pairing: %s\n", str);
  166. memset(&cp, 0, sizeof(cp));
  167. bacpy(&cp.addr.bdaddr, bdaddr);
  168. if (use_bredr)
  169. cp.addr.type = BDADDR_BREDR;
  170. else if (use_random)
  171. cp.addr.type = BDADDR_LE_RANDOM;
  172. else
  173. cp.addr.type = BDADDR_LE_PUBLIC;
  174. cp.io_cap = 0x03;
  175. mgmt_send(mgmt, MGMT_OP_PAIR_DEVICE, index, sizeof(cp), &cp,
  176. pair_device_complete,
  177. UINT_TO_PTR(index), NULL);
  178. }
  179. static void add_remote_oob_data_complete(uint8_t status, uint16_t len,
  180. const void *param, void *user_data)
  181. {
  182. const struct mgmt_addr_info *rp = param;
  183. uint16_t index = PTR_TO_UINT(user_data);
  184. char str[18];
  185. if (status) {
  186. fprintf(stderr, "Adding OOB data for index %u failed: %s\n",
  187. index, mgmt_errstr(status));
  188. }
  189. ba2str(&rp->bdaddr, str);
  190. printf("[Index %u]\n", index);
  191. printf(" Remote data added: %s\n", str);
  192. if (index == index1) {
  193. uint8_t val = 0x01;
  194. mgmt_send(mgmt, MGMT_OP_SET_CONNECTABLE, index2, 1, &val,
  195. NULL, NULL, NULL);
  196. if (use_le)
  197. mgmt_send(mgmt, MGMT_OP_SET_ADVERTISING, index2,
  198. 1, &val, NULL, NULL, NULL);
  199. pair_device(index1, &bdaddr2);
  200. }
  201. }
  202. static void add_remote_oob_data(uint16_t index, const bdaddr_t *bdaddr,
  203. const uint8_t *hash192, const uint8_t *rand192,
  204. const uint8_t *hash256, const uint8_t *rand256)
  205. {
  206. struct mgmt_cp_add_remote_oob_data cp;
  207. memset(&cp, 0, sizeof(cp));
  208. bacpy(&cp.addr.bdaddr, bdaddr);
  209. if (use_bredr)
  210. cp.addr.type = BDADDR_BREDR;
  211. else if (use_random)
  212. cp.addr.type = BDADDR_LE_RANDOM;
  213. else
  214. cp.addr.type = BDADDR_LE_PUBLIC;
  215. if (hash192) {
  216. memcpy(cp.hash192, hash192, 16);
  217. if (rand192)
  218. memcpy(cp.rand192, rand192, 16);
  219. else
  220. memset(cp.rand192, 0, 16);
  221. } else {
  222. memset(cp.hash192, 0, 16);
  223. memset(cp.rand192, 0, 16);
  224. }
  225. if (hash256 && rand256) {
  226. memcpy(cp.hash256, hash256, 16);
  227. memcpy(cp.rand256, rand256, 16);
  228. } else {
  229. memset(cp.hash256, 0, 16);
  230. memset(cp.rand256, 0, 16);
  231. }
  232. mgmt_send(mgmt, MGMT_OP_ADD_REMOTE_OOB_DATA, index, sizeof(cp), &cp,
  233. add_remote_oob_data_complete,
  234. UINT_TO_PTR(index), NULL);
  235. }
  236. static void read_oob_data_complete(uint8_t status, uint16_t len,
  237. const void *param, void *user_data)
  238. {
  239. const struct mgmt_rp_read_local_oob_data *rp = param;
  240. uint16_t index = PTR_TO_UINT(user_data);
  241. const uint8_t *hash192, *rand192, *hash256, *rand256;
  242. int i;
  243. if (status) {
  244. fprintf(stderr, "Reading OOB data for index %u failed: %s\n",
  245. index, mgmt_errstr(status));
  246. mainloop_quit();
  247. return;
  248. }
  249. printf("[Index %u]\n", index);
  250. hash192 = NULL;
  251. rand192 = NULL;
  252. hash256 = NULL;
  253. rand256 = NULL;
  254. if (index == index1 && !provide_initiator) {
  255. printf(" Skipping initiator OOB data\n");
  256. goto done;
  257. } else if (index == index2 && !provide_acceptor) {
  258. printf(" Skipping acceptor OOB data\n");
  259. goto done;
  260. }
  261. if (provide_p192) {
  262. hash192 = rp->hash192;
  263. rand192 = rp->rand192;
  264. }
  265. printf(" Hash C from P-192: ");
  266. for (i = 0; i < 16; i++)
  267. printf("%02x", rp->hash192[i]);
  268. printf("\n");
  269. printf(" Randomizer R with P-192: ");
  270. for (i = 0; i < 16; i++)
  271. printf("%02x", rp->rand192[i]);
  272. printf("\n");
  273. if (len < sizeof(*rp))
  274. goto done;
  275. if (provide_p256) {
  276. hash256 = rp->hash256;
  277. rand256 = rp->rand256;
  278. }
  279. printf(" Hash C from P-256: ");
  280. for (i = 0; i < 16; i++)
  281. printf("%02x", rp->hash256[i]);
  282. printf("\n");
  283. printf(" Randomizer R with P-256: ");
  284. for (i = 0; i < 16; i++)
  285. printf("%02x", rp->rand256[i]);
  286. printf("\n");
  287. done:
  288. if (index == index1)
  289. add_remote_oob_data(index2, &bdaddr1,
  290. hash192, rand192, hash256, rand256);
  291. else if (index == index2)
  292. add_remote_oob_data(index1, &bdaddr2,
  293. hash192, rand192, hash256, rand256);
  294. }
  295. static void read_oob_ext_data_complete(uint8_t status, uint16_t len,
  296. const void *param, void *user_data)
  297. {
  298. const struct mgmt_rp_read_local_oob_ext_data *rp = param;
  299. uint16_t index = PTR_TO_UINT(user_data);
  300. uint16_t eir_len, parsed;
  301. const uint8_t *eir, *tk, *hash256, *rand256;
  302. int i;
  303. if (status) {
  304. fprintf(stderr, "Reading OOB data for index %u failed: %s\n",
  305. index, mgmt_errstr(status));
  306. mainloop_quit();
  307. return;
  308. }
  309. printf("[Index %u]\n", index);
  310. eir_len = le16_to_cpu(rp->eir_len);
  311. printf(" OOB data len: %u\n", eir_len);
  312. if (provide_tk)
  313. tk = oob_tk;
  314. else
  315. tk = NULL;
  316. hash256 = NULL;
  317. rand256 = NULL;
  318. if (index == index1 && !provide_initiator) {
  319. printf(" Skipping initiator OOB data\n");
  320. goto done;
  321. } else if (index == index2 && !provide_acceptor) {
  322. printf(" Skipping acceptor OOB data\n");
  323. goto done;
  324. }
  325. if (eir_len < 2)
  326. goto done;
  327. eir = rp->eir;
  328. parsed = 0;
  329. while (parsed < eir_len - 1) {
  330. uint8_t field_len = eir[0];
  331. if (field_len == 0)
  332. break;
  333. parsed += field_len + 1;
  334. if (parsed > eir_len)
  335. break;
  336. /* LE Bluetooth Device Address */
  337. if (eir[1] == 0x1b) {
  338. char str[18];
  339. ba2str((bdaddr_t *) (eir + 2), str);
  340. printf(" Device address: %s (%s)\n", str,
  341. eir[8] ? "random" : "public");
  342. }
  343. /* LE Role */
  344. if (eir[1] == 0x1c)
  345. printf(" Role: 0x%02x\n", eir[2]);
  346. /* LE Secure Connections Confirmation Value */
  347. if (eir[1] == 0x22) {
  348. hash256 = eir + 2;
  349. printf(" Hash C from P-256: ");
  350. for (i = 0; i < 16; i++)
  351. printf("%02x", hash256[i]);
  352. printf("\n");
  353. }
  354. /* LE Secure Connections Random Value */
  355. if (eir[1] == 0x23) {
  356. rand256 = eir + 2;
  357. printf(" Randomizer R with P-256: ");
  358. for (i = 0; i < 16; i++)
  359. printf("%02x", rand256[i]);
  360. printf("\n");
  361. }
  362. eir += field_len + 1;
  363. }
  364. done:
  365. if (index == index1)
  366. add_remote_oob_data(index2, &bdaddr1,
  367. tk, NULL, hash256, rand256);
  368. else if (index == index2)
  369. add_remote_oob_data(index1, &bdaddr2,
  370. tk, NULL, hash256, rand256);
  371. }
  372. static void set_powered_complete(uint8_t status, uint16_t len,
  373. const void *param, void *user_data)
  374. {
  375. uint16_t index = PTR_TO_UINT(user_data);
  376. uint32_t settings;
  377. uint8_t val;
  378. if (status) {
  379. fprintf(stderr, "Powering on for index %u failed: %s\n",
  380. index, mgmt_errstr(status));
  381. mainloop_quit();
  382. return;
  383. }
  384. settings = get_le32(param);
  385. if (!(settings & MGMT_SETTING_POWERED)) {
  386. fprintf(stderr, "Controller is not powered\n");
  387. mainloop_quit();
  388. return;
  389. }
  390. if (use_debug) {
  391. if (index == index1) {
  392. val = 0x02;
  393. mgmt_send(mgmt, MGMT_OP_SET_DEBUG_KEYS, index, 1, &val,
  394. NULL, NULL, NULL);
  395. } else if (index == index2) {
  396. val = 0x01;
  397. mgmt_send(mgmt, MGMT_OP_SET_DEBUG_KEYS, index, 1, &val,
  398. NULL, NULL, NULL);
  399. }
  400. }
  401. if (use_bredr && (provide_p192 || provide_p256)) {
  402. mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_DATA, index, 0, NULL,
  403. read_oob_data_complete,
  404. UINT_TO_PTR(index), NULL);
  405. } else if (use_le && provide_p256) {
  406. uint8_t type = (1 << BDADDR_LE_PUBLIC) |
  407. (1 << BDADDR_LE_RANDOM);
  408. mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, index,
  409. sizeof(type), &type,
  410. read_oob_ext_data_complete,
  411. UINT_TO_PTR(index), NULL);
  412. } else if (use_le && provide_tk) {
  413. const uint8_t *tk = oob_tk;
  414. if (index == index1)
  415. add_remote_oob_data(index2, &bdaddr1,
  416. tk, NULL, NULL, NULL);
  417. else if (index == index2)
  418. add_remote_oob_data(index1, &bdaddr2,
  419. tk, NULL, NULL, NULL);
  420. } else {
  421. if (index == index1)
  422. add_remote_oob_data(index2, &bdaddr1,
  423. NULL, NULL, NULL, NULL);
  424. else if (index == index2)
  425. add_remote_oob_data(index1, &bdaddr2,
  426. NULL, NULL, NULL, NULL);
  427. }
  428. }
  429. static void clear_link_keys(uint16_t index)
  430. {
  431. struct mgmt_cp_load_link_keys cp;
  432. memset(&cp, 0, sizeof(cp));
  433. cp.debug_keys = 0x00;
  434. cp.key_count = cpu_to_le16(0);
  435. mgmt_send(mgmt, MGMT_OP_LOAD_LINK_KEYS, index,
  436. sizeof(cp), &cp, NULL, NULL, NULL);
  437. }
  438. static void clear_long_term_keys(uint16_t index)
  439. {
  440. struct mgmt_cp_load_long_term_keys cp;
  441. memset(&cp, 0, sizeof(cp));
  442. cp.key_count = cpu_to_le16(0);
  443. mgmt_send(mgmt, MGMT_OP_LOAD_LONG_TERM_KEYS, index,
  444. sizeof(cp), &cp, NULL, NULL, NULL);
  445. }
  446. static void clear_identity_resolving_keys(uint16_t index)
  447. {
  448. struct mgmt_cp_load_irks cp;
  449. memset(&cp, 0, sizeof(cp));
  450. cp.irk_count = cpu_to_le16(0);
  451. mgmt_send(mgmt, MGMT_OP_LOAD_IRKS, index,
  452. sizeof(cp), &cp, NULL, NULL, NULL);
  453. }
  454. static void clear_remote_oob_data(uint16_t index)
  455. {
  456. struct mgmt_cp_remove_remote_oob_data cp;
  457. memset(&cp, 0, sizeof(cp));
  458. bacpy(&cp.addr.bdaddr, BDADDR_ANY);
  459. cp.addr.type = BDADDR_BREDR;
  460. mgmt_send(mgmt, MGMT_OP_REMOVE_REMOTE_OOB_DATA, index,
  461. sizeof(cp), &cp, NULL, NULL, NULL);
  462. }
  463. static void set_powered_down_complete(uint8_t status, uint16_t len,
  464. const void *param, void *user_data)
  465. {
  466. uint16_t index = PTR_TO_UINT(user_data);
  467. if (status) {
  468. fprintf(stderr, "Power down for index %u failed: %s\n",
  469. index, mgmt_errstr(status));
  470. mainloop_quit();
  471. return;
  472. }
  473. }
  474. static void set_bredr_complete(uint8_t status, uint16_t len,
  475. const void *param, void *user_data)
  476. {
  477. uint16_t index = PTR_TO_UINT(user_data);
  478. if (status) {
  479. fprintf(stderr, "Setting BR/EDR for index %u failed: %s\n",
  480. index, mgmt_errstr(status));
  481. mainloop_quit();
  482. return;
  483. }
  484. }
  485. static void set_le_complete(uint8_t status, uint16_t len,
  486. const void *param, void *user_data)
  487. {
  488. uint16_t index = PTR_TO_UINT(user_data);
  489. if (status) {
  490. fprintf(stderr, "Setting LE for index %u failed: %s\n",
  491. index, mgmt_errstr(status));
  492. mainloop_quit();
  493. return;
  494. }
  495. }
  496. static void set_ssp_complete(uint8_t status, uint16_t len,
  497. const void *param, void *user_data)
  498. {
  499. uint16_t index = PTR_TO_UINT(user_data);
  500. if (status) {
  501. fprintf(stderr, "Simple Pairing for index %u failed: %s\n",
  502. index, mgmt_errstr(status));
  503. mainloop_quit();
  504. return;
  505. }
  506. }
  507. static void set_static_address_complete(uint8_t status, uint16_t len,
  508. const void *param, void *user_data)
  509. {
  510. uint16_t index = PTR_TO_UINT(user_data);
  511. if (status) {
  512. fprintf(stderr, "Static address for index %u failed: %s\n",
  513. index, mgmt_errstr(status));
  514. mainloop_quit();
  515. return;
  516. }
  517. }
  518. static void set_secure_conn_complete(uint8_t status, uint16_t len,
  519. const void *param, void *user_data)
  520. {
  521. uint16_t index = PTR_TO_UINT(user_data);
  522. if (status) {
  523. fprintf(stderr, "Secure connections for index %u failed: %s\n",
  524. index, mgmt_errstr(status));
  525. mainloop_quit();
  526. return;
  527. }
  528. }
  529. static void set_privacy_complete(uint8_t status, uint16_t len,
  530. const void *param, void *user_data)
  531. {
  532. uint16_t index = PTR_TO_UINT(user_data);
  533. if (status) {
  534. fprintf(stderr, "Setting privacy for index %u failed: %s\n",
  535. index, mgmt_errstr(status));
  536. mainloop_quit();
  537. return;
  538. }
  539. }
  540. static void set_debug_keys_complete(uint8_t status, uint16_t len,
  541. const void *param, void *user_data)
  542. {
  543. uint16_t index = PTR_TO_UINT(user_data);
  544. if (status) {
  545. fprintf(stderr, "Setting debug keys for index %u failed: %s\n",
  546. index, mgmt_errstr(status));
  547. mainloop_quit();
  548. return;
  549. }
  550. }
  551. static void set_bondable_complete(uint8_t status, uint16_t len,
  552. const void *param, void *user_data)
  553. {
  554. uint16_t index = PTR_TO_UINT(user_data);
  555. if (status) {
  556. fprintf(stderr, "Setting bondable for index %u failed: %s\n",
  557. index, mgmt_errstr(status));
  558. mainloop_quit();
  559. return;
  560. }
  561. }
  562. static void read_info(uint8_t status, uint16_t len, const void *param,
  563. void *user_data)
  564. {
  565. const struct mgmt_rp_read_info *rp = param;
  566. uint16_t index = PTR_TO_UINT(user_data);
  567. uint32_t supported_settings;
  568. uint8_t val;
  569. char str[18];
  570. if (status) {
  571. fprintf(stderr, "Reading info for index %u failed: %s\n",
  572. index, mgmt_errstr(status));
  573. mainloop_quit();
  574. return;
  575. }
  576. ba2str(&rp->bdaddr, str);
  577. printf("[Index %u]\n", index);
  578. printf(" Address: %s\n", str);
  579. if (index == index1)
  580. bacpy(&bdaddr1, &rp->bdaddr);
  581. else if (index == index2)
  582. bacpy(&bdaddr2, &rp->bdaddr);
  583. supported_settings = le32_to_cpu(rp->supported_settings);
  584. if (use_bredr && !(supported_settings & MGMT_SETTING_BREDR)) {
  585. fprintf(stderr, "BR/EDR support missing\n");
  586. mainloop_quit();
  587. return;
  588. }
  589. if (!use_legacy && !(supported_settings & MGMT_SETTING_SSP)) {
  590. fprintf(stderr, "Secure Simple Pairing support missing\n");
  591. mainloop_quit();
  592. return;
  593. }
  594. if (use_le && !(supported_settings & MGMT_SETTING_LE)) {
  595. fprintf(stderr, "Low Energy support missing\n");
  596. mainloop_quit();
  597. return;
  598. }
  599. if (use_sc && !(supported_settings & MGMT_SETTING_SECURE_CONN)) {
  600. fprintf(stderr, "Secure Connections support missing\n");
  601. mainloop_quit();
  602. return;
  603. }
  604. if (use_sconly && !(supported_settings & MGMT_SETTING_SECURE_CONN)) {
  605. fprintf(stderr, "Secure Connections Only support missing\n");
  606. mainloop_quit();
  607. return;
  608. }
  609. if (use_privacy && !(supported_settings & MGMT_SETTING_PRIVACY)) {
  610. fprintf(stderr, "Privacy support missing\n");
  611. mainloop_quit();
  612. return;
  613. }
  614. if (use_debug && !(supported_settings & MGMT_SETTING_DEBUG_KEYS)) {
  615. fprintf(stderr, "Debug keys support missing\n");
  616. mainloop_quit();
  617. return;
  618. }
  619. if (use_cross && (!(supported_settings & MGMT_SETTING_BREDR) ||
  620. !(supported_settings & MGMT_SETTING_LE))) {
  621. fprintf(stderr, "Dual-mode support is support missing\n");
  622. mainloop_quit();
  623. return;
  624. }
  625. if (provide_tk) {
  626. const uint8_t *tk = oob_tk;
  627. int i;
  628. printf(" TK Value: ");
  629. for (i = 0; i < 16; i++)
  630. printf("%02x", tk[i]);
  631. printf("\n");
  632. }
  633. mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index,
  634. pin_code_request_event,
  635. UINT_TO_PTR(index), NULL);
  636. mgmt_register(mgmt, MGMT_EV_NEW_LINK_KEY, index,
  637. new_link_key_event,
  638. UINT_TO_PTR(index), NULL);
  639. mgmt_register(mgmt, MGMT_EV_NEW_LONG_TERM_KEY, index,
  640. new_long_term_key_event,
  641. UINT_TO_PTR(index), NULL);
  642. val = 0x00;
  643. mgmt_send(mgmt, MGMT_OP_SET_POWERED, index, 1, &val,
  644. set_powered_down_complete,
  645. UINT_TO_PTR(index), NULL);
  646. clear_link_keys(index);
  647. clear_long_term_keys(index);
  648. clear_identity_resolving_keys(index);
  649. clear_remote_oob_data(index);
  650. if (use_bredr) {
  651. val = 0x01;
  652. mgmt_send(mgmt, MGMT_OP_SET_BREDR, index, 1, &val,
  653. set_bredr_complete,
  654. UINT_TO_PTR(index), NULL);
  655. val = use_cross ? 0x01 : 0x00;
  656. mgmt_send(mgmt, MGMT_OP_SET_LE, index, 1, &val,
  657. set_le_complete,
  658. UINT_TO_PTR(index), NULL);
  659. val = use_legacy ? 0x00 : 0x01;
  660. mgmt_send(mgmt, MGMT_OP_SET_SSP, index, 1, &val,
  661. set_ssp_complete,
  662. UINT_TO_PTR(index), NULL);
  663. } else if (use_le) {
  664. val = 0x01;
  665. mgmt_send(mgmt, MGMT_OP_SET_LE, index, 1, &val,
  666. set_le_complete,
  667. UINT_TO_PTR(index), NULL);
  668. val = use_cross ? 0x01 : 0x00;
  669. mgmt_send(mgmt, MGMT_OP_SET_BREDR, index, 1, &val,
  670. set_bredr_complete,
  671. UINT_TO_PTR(index), NULL);
  672. if (use_cross) {
  673. val = use_legacy ? 0x00 : 0x01;
  674. mgmt_send(mgmt, MGMT_OP_SET_SSP, index, 1, &val,
  675. set_ssp_complete,
  676. UINT_TO_PTR(index), NULL);
  677. }
  678. } else {
  679. fprintf(stderr, "Invalid transport for pairing\n");
  680. mainloop_quit();
  681. return;
  682. }
  683. if (use_random) {
  684. bdaddr_t bdaddr;
  685. str2ba("c0:00:aa:bb:00:00", &bdaddr);
  686. bdaddr.b[0] = index;
  687. mgmt_send(mgmt, MGMT_OP_SET_STATIC_ADDRESS, index, 6, &bdaddr,
  688. set_static_address_complete,
  689. UINT_TO_PTR(index), NULL);
  690. if (index == index1)
  691. bacpy(&bdaddr1, &bdaddr);
  692. else if (index == index2)
  693. bacpy(&bdaddr2, &bdaddr);
  694. } else {
  695. bdaddr_t bdaddr;
  696. bacpy(&bdaddr, BDADDR_ANY);
  697. mgmt_send(mgmt, MGMT_OP_SET_STATIC_ADDRESS, index, 6, &bdaddr,
  698. set_static_address_complete,
  699. UINT_TO_PTR(index), NULL);
  700. }
  701. if (use_sc) {
  702. val = 0x01;
  703. mgmt_send(mgmt, MGMT_OP_SET_SECURE_CONN, index, 1, &val,
  704. set_secure_conn_complete,
  705. UINT_TO_PTR(index), NULL);
  706. } else if (use_sconly) {
  707. val = 0x02;
  708. mgmt_send(mgmt, MGMT_OP_SET_SECURE_CONN, index, 1, &val,
  709. set_secure_conn_complete,
  710. UINT_TO_PTR(index), NULL);
  711. } else {
  712. val = 0x00;
  713. mgmt_send(mgmt, MGMT_OP_SET_SECURE_CONN, index, 1, &val,
  714. set_secure_conn_complete,
  715. UINT_TO_PTR(index), NULL);
  716. }
  717. if (use_privacy) {
  718. struct mgmt_cp_set_privacy cp;
  719. if (index == index2) {
  720. cp.privacy = 0x01;
  721. memcpy(cp.irk, REMOTE_IRK, sizeof(cp.irk));
  722. } else {
  723. cp.privacy = 0x00;
  724. memset(cp.irk, 0, sizeof(cp.irk));
  725. }
  726. mgmt_send(mgmt, MGMT_OP_SET_PRIVACY, index, sizeof(cp), &cp,
  727. set_privacy_complete,
  728. UINT_TO_PTR(index), NULL);
  729. } else {
  730. struct mgmt_cp_set_privacy cp;
  731. cp.privacy = 0x00;
  732. memset(cp.irk, 0, sizeof(cp.irk));
  733. mgmt_send(mgmt, MGMT_OP_SET_PRIVACY, index, sizeof(cp), &cp,
  734. set_privacy_complete,
  735. UINT_TO_PTR(index), NULL);
  736. }
  737. val = 0x00;
  738. mgmt_send(mgmt, MGMT_OP_SET_DEBUG_KEYS, index, 1, &val,
  739. set_debug_keys_complete,
  740. UINT_TO_PTR(index), NULL);
  741. val = 0x01;
  742. mgmt_send(mgmt, MGMT_OP_SET_BONDABLE, index, 1, &val,
  743. set_bondable_complete,
  744. UINT_TO_PTR(index), NULL);
  745. val = 0x01;
  746. mgmt_send(mgmt, MGMT_OP_SET_POWERED, index, 1, &val,
  747. set_powered_complete,
  748. UINT_TO_PTR(index), NULL);
  749. }
  750. static void read_index_list(uint8_t status, uint16_t len, const void *param,
  751. void *user_data)
  752. {
  753. const struct mgmt_rp_read_index_list *rp = param;
  754. uint16_t count;
  755. int i;
  756. if (status) {
  757. fprintf(stderr, "Reading index list failed: %s\n",
  758. mgmt_errstr(status));
  759. mainloop_quit();
  760. return;
  761. }
  762. count = le16_to_cpu(rp->num_controllers);
  763. if (count < 2) {
  764. fprintf(stderr, "At least 2 controllers are required\n");
  765. mainloop_quit();
  766. return;
  767. }
  768. for (i = 0; i < count; i++) {
  769. uint16_t index = cpu_to_le16(rp->index[i]);
  770. if (index < index1)
  771. index1 = index;
  772. }
  773. for (i = 0; i < count; i++) {
  774. uint16_t index = cpu_to_le16(rp->index[i]);
  775. if (index < index2 && index > index1)
  776. index2 = index;
  777. }
  778. printf("Selecting index %u for initiator\n", index1);
  779. printf("Selecting index %u for acceptor\n", index2);
  780. if (provide_tk) {
  781. struct bt_crypto *crypto;
  782. printf("Generating Security Manager TK Value\n");
  783. crypto = bt_crypto_new();
  784. bt_crypto_random_bytes(crypto, oob_tk, 16);
  785. bt_crypto_unref(crypto);
  786. }
  787. mgmt_send(mgmt, MGMT_OP_READ_INFO, index1, 0, NULL,
  788. read_info, UINT_TO_PTR(index1), NULL);
  789. mgmt_send(mgmt, MGMT_OP_READ_INFO, index2, 0, NULL,
  790. read_info, UINT_TO_PTR(index2), NULL);
  791. }
  792. static void signal_callback(int signum, void *user_data)
  793. {
  794. switch (signum) {
  795. case SIGINT:
  796. case SIGTERM:
  797. mainloop_quit();
  798. break;
  799. }
  800. }
  801. static void usage(void)
  802. {
  803. printf("oobtest - Out-of-band pairing testing\n"
  804. "Usage:\n");
  805. printf("\toobtest [options]\n");
  806. printf("options:\n"
  807. "\t-B, --bredr Use BR/EDR transport\n"
  808. "\t-L, --le Use LE transport\n"
  809. "\t-S, --sc Use Secure Connections\n"
  810. "\t-O, --sconly Use Secure Connections Only\n"
  811. "\t-P, --legacy Use Legacy Pairing\n"
  812. "\t-R, --random Use Static random address\n"
  813. "\t-Y, --privacy Use LE privacy feature\n"
  814. "\t-D, --debug Use Pairing debug keys\n"
  815. "\t-C, --cross Use cross-transport pairing\n"
  816. "\t-0, --tk Provide LE legacy OOB data\n"
  817. "\t-1, --p192 Provide P-192 OOB data\n"
  818. "\t-2, --p256 Provide P-256 OOB data\n"
  819. "\t-I, --initiator Initiator provides OOB data\n"
  820. "\t-A, --acceptor Acceptor provides OOB data\n"
  821. "\t-h, --help Show help options\n");
  822. }
  823. static const struct option main_options[] = {
  824. { "bredr", no_argument, NULL, 'B' },
  825. { "le", no_argument, NULL, 'L' },
  826. { "sc", no_argument, NULL, 'S' },
  827. { "sconly", no_argument, NULL, 'O' },
  828. { "legacy", no_argument, NULL, 'P' },
  829. { "random", no_argument, NULL, 'R' },
  830. { "static", no_argument, NULL, 'R' },
  831. { "privacy", no_argument, NULL, 'Y' },
  832. { "debug", no_argument, NULL, 'D' },
  833. { "cross", no_argument, NULL, 'C' },
  834. { "dual", no_argument, NULL, 'C' },
  835. { "tk", no_argument, NULL, '0' },
  836. { "p192", no_argument, NULL, '1' },
  837. { "p256", no_argument, NULL, '2' },
  838. { "initiator", no_argument, NULL, 'I' },
  839. { "acceptor", no_argument, NULL, 'A' },
  840. { "version", no_argument, NULL, 'v' },
  841. { "help", no_argument, NULL, 'h' },
  842. { }
  843. };
  844. int main(int argc ,char *argv[])
  845. {
  846. int exit_status;
  847. for (;;) {
  848. int opt;
  849. opt = getopt_long(argc, argv, "BLSOPRYDC012IAvh",
  850. main_options, NULL);
  851. if (opt < 0)
  852. break;
  853. switch (opt) {
  854. case 'B':
  855. use_bredr = true;
  856. break;
  857. case 'L':
  858. use_le = true;
  859. break;
  860. case 'S':
  861. use_sc = true;
  862. break;
  863. case 'O':
  864. use_sconly = true;
  865. break;
  866. case 'P':
  867. use_legacy = true;
  868. break;
  869. case 'R':
  870. use_random = true;
  871. break;
  872. case 'Y':
  873. use_privacy = true;
  874. break;
  875. case 'D':
  876. use_debug = true;
  877. break;
  878. case 'C':
  879. use_cross = true;
  880. break;
  881. case '0':
  882. provide_tk = true;
  883. break;
  884. case '1':
  885. provide_p192 = true;
  886. break;
  887. case '2':
  888. provide_p256 = true;
  889. break;
  890. case 'I':
  891. provide_initiator = true;
  892. break;
  893. case 'A':
  894. provide_acceptor = true;
  895. break;
  896. case 'v':
  897. printf("%s\n", VERSION);
  898. return EXIT_SUCCESS;
  899. case 'h':
  900. usage();
  901. return EXIT_SUCCESS;
  902. default:
  903. return EXIT_FAILURE;
  904. }
  905. }
  906. if (argc - optind > 0) {
  907. fprintf(stderr, "Invalid command line parameters\n");
  908. return EXIT_FAILURE;
  909. }
  910. if (use_bredr == use_le) {
  911. fprintf(stderr, "Specify either --bredr or --le\n");
  912. return EXIT_FAILURE;
  913. }
  914. if (use_legacy && !use_bredr) {
  915. fprintf(stderr, "Specify --legacy with --bredr\n");
  916. return EXIT_FAILURE;
  917. }
  918. if (use_privacy && !use_le && !use_cross ) {
  919. fprintf(stderr, "Specify --privacy with --le or --cross\n");
  920. return EXIT_FAILURE;
  921. }
  922. if (use_random && !use_le) {
  923. fprintf(stderr, "Specify --random with --le\n");
  924. return EXIT_FAILURE;
  925. }
  926. if (use_random && use_cross) {
  927. fprintf(stderr, "Only --random or --cross can be used\n");
  928. return EXIT_FAILURE;
  929. }
  930. if (use_sc && use_sconly) {
  931. fprintf(stderr, "Only --sc or --sconly can be used\n");
  932. return EXIT_FAILURE;
  933. }
  934. mainloop_init();
  935. mgmt = mgmt_new_default();
  936. if (!mgmt) {
  937. fprintf(stderr, "Failed to open management socket\n");
  938. return EXIT_FAILURE;
  939. }
  940. if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST,
  941. MGMT_INDEX_NONE, 0, NULL,
  942. read_index_list, NULL, NULL)) {
  943. fprintf(stderr, "Failed to read index list\n");
  944. exit_status = EXIT_FAILURE;
  945. goto done;
  946. }
  947. exit_status = mainloop_run_with_signal(signal_callback, NULL);
  948. done:
  949. mgmt_unref(mgmt);
  950. return exit_status;
  951. }