smp-tester.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2013 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdlib.h>
  14. #include <unistd.h>
  15. #include <errno.h>
  16. #include <stdbool.h>
  17. #include <sys/socket.h>
  18. #include <glib.h>
  19. #include "lib/bluetooth.h"
  20. #include "lib/hci.h"
  21. #include "lib/mgmt.h"
  22. #include "monitor/bt.h"
  23. #include "emulator/bthost.h"
  24. #include "emulator/hciemu.h"
  25. #include "src/shared/crypto.h"
  26. #include "src/shared/ecc.h"
  27. #include "src/shared/tester.h"
  28. #include "src/shared/mgmt.h"
  29. #define SMP_CID 0x0006
  30. struct test_data {
  31. const void *test_data;
  32. struct mgmt *mgmt;
  33. uint16_t mgmt_index;
  34. struct hciemu *hciemu;
  35. enum hciemu_type hciemu_type;
  36. unsigned int io_id;
  37. uint8_t ia[6];
  38. uint8_t ia_type;
  39. uint8_t ra[6];
  40. uint8_t ra_type;
  41. bool out;
  42. uint16_t handle;
  43. size_t counter;
  44. struct bt_crypto *crypto;
  45. uint8_t tk[16];
  46. uint8_t prnd[16];
  47. uint8_t rrnd[16];
  48. uint8_t pcnf[16];
  49. uint8_t preq[7];
  50. uint8_t prsp[7];
  51. uint8_t ltk[16];
  52. uint8_t remote_pk[64];
  53. uint8_t local_pk[64];
  54. uint8_t local_sk[32];
  55. uint8_t dhkey[32];
  56. int unmet_conditions;
  57. };
  58. struct smp_req_rsp {
  59. const void *send;
  60. uint16_t send_len;
  61. const void *expect;
  62. uint16_t expect_len;
  63. };
  64. struct smp_data {
  65. const struct smp_req_rsp *req;
  66. size_t req_count;
  67. bool mitm;
  68. uint16_t expect_hci_command;
  69. const void *expect_hci_param;
  70. uint8_t expect_hci_len;
  71. const void * (*expect_hci_func)(uint8_t *len);
  72. bool sc;
  73. };
  74. static void print_debug(const char *str, void *user_data)
  75. {
  76. const char *prefix = user_data;
  77. tester_print("%s%s", prefix, str);
  78. }
  79. static void read_info_callback(uint8_t status, uint16_t length,
  80. const void *param, void *user_data)
  81. {
  82. struct test_data *data = tester_get_data();
  83. const struct mgmt_rp_read_info *rp = param;
  84. char addr[18];
  85. uint16_t manufacturer;
  86. uint32_t supported_settings, current_settings;
  87. tester_print("Read Info callback");
  88. tester_print(" Status: 0x%02x", status);
  89. if (status || !param) {
  90. tester_pre_setup_failed();
  91. return;
  92. }
  93. ba2str(&rp->bdaddr, addr);
  94. manufacturer = btohs(rp->manufacturer);
  95. supported_settings = btohl(rp->supported_settings);
  96. current_settings = btohl(rp->current_settings);
  97. tester_print(" Address: %s", addr);
  98. tester_print(" Version: 0x%02x", rp->version);
  99. tester_print(" Manufacturer: 0x%04x", manufacturer);
  100. tester_print(" Supported settings: 0x%08x", supported_settings);
  101. tester_print(" Current settings: 0x%08x", current_settings);
  102. tester_print(" Class: 0x%02x%02x%02x",
  103. rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
  104. tester_print(" Name: %s", rp->name);
  105. tester_print(" Short name: %s", rp->short_name);
  106. if (strcmp(hciemu_get_address(data->hciemu), addr)) {
  107. tester_pre_setup_failed();
  108. return;
  109. }
  110. tester_pre_setup_complete();
  111. }
  112. static void index_added_callback(uint16_t index, uint16_t length,
  113. const void *param, void *user_data)
  114. {
  115. struct test_data *data = tester_get_data();
  116. tester_print("Index Added callback");
  117. tester_print(" Index: 0x%04x", index);
  118. data->mgmt_index = index;
  119. mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
  120. read_info_callback, NULL, NULL);
  121. }
  122. static void index_removed_callback(uint16_t index, uint16_t length,
  123. const void *param, void *user_data)
  124. {
  125. struct test_data *data = tester_get_data();
  126. tester_print("Index Removed callback");
  127. tester_print(" Index: 0x%04x", index);
  128. if (index != data->mgmt_index)
  129. return;
  130. mgmt_unregister_index(data->mgmt, data->mgmt_index);
  131. mgmt_unref(data->mgmt);
  132. data->mgmt = NULL;
  133. tester_post_teardown_complete();
  134. }
  135. static void read_index_list_callback(uint8_t status, uint16_t length,
  136. const void *param, void *user_data)
  137. {
  138. struct test_data *data = tester_get_data();
  139. tester_print("Read Index List callback");
  140. tester_print(" Status: 0x%02x", status);
  141. if (status || !param) {
  142. tester_pre_setup_failed();
  143. return;
  144. }
  145. mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
  146. index_added_callback, NULL, NULL);
  147. mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
  148. index_removed_callback, NULL, NULL);
  149. data->hciemu = hciemu_new(data->hciemu_type);
  150. if (!data->hciemu) {
  151. tester_warn("Failed to setup HCI emulation");
  152. tester_pre_setup_failed();
  153. }
  154. if (tester_use_debug())
  155. hciemu_set_debug(data->hciemu, print_debug, "hciemu: ", NULL);
  156. tester_print("New hciemu instance created");
  157. }
  158. static void test_pre_setup(const void *test_data)
  159. {
  160. struct test_data *data = tester_get_data();
  161. data->crypto = bt_crypto_new();
  162. if (!data->crypto) {
  163. tester_warn("Failed to setup crypto");
  164. tester_pre_setup_failed();
  165. return;
  166. }
  167. data->mgmt = mgmt_new_default();
  168. if (!data->mgmt) {
  169. tester_warn("Failed to setup management interface");
  170. bt_crypto_unref(data->crypto);
  171. tester_pre_setup_failed();
  172. return;
  173. }
  174. if (tester_use_debug())
  175. mgmt_set_debug(data->mgmt, print_debug, "mgmt: ", NULL);
  176. mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
  177. read_index_list_callback, NULL, NULL);
  178. }
  179. static void test_post_teardown(const void *test_data)
  180. {
  181. struct test_data *data = tester_get_data();
  182. if (data->io_id > 0) {
  183. g_source_remove(data->io_id);
  184. data->io_id = 0;
  185. }
  186. if (data->crypto) {
  187. bt_crypto_unref(data->crypto);
  188. data->crypto = NULL;
  189. }
  190. hciemu_unref(data->hciemu);
  191. data->hciemu = NULL;
  192. }
  193. static void test_data_free(void *test_data)
  194. {
  195. struct test_data *data = test_data;
  196. free(data);
  197. }
  198. static void test_add_condition(struct test_data *data)
  199. {
  200. data->unmet_conditions++;
  201. tester_print("Test condition added, total %d", data->unmet_conditions);
  202. }
  203. static void test_condition_complete(struct test_data *data)
  204. {
  205. data->unmet_conditions--;
  206. tester_print("Test condition complete, %d left",
  207. data->unmet_conditions);
  208. if (data->unmet_conditions > 0)
  209. return;
  210. tester_test_passed();
  211. }
  212. #define test_smp(name, data, setup, func) \
  213. do { \
  214. struct test_data *user; \
  215. user = calloc(1, sizeof(struct test_data)); \
  216. if (!user) \
  217. break; \
  218. user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
  219. user->test_data = data; \
  220. tester_add_full(name, data, \
  221. test_pre_setup, setup, func, NULL, \
  222. test_post_teardown, 2, user, test_data_free); \
  223. } while (0)
  224. static const uint8_t smp_nval_req_1[] = { 0x0b, 0x00 };
  225. static const uint8_t smp_nval_req_1_rsp[] = { 0x05, 0x07 };
  226. static const struct smp_req_rsp nval_req_1[] = {
  227. { smp_nval_req_1, sizeof(smp_nval_req_1),
  228. smp_nval_req_1_rsp, sizeof(smp_nval_req_1_rsp) },
  229. };
  230. static const struct smp_data smp_server_nval_req_1_test = {
  231. .req = nval_req_1,
  232. .req_count = G_N_ELEMENTS(nval_req_1),
  233. };
  234. static const uint8_t smp_nval_req_2[7] = { 0x01 };
  235. static const uint8_t smp_nval_req_2_rsp[] = { 0x05, 0x06 };
  236. static const struct smp_req_rsp srv_nval_req_1[] = {
  237. { smp_nval_req_2, sizeof(smp_nval_req_2),
  238. smp_nval_req_2_rsp, sizeof(smp_nval_req_2_rsp) },
  239. };
  240. static const struct smp_data smp_server_nval_req_2_test = {
  241. .req = srv_nval_req_1,
  242. .req_count = G_N_ELEMENTS(srv_nval_req_1),
  243. };
  244. static const uint8_t smp_nval_req_3[] = { 0x01, 0xff };
  245. static const uint8_t smp_nval_req_3_rsp[] = { 0x05, 0x0a };
  246. static const struct smp_req_rsp srv_nval_req_2[] = {
  247. { smp_nval_req_3, sizeof(smp_nval_req_3),
  248. smp_nval_req_3_rsp, sizeof(smp_nval_req_3_rsp) },
  249. };
  250. static const struct smp_data smp_server_nval_req_3_test = {
  251. .req = srv_nval_req_2,
  252. .req_count = G_N_ELEMENTS(srv_nval_req_2),
  253. };
  254. static const uint8_t smp_basic_req_1[] = { 0x01, /* Pairing Request */
  255. 0x03, /* NoInputNoOutput */
  256. 0x00, /* OOB Flag */
  257. 0x01, /* Bonding - no MITM */
  258. 0x10, /* Max key size */
  259. 0x05, /* Init. key dist. */
  260. 0x05, /* Rsp. key dist. */
  261. };
  262. static const uint8_t smp_basic_req_1_rsp[] = { 0x02, /* Pairing Response */
  263. 0x03, /* NoInputNoOutput */
  264. 0x00, /* OOB Flag */
  265. 0x01, /* Bonding - no MITM */
  266. 0x10, /* Max key size */
  267. 0x05, /* Init. key dist. */
  268. 0x05, /* Rsp. key dist. */
  269. };
  270. static const uint8_t smp_confirm_req_1[17] = { 0x03 };
  271. static const uint8_t smp_random_req_1[17] = { 0x04 };
  272. static const struct smp_req_rsp srv_basic_req_1[] = {
  273. { smp_basic_req_1, sizeof(smp_basic_req_1),
  274. smp_basic_req_1_rsp, sizeof(smp_basic_req_1_rsp) },
  275. { smp_confirm_req_1, sizeof(smp_confirm_req_1),
  276. smp_confirm_req_1, sizeof(smp_confirm_req_1) },
  277. { smp_random_req_1, sizeof(smp_random_req_1),
  278. smp_random_req_1, sizeof(smp_random_req_1) },
  279. };
  280. static const struct smp_data smp_server_basic_req_1_test = {
  281. .req = srv_basic_req_1,
  282. .req_count = G_N_ELEMENTS(srv_basic_req_1),
  283. };
  284. static const struct smp_req_rsp cli_basic_req_1[] = {
  285. { NULL, 0, smp_basic_req_1, sizeof(smp_basic_req_1) },
  286. { smp_basic_req_1_rsp, sizeof(smp_basic_req_1_rsp),
  287. smp_confirm_req_1, sizeof(smp_confirm_req_1) },
  288. { smp_confirm_req_1, sizeof(smp_confirm_req_1),
  289. smp_random_req_1, sizeof(smp_random_req_1) },
  290. { smp_random_req_1, sizeof(smp_random_req_1), NULL, 0 },
  291. };
  292. static const struct smp_data smp_client_basic_req_1_test = {
  293. .req = cli_basic_req_1,
  294. .req_count = G_N_ELEMENTS(cli_basic_req_1),
  295. };
  296. static const uint8_t smp_basic_req_2[] = { 0x01, /* Pairing Request */
  297. 0x04, /* NoInputNoOutput */
  298. 0x00, /* OOB Flag */
  299. 0x05, /* Bonding - MITM */
  300. 0x10, /* Max key size */
  301. 0x05, /* Init. key dist. */
  302. 0x05, /* Rsp. key dist. */
  303. };
  304. static const struct smp_req_rsp cli_basic_req_2[] = {
  305. { NULL, 0, smp_basic_req_2, sizeof(smp_basic_req_2) },
  306. { smp_basic_req_1_rsp, sizeof(smp_basic_req_1_rsp),
  307. smp_confirm_req_1, sizeof(smp_confirm_req_1) },
  308. { smp_confirm_req_1, sizeof(smp_confirm_req_1),
  309. smp_random_req_1, sizeof(smp_random_req_1) },
  310. { smp_random_req_1, sizeof(smp_random_req_1), NULL, 0 },
  311. };
  312. static const struct smp_data smp_client_basic_req_2_test = {
  313. .req = cli_basic_req_2,
  314. .req_count = G_N_ELEMENTS(cli_basic_req_1),
  315. .mitm = true,
  316. };
  317. static void user_confirm_request_callback(uint16_t index, uint16_t length,
  318. const void *param,
  319. void *user_data)
  320. {
  321. const struct mgmt_ev_user_confirm_request *ev = param;
  322. struct test_data *data = tester_get_data();
  323. struct mgmt_cp_user_confirm_reply cp;
  324. memset(&cp, 0, sizeof(cp));
  325. memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
  326. mgmt_reply(data->mgmt, MGMT_OP_USER_CONFIRM_REPLY,
  327. data->mgmt_index, sizeof(cp), &cp, NULL, NULL, NULL);
  328. }
  329. static const uint8_t smp_sc_req_1[] = { 0x01, /* Pairing Request */
  330. 0x03, /* NoInputNoOutput */
  331. 0x00, /* OOB Flag */
  332. 0x29, /* Bonding - no MITM, SC, CT2 */
  333. 0x10, /* Max key size */
  334. 0x0d, /* Init. key dist. */
  335. 0x0d, /* Rsp. key dist. */
  336. };
  337. static const struct smp_req_rsp cli_sc_req_1[] = {
  338. { NULL, 0, smp_sc_req_1, sizeof(smp_sc_req_1) },
  339. { smp_basic_req_1_rsp, sizeof(smp_basic_req_1_rsp),
  340. smp_confirm_req_1, sizeof(smp_confirm_req_1) },
  341. { smp_confirm_req_1, sizeof(smp_confirm_req_1),
  342. smp_random_req_1, sizeof(smp_random_req_1) },
  343. { smp_random_req_1, sizeof(smp_random_req_1), NULL, 0 },
  344. };
  345. static const struct smp_data smp_client_sc_req_1_test = {
  346. .req = cli_sc_req_1,
  347. .req_count = G_N_ELEMENTS(cli_sc_req_1),
  348. .sc = true,
  349. };
  350. static const uint8_t smp_sc_rsp_1[] = { 0x02, /* Pairing Response */
  351. 0x03, /* NoInputNoOutput */
  352. 0x00, /* OOB Flag */
  353. 0x09, /* Bonding - no MITM, SC */
  354. 0x10, /* Max key size */
  355. 0x0d, /* Init. key dist. */
  356. 0x0d, /* Rsp. key dist. */
  357. };
  358. static const uint8_t smp_sc_pk[65] = { 0x0c };
  359. static const struct smp_req_rsp cli_sc_req_2[] = {
  360. { NULL, 0, smp_sc_req_1, sizeof(smp_sc_req_1) },
  361. { smp_sc_rsp_1, sizeof(smp_sc_rsp_1), smp_sc_pk, sizeof(smp_sc_pk) },
  362. { smp_sc_pk, sizeof(smp_sc_pk), NULL, 0 },
  363. { smp_confirm_req_1, sizeof(smp_confirm_req_1),
  364. smp_random_req_1, sizeof(smp_random_req_1) },
  365. { smp_random_req_1, sizeof(smp_random_req_1), NULL, 0 },
  366. };
  367. static const struct smp_data smp_client_sc_req_2_test = {
  368. .req = cli_sc_req_2,
  369. .req_count = G_N_ELEMENTS(cli_sc_req_2),
  370. .sc = true,
  371. };
  372. static void client_connectable_complete(uint16_t opcode, uint8_t status,
  373. const void *param, uint8_t len,
  374. void *user_data)
  375. {
  376. if (opcode != BT_HCI_CMD_LE_SET_ADV_ENABLE)
  377. return;
  378. tester_print("Client set connectable status 0x%02x", status);
  379. if (status)
  380. tester_setup_failed();
  381. else
  382. tester_setup_complete();
  383. }
  384. static void setup_powered_client_callback(uint8_t status, uint16_t length,
  385. const void *param, void *user_data)
  386. {
  387. struct test_data *data = tester_get_data();
  388. struct bthost *bthost;
  389. if (status != MGMT_STATUS_SUCCESS) {
  390. tester_setup_failed();
  391. return;
  392. }
  393. tester_print("Controller powered on");
  394. bthost = hciemu_client_get_host(data->hciemu);
  395. bthost_set_cmd_complete_cb(bthost, client_connectable_complete, data);
  396. bthost_set_adv_enable(bthost, 0x01);
  397. }
  398. static void make_pk(struct test_data *data)
  399. {
  400. if (!ecc_make_key(data->local_pk, data->local_sk)) {
  401. tester_print("Failed to general local ECDH keypair");
  402. tester_setup_failed();
  403. return;
  404. }
  405. }
  406. static void setup_powered_client(const void *test_data)
  407. {
  408. struct test_data *data = tester_get_data();
  409. const struct smp_data *smp = data->test_data;
  410. unsigned char param[] = { 0x01 };
  411. mgmt_register(data->mgmt, MGMT_EV_USER_CONFIRM_REQUEST,
  412. data->mgmt_index, user_confirm_request_callback,
  413. data, NULL);
  414. tester_print("Powering on controller");
  415. mgmt_send(data->mgmt, MGMT_OP_SET_LE, data->mgmt_index,
  416. sizeof(param), param, NULL, NULL, NULL);
  417. mgmt_send(data->mgmt, MGMT_OP_SET_BONDABLE, data->mgmt_index,
  418. sizeof(param), param, NULL, NULL, NULL);
  419. if (smp->sc) {
  420. mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
  421. sizeof(param), param, NULL, NULL, NULL);
  422. mgmt_send(data->mgmt, MGMT_OP_SET_SECURE_CONN,
  423. data->mgmt_index, sizeof(param), param, NULL,
  424. NULL, NULL);
  425. make_pk(data);
  426. }
  427. mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
  428. sizeof(param), param, setup_powered_client_callback,
  429. NULL, NULL);
  430. }
  431. static void pair_device_complete(uint8_t status, uint16_t length,
  432. const void *param, void *user_data)
  433. {
  434. if (status != MGMT_STATUS_SUCCESS) {
  435. tester_warn("Pairing failed: %s", mgmt_errstr(status));
  436. return;
  437. }
  438. tester_print("Pairing succeedded");
  439. }
  440. static const void *get_pdu(const uint8_t *pdu)
  441. {
  442. struct test_data *data = tester_get_data();
  443. const struct smp_data *smp = data->test_data;
  444. uint8_t opcode = pdu[0];
  445. static uint8_t buf[65];
  446. switch (opcode) {
  447. case 0x01: /* Pairing Request */
  448. memcpy(data->preq, pdu, sizeof(data->preq));
  449. break;
  450. case 0x02: /* Pairing Response */
  451. memcpy(data->prsp, pdu, sizeof(data->prsp));
  452. break;
  453. case 0x03: /* Pairing Confirm */
  454. buf[0] = pdu[0];
  455. if (smp->sc)
  456. bt_crypto_f4(data->crypto, data->local_pk,
  457. data->remote_pk, data->prnd, 0,
  458. &buf[1]);
  459. else
  460. bt_crypto_c1(data->crypto, data->tk, data->prnd,
  461. data->prsp, data->preq, data->ia_type,
  462. data->ia, data->ra_type, data->ra,
  463. &buf[1]);
  464. return buf;
  465. case 0x04: /* Pairing Random */
  466. buf[0] = pdu[0];
  467. memcpy(&buf[1], data->prnd, 16);
  468. return buf;
  469. case 0x0c: /* Public Key */
  470. buf[0] = pdu[0];
  471. memcpy(&buf[1], data->local_pk, 64);
  472. return buf;
  473. default:
  474. break;
  475. }
  476. return pdu;
  477. }
  478. static bool verify_random(const uint8_t rnd[16])
  479. {
  480. struct test_data *data = tester_get_data();
  481. uint8_t confirm[16];
  482. if (!bt_crypto_c1(data->crypto, data->tk, data->rrnd, data->prsp,
  483. data->preq, data->ia_type, data->ia,
  484. data->ra_type, data->ra, confirm))
  485. return false;
  486. if (memcmp(data->pcnf, confirm, sizeof(data->pcnf)) != 0) {
  487. tester_warn("Confirmation values don't match");
  488. return false;
  489. }
  490. if (data->out) {
  491. struct bthost *bthost = hciemu_client_get_host(data->hciemu);
  492. bt_crypto_s1(data->crypto, data->tk, data->rrnd, data->prnd,
  493. data->ltk);
  494. bthost_le_start_encrypt(bthost, data->handle, data->ltk);
  495. } else {
  496. bt_crypto_s1(data->crypto, data->tk, data->prnd, data->rrnd,
  497. data->ltk);
  498. }
  499. return true;
  500. }
  501. static bool sc_random(struct test_data *test_data)
  502. {
  503. return true;
  504. }
  505. static void smp_server(const void *data, uint16_t len, void *user_data)
  506. {
  507. struct test_data *test_data = user_data;
  508. struct bthost *bthost = hciemu_client_get_host(test_data->hciemu);
  509. const struct smp_data *smp = test_data->test_data;
  510. const struct smp_req_rsp *req;
  511. uint8_t opcode;
  512. const void *pdu;
  513. if (len < 1) {
  514. tester_warn("Received too small SMP PDU");
  515. goto failed;
  516. }
  517. opcode = *((const uint8_t *) data);
  518. tester_print("Received SMP opcode 0x%02x", opcode);
  519. if (test_data->counter >= smp->req_count) {
  520. test_condition_complete(test_data);
  521. return;
  522. }
  523. req = &smp->req[test_data->counter++];
  524. if (!req->expect)
  525. goto next;
  526. if (req->expect_len != len) {
  527. tester_warn("Unexpected SMP PDU length (%u != %u)",
  528. len, req->expect_len);
  529. goto failed;
  530. }
  531. switch (opcode) {
  532. case 0x01: /* Pairing Request */
  533. memcpy(test_data->preq, data, sizeof(test_data->preq));
  534. break;
  535. case 0x02: /* Pairing Response */
  536. memcpy(test_data->prsp, data, sizeof(test_data->prsp));
  537. break;
  538. case 0x03: /* Pairing Confirm */
  539. memcpy(test_data->pcnf, data + 1, 16);
  540. goto next;
  541. case 0x04: /* Pairing Random */
  542. memcpy(test_data->rrnd, data + 1, 16);
  543. if (smp->sc) {
  544. if (!sc_random(test_data))
  545. goto failed;
  546. } else {
  547. if (!verify_random(data + 1))
  548. goto failed;
  549. }
  550. goto next;
  551. case 0x0c: /* Public Key */
  552. memcpy(test_data->remote_pk, data + 1, 64);
  553. ecdh_shared_secret(test_data->remote_pk, test_data->local_sk,
  554. test_data->dhkey);
  555. goto next;
  556. default:
  557. break;
  558. }
  559. if (memcmp(req->expect, data, len) != 0) {
  560. tester_warn("Unexpected SMP PDU");
  561. goto failed;
  562. }
  563. next:
  564. while (true) {
  565. if (smp->req_count == test_data->counter) {
  566. test_condition_complete(test_data);
  567. break;
  568. }
  569. req = &smp->req[test_data->counter];
  570. pdu = get_pdu(req->send);
  571. bthost_send_cid(bthost, test_data->handle, SMP_CID, pdu,
  572. req->send_len);
  573. if (req->expect)
  574. break;
  575. else
  576. test_data->counter++;
  577. }
  578. return;
  579. failed:
  580. tester_test_failed();
  581. }
  582. static void command_hci_callback(uint16_t opcode, const void *param,
  583. uint8_t length, void *user_data)
  584. {
  585. struct test_data *data = user_data;
  586. const struct smp_data *smp = data->test_data;
  587. const void *expect_hci_param = smp->expect_hci_param;
  588. uint8_t expect_hci_len = smp->expect_hci_len;
  589. tester_print("HCI Command 0x%04x length %u", opcode, length);
  590. if (opcode != smp->expect_hci_command)
  591. return;
  592. if (smp->expect_hci_func)
  593. expect_hci_param = smp->expect_hci_func(&expect_hci_len);
  594. if (length != expect_hci_len) {
  595. tester_warn("Invalid parameter size for HCI command");
  596. tester_test_failed();
  597. return;
  598. }
  599. if (memcmp(param, expect_hci_param, length) != 0) {
  600. tester_warn("Unexpected HCI command parameter value");
  601. tester_test_failed();
  602. return;
  603. }
  604. test_condition_complete(data);
  605. }
  606. static void smp_new_conn(uint16_t handle, void *user_data)
  607. {
  608. struct test_data *data = user_data;
  609. const struct smp_data *smp = data->test_data;
  610. struct bthost *bthost = hciemu_client_get_host(data->hciemu);
  611. const struct smp_req_rsp *req;
  612. const void *pdu;
  613. tester_print("New SMP client connection with handle 0x%04x", handle);
  614. data->handle = handle;
  615. bthost_add_cid_hook(bthost, handle, SMP_CID, smp_server, data);
  616. if (smp->req_count == data->counter)
  617. return;
  618. req = &smp->req[data->counter];
  619. if (!req->send)
  620. return;
  621. tester_print("Sending SMP PDU");
  622. pdu = get_pdu(req->send);
  623. bthost_send_cid(bthost, handle, SMP_CID, pdu, req->send_len);
  624. if (!req->expect)
  625. test_condition_complete(data);
  626. }
  627. static void init_bdaddr(struct test_data *data)
  628. {
  629. const uint8_t *central_bdaddr, *client_bdaddr;
  630. central_bdaddr = hciemu_get_central_bdaddr(data->hciemu);
  631. if (!central_bdaddr) {
  632. tester_warn("No central bdaddr");
  633. tester_test_failed();
  634. return;
  635. }
  636. client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
  637. if (!client_bdaddr) {
  638. tester_warn("No client bdaddr");
  639. tester_test_failed();
  640. return;
  641. }
  642. data->ia_type = LE_PUBLIC_ADDRESS;
  643. data->ra_type = LE_PUBLIC_ADDRESS;
  644. if (data->out) {
  645. memcpy(data->ia, client_bdaddr, sizeof(data->ia));
  646. memcpy(data->ra, central_bdaddr, sizeof(data->ra));
  647. } else {
  648. memcpy(data->ia, central_bdaddr, sizeof(data->ia));
  649. memcpy(data->ra, client_bdaddr, sizeof(data->ra));
  650. }
  651. }
  652. static void test_client(const void *test_data)
  653. {
  654. struct test_data *data = tester_get_data();
  655. const struct smp_data *smp = data->test_data;
  656. struct mgmt_cp_pair_device cp;
  657. struct bthost *bthost;
  658. init_bdaddr(data);
  659. bthost = hciemu_client_get_host(data->hciemu);
  660. bthost_set_connect_cb(bthost, smp_new_conn, data);
  661. test_add_condition(data);
  662. if (smp->expect_hci_command) {
  663. tester_print("Registering HCI command callback");
  664. hciemu_add_central_post_command_hook(data->hciemu,
  665. command_hci_callback, data);
  666. test_add_condition(data);
  667. }
  668. memcpy(&cp.addr.bdaddr, data->ra, sizeof(data->ra));
  669. cp.addr.type = BDADDR_LE_PUBLIC;
  670. if (smp->mitm)
  671. cp.io_cap = 0x04; /* KeyboardDisplay */
  672. else
  673. cp.io_cap = 0x03; /* NoInputNoOutput */
  674. mgmt_send(data->mgmt, MGMT_OP_PAIR_DEVICE, data->mgmt_index,
  675. sizeof(cp), &cp, pair_device_complete, NULL, NULL);
  676. tester_print("Pairing in progress");
  677. }
  678. static void setup_powered_server_callback(uint8_t status, uint16_t length,
  679. const void *param, void *user_data)
  680. {
  681. if (status != MGMT_STATUS_SUCCESS) {
  682. tester_setup_failed();
  683. return;
  684. }
  685. tester_print("Controller powered on");
  686. tester_setup_complete();
  687. }
  688. static void setup_powered_server(const void *test_data)
  689. {
  690. struct test_data *data = tester_get_data();
  691. const struct smp_data *smp = data->test_data;
  692. unsigned char param[] = { 0x01 };
  693. mgmt_register(data->mgmt, MGMT_EV_USER_CONFIRM_REQUEST,
  694. data->mgmt_index, user_confirm_request_callback,
  695. data, NULL);
  696. tester_print("Powering on controller");
  697. mgmt_send(data->mgmt, MGMT_OP_SET_LE, data->mgmt_index,
  698. sizeof(param), param, NULL, NULL, NULL);
  699. mgmt_send(data->mgmt, MGMT_OP_SET_BONDABLE, data->mgmt_index,
  700. sizeof(param), param, NULL, NULL, NULL);
  701. mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
  702. sizeof(param), param, NULL, NULL, NULL);
  703. mgmt_send(data->mgmt, MGMT_OP_SET_ADVERTISING, data->mgmt_index,
  704. sizeof(param), param, NULL, NULL, NULL);
  705. if (smp->sc) {
  706. mgmt_send(data->mgmt, MGMT_OP_SET_SECURE_CONN,
  707. data->mgmt_index, sizeof(param), param, NULL,
  708. NULL, NULL);
  709. make_pk(data);
  710. }
  711. mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
  712. sizeof(param), param, setup_powered_server_callback,
  713. NULL, NULL);
  714. }
  715. static void test_server(const void *test_data)
  716. {
  717. struct test_data *data = tester_get_data();
  718. const struct smp_data *smp = data->test_data;
  719. struct bthost *bthost;
  720. data->out = true;
  721. init_bdaddr(data);
  722. bthost = hciemu_client_get_host(data->hciemu);
  723. bthost_set_connect_cb(bthost, smp_new_conn, data);
  724. test_add_condition(data);
  725. bthost_hci_connect(bthost, data->ra, BDADDR_LE_PUBLIC);
  726. if (smp->expect_hci_command) {
  727. tester_print("Registering HCI command callback");
  728. hciemu_add_central_post_command_hook(data->hciemu,
  729. command_hci_callback, data);
  730. test_add_condition(data);
  731. }
  732. }
  733. int main(int argc, char *argv[])
  734. {
  735. tester_init(&argc, &argv);
  736. test_smp("SMP Server - Basic Request 1",
  737. &smp_server_basic_req_1_test,
  738. setup_powered_server, test_server);
  739. test_smp("SMP Server - Invalid Request 1",
  740. &smp_server_nval_req_1_test,
  741. setup_powered_server, test_server);
  742. test_smp("SMP Server - Invalid Request 2",
  743. &smp_server_nval_req_2_test,
  744. setup_powered_server, test_server);
  745. test_smp("SMP Server - Invalid Request 3",
  746. &smp_server_nval_req_3_test,
  747. setup_powered_server, test_server);
  748. test_smp("SMP Client - Basic Request 1",
  749. &smp_client_basic_req_1_test,
  750. setup_powered_client, test_client);
  751. test_smp("SMP Client - Basic Request 2",
  752. &smp_client_basic_req_2_test,
  753. setup_powered_client, test_client);
  754. test_smp("SMP Client - SC Request 1",
  755. &smp_client_sc_req_1_test,
  756. setup_powered_client, test_client);
  757. test_smp("SMP Client - SC Request 2",
  758. &smp_client_sc_req_2_test,
  759. setup_powered_client, test_client);
  760. return tester_run();
  761. }