prov-initiator.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2018-2019 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <ell/ell.h>
  14. #include "src/shared/ecc.h"
  15. #include "mesh/mesh-defs.h"
  16. #include "mesh/util.h"
  17. #include "mesh/crypto.h"
  18. #include "mesh/net.h"
  19. #include "mesh/node.h"
  20. #include "mesh/keyring.h"
  21. #include "mesh/prov.h"
  22. #include "mesh/provision.h"
  23. #include "mesh/pb-adv.h"
  24. #include "mesh/mesh.h"
  25. #include "mesh/agent.h"
  26. #include "mesh/error.h"
  27. #define MIN(x, y) ((x) < (y) ? (x) : (y))
  28. /* Quick size sanity check */
  29. static const uint16_t expected_pdu_size[] = {
  30. 2, /* PROV_INVITE */
  31. 12, /* PROV_CAPS */
  32. 6, /* PROV_START */
  33. 65, /* PROV_PUB_KEY */
  34. 1, /* PROV_INP_CMPLT */
  35. 17, /* PROV_CONFIRM */
  36. 17, /* PROV_RANDOM */
  37. 34, /* PROV_DATA */
  38. 1, /* PROV_COMPLETE */
  39. 2, /* PROV_FAILED */
  40. };
  41. #define BEACON_TYPE_UNPROVISIONED 0x00
  42. static const uint8_t pkt_filter = MESH_AD_TYPE_PROVISION;
  43. enum int_state {
  44. INT_PROV_IDLE = 0,
  45. INT_PROV_INVITE_SENT,
  46. INT_PROV_INVITE_ACKED,
  47. INT_PROV_START_SENT,
  48. INT_PROV_START_ACKED,
  49. INT_PROV_KEY_SENT,
  50. INT_PROV_KEY_ACKED,
  51. INT_PROV_CONF_SENT,
  52. INT_PROV_CONF_ACKED,
  53. INT_PROV_RAND_SENT,
  54. INT_PROV_RAND_ACKED,
  55. INT_PROV_DATA_SENT,
  56. INT_PROV_DATA_ACKED,
  57. };
  58. #define MAT_REMOTE_PUBLIC 0x01
  59. #define MAT_LOCAL_PRIVATE 0x02
  60. #define MAT_RAND_AUTH 0x04
  61. #define MAT_SECRET (MAT_REMOTE_PUBLIC | MAT_LOCAL_PRIVATE)
  62. struct mesh_prov_initiator {
  63. mesh_prov_initiator_start_func_t start_cb;
  64. mesh_prov_initiator_complete_func_t complete_cb;
  65. mesh_prov_initiator_data_req_func_t data_req_cb;
  66. prov_trans_tx_t trans_tx;
  67. struct mesh_agent *agent;
  68. void *caller_data;
  69. void *trans_data;
  70. struct mesh_node *node;
  71. struct l_timeout *timeout;
  72. uint32_t to_secs;
  73. enum int_state state;
  74. enum trans_type transport;
  75. uint16_t net_idx;
  76. uint16_t unicast;
  77. uint8_t material;
  78. uint8_t expected;
  79. int8_t previous;
  80. struct conf_input conf_inputs;
  81. uint8_t calc_key[16];
  82. uint8_t salt[16];
  83. uint8_t confirm[16];
  84. uint8_t s_key[16];
  85. uint8_t s_nonce[13];
  86. uint8_t private_key[32];
  87. uint8_t secret[32];
  88. uint8_t rand_auth_workspace[48];
  89. uint8_t uuid[16];
  90. };
  91. static struct mesh_prov_initiator *prov = NULL;
  92. static void initiator_free(void)
  93. {
  94. if (prov)
  95. l_timeout_remove(prov->timeout);
  96. mesh_send_cancel(&pkt_filter, sizeof(pkt_filter));
  97. pb_adv_unreg(prov);
  98. l_free(prov);
  99. prov = NULL;
  100. }
  101. static void int_prov_close(void *user_data, uint8_t reason)
  102. {
  103. struct mesh_prov_initiator *prov = user_data;
  104. struct mesh_prov_node_info info;
  105. if (reason != PROV_ERR_SUCCESS) {
  106. prov->complete_cb(prov->caller_data, reason, NULL);
  107. initiator_free();
  108. return;
  109. }
  110. memcpy(info.device_key, prov->calc_key, 16);
  111. info.net_index = prov->net_idx;
  112. info.unicast = prov->unicast;
  113. info.num_ele = prov->conf_inputs.caps.num_ele;
  114. prov->complete_cb(prov->caller_data, PROV_ERR_SUCCESS, &info);
  115. initiator_free();
  116. }
  117. static void swap_u256_bytes(uint8_t *u256)
  118. {
  119. int i;
  120. /* End-to-End byte reflection of 32 octet buffer */
  121. for (i = 0; i < 16; i++) {
  122. u256[i] ^= u256[31 - i];
  123. u256[31 - i] ^= u256[i];
  124. u256[i] ^= u256[31 - i];
  125. }
  126. }
  127. static void int_prov_open(void *user_data, prov_trans_tx_t trans_tx,
  128. void *trans_data, uint8_t transport)
  129. {
  130. struct mesh_prov_initiator *rx_prov = user_data;
  131. struct prov_invite_msg msg = { PROV_INVITE, { 30 }};
  132. /* Only one provisioning session may be open at a time */
  133. if (rx_prov != prov)
  134. return;
  135. /* Only one provisioning session may be open at a time */
  136. if (prov->trans_tx && prov->trans_tx != trans_tx &&
  137. prov->transport != transport)
  138. return;
  139. /* We only care here if transport does *not* match */
  140. if (transport != prov->transport)
  141. return;
  142. /* Always use an ephemeral key when Initiator */
  143. ecc_make_key(prov->conf_inputs.prv_pub_key, prov->private_key);
  144. swap_u256_bytes(prov->conf_inputs.prv_pub_key);
  145. swap_u256_bytes(prov->conf_inputs.prv_pub_key + 32);
  146. prov->material |= MAT_LOCAL_PRIVATE;
  147. prov->trans_tx = trans_tx;
  148. prov->trans_data = trans_data;
  149. prov->state = INT_PROV_INVITE_SENT;
  150. prov->expected = PROV_CAPS;
  151. prov->conf_inputs.invite.attention = msg.invite.attention;
  152. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  153. return;
  154. }
  155. static bool prov_calc_secret(const uint8_t *pub, const uint8_t *priv,
  156. uint8_t *secret)
  157. {
  158. uint8_t tmp[64];
  159. /* Convert to ECC byte order */
  160. memcpy(tmp, pub, 64);
  161. swap_u256_bytes(tmp);
  162. swap_u256_bytes(tmp + 32);
  163. if (!ecdh_shared_secret(tmp, priv, secret))
  164. return false;
  165. /* Convert to Mesh byte order */
  166. swap_u256_bytes(secret);
  167. return true;
  168. }
  169. static bool int_credentials(struct mesh_prov_initiator *prov)
  170. {
  171. if (!memcmp(prov->conf_inputs.prv_pub_key,
  172. prov->conf_inputs.dev_pub_key, 64))
  173. return false;
  174. if (!prov_calc_secret(prov->conf_inputs.dev_pub_key,
  175. prov->private_key, prov->secret))
  176. return false;
  177. if (!mesh_crypto_s1(&prov->conf_inputs,
  178. sizeof(prov->conf_inputs), prov->salt))
  179. return false;
  180. if (!mesh_crypto_prov_conf_key(prov->secret, prov->salt,
  181. prov->calc_key))
  182. return false;
  183. l_getrandom(prov->rand_auth_workspace, 16);
  184. print_packet("PublicKeyProv", prov->conf_inputs.prv_pub_key, 64);
  185. print_packet("PublicKeyDev", prov->conf_inputs.dev_pub_key, 64);
  186. /* Print DBG out in Mesh order */
  187. swap_u256_bytes(prov->private_key);
  188. print_packet("PrivateKeyLocal", prov->private_key, 32);
  189. print_packet("ConfirmationInputs", &prov->conf_inputs,
  190. sizeof(prov->conf_inputs));
  191. print_packet("ECDHSecret", prov->secret, 32);
  192. print_packet("LocalRandom", prov->rand_auth_workspace, 16);
  193. print_packet("ConfirmationSalt", prov->salt, 16);
  194. print_packet("ConfirmationKey", prov->calc_key, 16);
  195. return true;
  196. }
  197. static uint8_t u16_high_bit(uint16_t mask)
  198. {
  199. uint8_t cnt = 0;
  200. if (!mask)
  201. return 0xff;
  202. while (mask & 0xfffe) {
  203. cnt++;
  204. mask >>= 1;
  205. }
  206. return cnt;
  207. }
  208. static uint32_t digit_mod(uint8_t power)
  209. {
  210. uint32_t ret = 1;
  211. while (power--)
  212. ret *= 10;
  213. return ret;
  214. }
  215. static void calc_local_material(const uint8_t *random)
  216. {
  217. /* Calculate SessionKey while the data is fresh */
  218. mesh_crypto_prov_prov_salt(prov->salt,
  219. prov->rand_auth_workspace, random,
  220. prov->salt);
  221. mesh_crypto_session_key(prov->secret, prov->salt,
  222. prov->s_key);
  223. mesh_crypto_nonce(prov->secret, prov->salt, prov->s_nonce);
  224. print_packet("SessionKey", prov->s_key, sizeof(prov->s_key));
  225. print_packet("Nonce", prov->s_nonce, sizeof(prov->s_nonce));
  226. }
  227. static void send_confirm(struct mesh_prov_initiator *prov)
  228. {
  229. struct prov_conf_msg msg;
  230. msg.opcode = PROV_CONFIRM;
  231. mesh_crypto_aes_cmac(prov->calc_key, prov->rand_auth_workspace,
  232. 32, msg.conf);
  233. memcpy(prov->confirm, msg.conf, sizeof(prov->confirm));
  234. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  235. prov->state = INT_PROV_CONF_SENT;
  236. prov->expected = PROV_CONFIRM;
  237. }
  238. static void number_cb(void *user_data, int err, uint32_t number)
  239. {
  240. struct mesh_prov_initiator *rx_prov = user_data;
  241. struct prov_fail_msg msg;
  242. if (prov != rx_prov)
  243. return;
  244. if (err) {
  245. msg.opcode = PROV_FAILED;
  246. msg.reason = PROV_ERR_UNEXPECTED_ERR;
  247. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  248. return;
  249. }
  250. /* Save two copies, to generate two confirmation values */
  251. l_put_be32(number, prov->rand_auth_workspace + 28);
  252. l_put_be32(number, prov->rand_auth_workspace + 44);
  253. prov->material |= MAT_RAND_AUTH;
  254. send_confirm(prov);
  255. }
  256. static void static_cb(void *user_data, int err, uint8_t *key, uint32_t len)
  257. {
  258. struct mesh_prov_initiator *rx_prov = user_data;
  259. struct prov_fail_msg msg;
  260. if (prov != rx_prov)
  261. return;
  262. if (err || !key || len != 16) {
  263. msg.opcode = PROV_FAILED;
  264. msg.reason = PROV_ERR_UNEXPECTED_ERR;
  265. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  266. return;
  267. }
  268. memcpy(prov->rand_auth_workspace + 16, key, 16);
  269. memcpy(prov->rand_auth_workspace + 32, key, 16);
  270. prov->material |= MAT_RAND_AUTH;
  271. send_confirm(prov);
  272. }
  273. static void send_pub_key(struct mesh_prov_initiator *prov)
  274. {
  275. struct prov_pub_key_msg msg;
  276. msg.opcode = PROV_PUB_KEY;
  277. memcpy(msg.pub_key, prov->conf_inputs.prv_pub_key, 64);
  278. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  279. prov->state = INT_PROV_KEY_SENT;
  280. }
  281. static void pub_key_cb(void *user_data, int err, uint8_t *key, uint32_t len)
  282. {
  283. struct mesh_prov_initiator *rx_prov = user_data;
  284. struct prov_fail_msg msg;
  285. uint8_t fail_code[2];
  286. if (prov != rx_prov)
  287. return;
  288. if (err || !key || len != 64) {
  289. msg.opcode = PROV_FAILED;
  290. msg.reason = PROV_ERR_UNEXPECTED_ERR;
  291. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  292. return;
  293. }
  294. memcpy(prov->conf_inputs.dev_pub_key, key, 64);
  295. prov->material |= MAT_REMOTE_PUBLIC;
  296. if ((prov->material & MAT_SECRET) == MAT_SECRET) {
  297. if (!int_credentials(prov)) {
  298. fail_code[0] = PROV_FAILED;
  299. fail_code[1] = PROV_ERR_UNEXPECTED_ERR;
  300. prov->trans_tx(prov->trans_data, fail_code, 2);
  301. int_prov_close(prov, fail_code[1]);
  302. return;
  303. }
  304. }
  305. send_pub_key(prov);
  306. }
  307. static void send_random(struct mesh_prov_initiator *prov)
  308. {
  309. struct prov_rand_msg msg;
  310. msg.opcode = PROV_RANDOM;
  311. memcpy(msg.rand, prov->rand_auth_workspace, sizeof(msg.rand));
  312. prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
  313. prov->state = INT_PROV_RAND_SENT;
  314. prov->expected = PROV_RANDOM;
  315. }
  316. void initiator_prov_data(uint16_t net_idx, uint16_t primary, void *caller_data)
  317. {
  318. struct prov_data_msg prov_data;
  319. struct prov_fail_msg prov_fail;
  320. struct keyring_net_key key;
  321. struct mesh_net *net;
  322. uint32_t iv_index;
  323. uint8_t snb_flags;
  324. if (!prov || caller_data != prov->caller_data)
  325. return;
  326. if (prov->state != INT_PROV_RAND_ACKED)
  327. return;
  328. net = node_get_net(prov->node);
  329. prov->expected = PROV_COMPLETE;
  330. /* Calculate remote device key */
  331. mesh_crypto_device_key(prov->secret,
  332. prov->salt,
  333. prov->calc_key);
  334. print_packet("DevKey", prov->calc_key, 16);
  335. /* Fill Prov Data Structure */
  336. if (!keyring_get_net_key(prov->node, net_idx, &key)) {
  337. prov_fail.reason = PROV_ERR_UNEXPECTED_ERR;
  338. goto failure;
  339. }
  340. prov->unicast = primary;
  341. prov->net_idx = net_idx;
  342. mesh_net_get_snb_state(net, &snb_flags, &iv_index);
  343. prov_data.opcode = PROV_DATA;
  344. if (key.phase == KEY_REFRESH_PHASE_TWO) {
  345. memcpy(&prov_data.data.net_key, key.new_key, 16);
  346. snb_flags |= PROV_FLAG_KR;
  347. } else
  348. memcpy(&prov_data.data.net_key, key.old_key, 16);
  349. l_put_be16(net_idx, &prov_data.data.net_idx);
  350. l_put_u8(snb_flags, &prov_data.data.flags);
  351. l_put_be32(iv_index, &prov_data.data.iv_index);
  352. l_put_be16(primary, &prov_data.data.primary);
  353. print_packet("ProvData", &prov_data.data, sizeof(prov_data.data));
  354. /* Encrypt Prov Data */
  355. mesh_crypto_aes_ccm_encrypt(prov->s_nonce, prov->s_key,
  356. NULL, 0,
  357. &prov_data.data,
  358. sizeof(prov_data.data),
  359. &prov_data.data,
  360. NULL, sizeof(prov_data.mic));
  361. print_packet("EncdData", &prov_data.data, sizeof(prov_data) - 1);
  362. prov->trans_tx(prov->trans_data, &prov_data, sizeof(prov_data));
  363. prov->state = INT_PROV_DATA_SENT;
  364. return;
  365. failure:
  366. l_debug("Failing... %d", prov_fail.reason);
  367. prov_fail.opcode = PROV_FAILED;
  368. prov->trans_tx(prov->trans_data, &prov_fail, sizeof(prov_fail));
  369. /* TODO: Call Complete Callback (Fail)*/
  370. }
  371. static void get_random_key(struct mesh_prov_initiator *prov, uint8_t action,
  372. uint8_t size)
  373. {
  374. uint32_t oob_key;
  375. int i;
  376. if (action >= PROV_ACTION_IN_ALPHA) {
  377. uint8_t alpha;
  378. char tmp[17];
  379. memset(tmp, 0, sizeof(tmp));
  380. if (size > 16)
  381. size = 16;
  382. /* Create random alphanumeric string made of 0-9, a-z, A-Z */
  383. for (i = 0; i < size; i++) {
  384. l_getrandom(&alpha, sizeof(alpha));
  385. alpha %= (10 + 26 + 26);
  386. if (alpha < 10)
  387. alpha += '0';
  388. else if (alpha < 10 + 26)
  389. alpha += 'a' - 10;
  390. else
  391. alpha += 'A' - 10 - 26;
  392. tmp[i] = (char) alpha;
  393. }
  394. memcpy(prov->rand_auth_workspace + 16, tmp, size);
  395. memcpy(prov->rand_auth_workspace + 32, tmp, size);
  396. return;
  397. }
  398. l_getrandom(&oob_key, sizeof(oob_key));
  399. if (action <= PROV_ACTION_TWIST)
  400. oob_key %= size;
  401. else
  402. oob_key %= digit_mod(size);
  403. if (!oob_key)
  404. oob_key = size;
  405. /* Save two copies, for two confirmation values */
  406. l_put_be32(oob_key, prov->rand_auth_workspace + 28);
  407. l_put_be32(oob_key, prov->rand_auth_workspace + 44);
  408. }
  409. static void int_prov_auth(void)
  410. {
  411. uint8_t fail_code[2];
  412. uint32_t oob_key;
  413. prov->state = INT_PROV_KEY_ACKED;
  414. l_debug("auth_method: %d", prov->conf_inputs.start.auth_method);
  415. memset(prov->rand_auth_workspace + 16, 0, 32);
  416. switch (prov->conf_inputs.start.auth_method) {
  417. default:
  418. case 0:
  419. /* Auth Type 3c - No OOB */
  420. prov->material |= MAT_RAND_AUTH;
  421. break;
  422. case 1:
  423. /* Auth Type 3c - Static OOB */
  424. /* Prompt Agent for Static OOB */
  425. fail_code[1] = mesh_agent_request_static(prov->agent,
  426. static_cb, prov);
  427. if (fail_code[1])
  428. goto failure;
  429. break;
  430. case 2:
  431. /* Auth Type 3a - Output OOB */
  432. /* Prompt Agent for Output OOB */
  433. if (prov->conf_inputs.start.auth_action ==
  434. PROV_ACTION_OUT_ALPHA) {
  435. fail_code[1] = mesh_agent_prompt_alpha(
  436. prov->agent, true,
  437. static_cb, prov);
  438. } else {
  439. fail_code[1] = mesh_agent_prompt_number(
  440. prov->agent, true,
  441. prov->conf_inputs.start.auth_action,
  442. number_cb, prov);
  443. }
  444. if (fail_code[1])
  445. goto failure;
  446. break;
  447. case 3:
  448. /* Auth Type 3b - input OOB */
  449. get_random_key(prov,
  450. prov->conf_inputs.start.auth_action,
  451. prov->conf_inputs.start.auth_size);
  452. oob_key = l_get_be32(prov->rand_auth_workspace + 28);
  453. /* Ask Agent to Display random key */
  454. if (prov->conf_inputs.start.auth_action ==
  455. PROV_ACTION_IN_ALPHA) {
  456. fail_code[1] = mesh_agent_display_string(
  457. prov->agent,
  458. (char *) prov->rand_auth_workspace + 16,
  459. NULL, prov);
  460. } else {
  461. fail_code[1] = mesh_agent_display_number(
  462. prov->agent, true,
  463. prov->conf_inputs.start.auth_action,
  464. oob_key, NULL, prov);
  465. }
  466. if (fail_code[1])
  467. goto failure;
  468. break;
  469. }
  470. if (prov->material & MAT_RAND_AUTH)
  471. send_confirm(prov);
  472. return;
  473. failure:
  474. l_debug("Failing... %d", fail_code[1]);
  475. fail_code[0] = PROV_FAILED;
  476. prov->trans_tx(prov->trans_data, fail_code, 2);
  477. int_prov_close(prov, fail_code[1]);
  478. }
  479. static void int_prov_start_auth(const struct mesh_agent_prov_caps *prov_caps,
  480. const struct mesh_net_prov_caps *dev_caps,
  481. struct prov_start *start)
  482. {
  483. uint8_t pub_type = prov_caps->pub_type & dev_caps->pub_type;
  484. uint8_t static_type = prov_caps->static_type & dev_caps->static_type;
  485. uint16_t output_action = prov_caps->output_action &
  486. L_BE16_TO_CPU(dev_caps->output_action);
  487. uint8_t output_size = MIN(prov_caps->output_size,
  488. dev_caps->output_size);
  489. uint16_t input_action = prov_caps->input_action &
  490. L_BE16_TO_CPU(dev_caps->input_action);
  491. uint8_t input_size = MIN(prov_caps->input_size, dev_caps->input_size);
  492. if (pub_type)
  493. start->pub_key = 0x01;
  494. /* Parse OOB Options, prefer static, then out, then in */
  495. if (static_type) {
  496. start->auth_method = 0x01;
  497. return;
  498. }
  499. if (output_size && output_action) {
  500. start->auth_method = 0x02;
  501. start->auth_action = u16_high_bit(output_action);
  502. start->auth_size = MIN(output_size, 8);
  503. return;
  504. }
  505. if (input_size && input_action) {
  506. start->auth_method = 0x03;
  507. start->auth_action = u16_high_bit(input_action);
  508. start->auth_size = MIN(input_size, 8);
  509. return;
  510. }
  511. }
  512. static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
  513. {
  514. struct mesh_prov_initiator *rx_prov = user_data;
  515. uint8_t *out;
  516. uint8_t type = *data++;
  517. uint8_t fail_code[2];
  518. if (rx_prov != prov || !prov->trans_tx)
  519. return;
  520. l_debug("Provisioning packet received type: %2.2x (%u octets)",
  521. type, len);
  522. if (type == prov->previous) {
  523. l_error("Ignore repeated %2.2x packet", type);
  524. return;
  525. } else if (type > prov->expected || type < prov->previous) {
  526. l_error("Expected %2.2x, Got:%2.2x", prov->expected, type);
  527. fail_code[1] = PROV_ERR_UNEXPECTED_PDU;
  528. goto failure;
  529. }
  530. if (type >= L_ARRAY_SIZE(expected_pdu_size) ||
  531. len != expected_pdu_size[type]) {
  532. l_error("Expected PDU size %d, Got %d (type: %2.2x)",
  533. len, expected_pdu_size[type], type);
  534. fail_code[1] = PROV_ERR_INVALID_FORMAT;
  535. goto failure;
  536. }
  537. switch (type) {
  538. case PROV_CAPS: /* Capabilities */
  539. prov->state = INT_PROV_INVITE_ACKED;
  540. memcpy(&prov->conf_inputs.caps, data,
  541. sizeof(prov->conf_inputs.caps));
  542. l_debug("Got Num Ele %d", data[0]);
  543. l_debug("Got alg %4.4x", l_get_be16(data + 1));
  544. l_debug("Got pub_type %d", data[3]);
  545. l_debug("Got static_type %d", data[4]);
  546. l_debug("Got output_size %d", data[5]);
  547. l_debug("Got output_action %d", l_get_be16(data + 6));
  548. l_debug("Got input_size %d", data[8]);
  549. l_debug("Got input_action %d", l_get_be16(data + 9));
  550. if (!(l_get_be16(data + 1) & 0x0001)) {
  551. l_error("Unsupported Algorithm");
  552. fail_code[1] = PROV_ERR_INVALID_FORMAT;
  553. goto failure;
  554. }
  555. /*
  556. * Select auth mechanism from methods supported by both
  557. * parties.
  558. */
  559. int_prov_start_auth(mesh_agent_get_caps(prov->agent),
  560. &prov->conf_inputs.caps,
  561. &prov->conf_inputs.start);
  562. if (prov->conf_inputs.start.pub_key == 0x01) {
  563. prov->expected = PROV_CONFIRM;
  564. /* Prompt Agent for remote Public Key */
  565. mesh_agent_request_public_key(prov->agent,
  566. pub_key_cb, prov);
  567. /* Nothing else for us to do now */
  568. } else
  569. prov->expected = PROV_PUB_KEY;
  570. out = l_malloc(1 + sizeof(prov->conf_inputs.start));
  571. out[0] = PROV_START;
  572. memcpy(out + 1, &prov->conf_inputs.start,
  573. sizeof(prov->conf_inputs.start));
  574. prov->state = INT_PROV_START_SENT;
  575. prov->trans_tx(prov->trans_data, out,
  576. sizeof(prov->conf_inputs.start) + 1);
  577. l_free(out);
  578. break;
  579. case PROV_PUB_KEY: /* Public Key */
  580. /* If we expected Pub Key Out-Of-Band, then fail */
  581. if (prov->conf_inputs.start.pub_key) {
  582. fail_code[1] = PROV_ERR_INVALID_PDU;
  583. goto failure;
  584. }
  585. memcpy(prov->conf_inputs.dev_pub_key, data, 64);
  586. prov->material |= MAT_REMOTE_PUBLIC;
  587. prov->expected = PROV_CONFIRM;
  588. if ((prov->material & MAT_SECRET) != MAT_SECRET)
  589. return;
  590. if (!int_credentials(prov)) {
  591. fail_code[1] = PROV_ERR_UNEXPECTED_ERR;
  592. goto failure;
  593. }
  594. int_prov_auth();
  595. break;
  596. case PROV_INP_CMPLT: /* Provisioning Input Complete */
  597. /* TODO: Cancel Agent prompt */
  598. prov->material |= MAT_RAND_AUTH;
  599. send_confirm(prov);
  600. break;
  601. case PROV_CONFIRM: /* Confirmation */
  602. prov->state = INT_PROV_CONF_ACKED;
  603. /* RXed Device Confirmation */
  604. /* Disallow echoed values */
  605. if (!memcmp(prov->confirm, data, 16)) {
  606. fail_code[1] = PROV_ERR_INVALID_PDU;
  607. goto failure;
  608. }
  609. memcpy(prov->confirm, data, 16);
  610. print_packet("ConfirmationDevice", prov->confirm, 16);
  611. send_random(prov);
  612. break;
  613. case PROV_RANDOM: /* Random */
  614. prov->state = INT_PROV_RAND_ACKED;
  615. /* Disallow matching random values */
  616. if (!memcmp(prov->rand_auth_workspace, data, 16)) {
  617. fail_code[1] = PROV_ERR_INVALID_PDU;
  618. goto failure;
  619. }
  620. /* RXed Device Confirmation */
  621. calc_local_material(data);
  622. memcpy(prov->rand_auth_workspace + 16, data, 16);
  623. print_packet("RandomDevice", data, 16);
  624. mesh_crypto_aes_cmac(prov->calc_key,
  625. prov->rand_auth_workspace + 16,
  626. 32, prov->rand_auth_workspace);
  627. print_packet("Dev-Conf", prov->rand_auth_workspace, 16);
  628. if (memcmp(prov->rand_auth_workspace, prov->confirm, 16)) {
  629. l_error("Provisioning Failed-Confirm compare");
  630. fail_code[1] = PROV_ERR_CONFIRM_FAILED;
  631. goto failure;
  632. }
  633. if (!prov->data_req_cb(prov->caller_data,
  634. prov->conf_inputs.caps.num_ele)) {
  635. l_error("Provisioning Failed-Data Get");
  636. fail_code[1] = PROV_ERR_CANT_ASSIGN_ADDR;
  637. goto failure;
  638. }
  639. break;
  640. case PROV_COMPLETE: /* Complete */
  641. l_debug("Provisioning Complete");
  642. prov->state = INT_PROV_IDLE;
  643. int_prov_close(prov, PROV_ERR_SUCCESS);
  644. break;
  645. case PROV_FAILED: /* Failed */
  646. l_error("Provisioning Failed (reason: %d)", data[0]);
  647. prov->state = INT_PROV_IDLE;
  648. int_prov_close(prov, data[0]);
  649. break;
  650. default:
  651. l_error("Unknown Pkt %2.2x", type);
  652. fail_code[1] = PROV_ERR_UNEXPECTED_PDU;
  653. goto failure;
  654. }
  655. if (prov)
  656. prov->previous = type;
  657. return;
  658. failure:
  659. l_debug("Failing... %d", fail_code[1]);
  660. fail_code[0] = PROV_FAILED;
  661. prov->trans_tx(prov->trans_data, fail_code, 2);
  662. int_prov_close(prov, fail_code[1]);
  663. }
  664. static void int_prov_ack(void *user_data, uint8_t msg_num)
  665. {
  666. struct mesh_prov_initiator *rx_prov = user_data;
  667. if (rx_prov != prov || !prov->trans_tx)
  668. return;
  669. switch (prov->state) {
  670. case INT_PROV_START_SENT:
  671. prov->state = INT_PROV_START_ACKED;
  672. if (!prov->conf_inputs.start.pub_key)
  673. send_pub_key(prov);
  674. break;
  675. case INT_PROV_DATA_SENT:
  676. prov->state = INT_PROV_DATA_ACKED;
  677. break;
  678. case INT_PROV_KEY_SENT:
  679. if (prov->conf_inputs.start.pub_key)
  680. int_prov_auth();
  681. break;
  682. case INT_PROV_IDLE:
  683. case INT_PROV_INVITE_SENT:
  684. case INT_PROV_INVITE_ACKED:
  685. case INT_PROV_START_ACKED:
  686. case INT_PROV_KEY_ACKED:
  687. case INT_PROV_CONF_SENT:
  688. case INT_PROV_CONF_ACKED:
  689. case INT_PROV_RAND_SENT:
  690. case INT_PROV_RAND_ACKED:
  691. case INT_PROV_DATA_ACKED:
  692. default:
  693. break;
  694. }
  695. }
  696. static void initiator_open_cb(void *user_data, int err)
  697. {
  698. bool result;
  699. if (!prov)
  700. return;
  701. if (err != MESH_ERROR_NONE)
  702. goto fail;
  703. /* Always register for PB-ADV */
  704. result = pb_adv_reg(true, int_prov_open, int_prov_close, int_prov_rx,
  705. int_prov_ack, prov->uuid, prov);
  706. if (!result) {
  707. err = MESH_ERROR_FAILED;
  708. goto fail;
  709. }
  710. if (!prov)
  711. return;
  712. prov->start_cb(prov->caller_data, MESH_ERROR_NONE);
  713. return;
  714. fail:
  715. prov->start_cb(prov->caller_data, err);
  716. initiator_free();
  717. }
  718. bool initiator_start(enum trans_type transport,
  719. uint8_t uuid[16],
  720. uint16_t max_ele,
  721. uint32_t timeout, /* in seconds from mesh.conf */
  722. struct mesh_agent *agent,
  723. mesh_prov_initiator_start_func_t start_cb,
  724. mesh_prov_initiator_data_req_func_t data_req_cb,
  725. mesh_prov_initiator_complete_func_t complete_cb,
  726. void *node, void *caller_data)
  727. {
  728. /* Invoked from Add() method in mesh-api.txt, to add a
  729. * remote unprovisioned device network.
  730. */
  731. if (prov)
  732. return false;
  733. prov = l_new(struct mesh_prov_initiator, 1);
  734. prov->to_secs = timeout;
  735. prov->node = node;
  736. prov->agent = agent;
  737. prov->complete_cb = complete_cb;
  738. prov->start_cb = start_cb;
  739. prov->data_req_cb = data_req_cb;
  740. prov->caller_data = caller_data;
  741. prov->previous = -1;
  742. memcpy(prov->uuid, uuid, 16);
  743. mesh_agent_refresh(prov->agent, initiator_open_cb, prov);
  744. return true;
  745. }
  746. void initiator_cancel(void *user_data)
  747. {
  748. initiator_free();
  749. }