dpp_supplicant.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. /*
  2. * wpa_supplicant - DPP
  3. * Copyright (c) 2017, Qualcomm Atheros, Inc.
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "common/dpp.h"
  12. #include "wpa_supplicant_i.h"
  13. #include "driver_i.h"
  14. #include "offchannel.h"
  15. #include "dpp_supplicant.h"
  16. static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
  17. unsigned int freq);
  18. static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
  19. unsigned int freq, const u8 *dst,
  20. const u8 *src, const u8 *bssid,
  21. const u8 *data, size_t data_len,
  22. enum offchannel_send_action_result result);
  23. static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  24. static unsigned int wpas_dpp_next_id(struct wpa_supplicant *wpa_s)
  25. {
  26. struct dpp_bootstrap_info *bi;
  27. unsigned int max_id = 0;
  28. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  29. list) {
  30. if (bi->id > max_id)
  31. max_id = bi->id;
  32. }
  33. return max_id + 1;
  34. }
  35. /**
  36. * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
  37. * @wpa_s: Pointer to wpa_supplicant data
  38. * @cmd: DPP URI read from a QR Code
  39. * Returns: Identifier of the stored info or -1 on failure
  40. */
  41. int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
  42. {
  43. struct dpp_bootstrap_info *bi;
  44. struct dpp_authentication *auth = wpa_s->dpp_auth;
  45. bi = dpp_parse_qr_code(cmd);
  46. if (!bi)
  47. return -1;
  48. bi->id = wpas_dpp_next_id(wpa_s);
  49. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  50. if (auth && auth->response_pending &&
  51. dpp_notify_new_qr_code(auth, bi) == 1) {
  52. struct wpabuf *msg;
  53. wpa_printf(MSG_DEBUG,
  54. "DPP: Sending out pending authentication response");
  55. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
  56. wpabuf_len(auth->resp_attr));
  57. if (!msg)
  58. goto out;
  59. wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
  60. offchannel_send_action(wpa_s, auth->curr_freq,
  61. auth->peer_mac_addr, wpa_s->own_addr,
  62. broadcast,
  63. wpabuf_head(msg), wpabuf_len(msg),
  64. 500, wpas_dpp_tx_status, 0);
  65. wpabuf_free(msg);
  66. }
  67. out:
  68. return bi->id;
  69. }
  70. static char * get_param(const char *cmd, const char *param)
  71. {
  72. const char *pos, *end;
  73. char *val;
  74. size_t len;
  75. pos = os_strstr(cmd, param);
  76. if (!pos)
  77. return NULL;
  78. pos += os_strlen(param);
  79. end = os_strchr(pos, ' ');
  80. if (end)
  81. len = end - pos;
  82. else
  83. len = os_strlen(pos);
  84. val = os_malloc(len + 1);
  85. if (!val)
  86. return NULL;
  87. os_memcpy(val, pos, len);
  88. val[len] = '\0';
  89. return val;
  90. }
  91. int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd)
  92. {
  93. char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL;
  94. char *key = NULL;
  95. u8 *privkey = NULL;
  96. size_t privkey_len = 0;
  97. size_t len;
  98. int ret = -1;
  99. struct dpp_bootstrap_info *bi;
  100. bi = os_zalloc(sizeof(*bi));
  101. if (!bi)
  102. goto fail;
  103. if (os_strstr(cmd, "type=qrcode"))
  104. bi->type = DPP_BOOTSTRAP_QR_CODE;
  105. else
  106. goto fail;
  107. chan = get_param(cmd, " chan=");
  108. mac = get_param(cmd, " mac=");
  109. info = get_param(cmd, " info=");
  110. curve = get_param(cmd, " curve=");
  111. key = get_param(cmd, " key=");
  112. if (key) {
  113. privkey_len = os_strlen(key) / 2;
  114. privkey = os_malloc(privkey_len);
  115. if (!privkey ||
  116. hexstr2bin(key, privkey, privkey_len) < 0)
  117. goto fail;
  118. }
  119. pk = dpp_keygen(bi, curve, privkey, privkey_len);
  120. if (!pk)
  121. goto fail;
  122. len = 4; /* "DPP:" */
  123. if (chan) {
  124. if (dpp_parse_uri_chan_list(bi, chan) < 0)
  125. goto fail;
  126. len += 3 + os_strlen(chan); /* C:...; */
  127. }
  128. if (mac) {
  129. if (dpp_parse_uri_mac(bi, mac) < 0)
  130. goto fail;
  131. len += 3 + os_strlen(mac); /* M:...; */
  132. }
  133. if (info) {
  134. if (dpp_parse_uri_info(bi, info) < 0)
  135. goto fail;
  136. len += 3 + os_strlen(info); /* I:...; */
  137. }
  138. len += 4 + os_strlen(pk);
  139. bi->uri = os_malloc(len + 1);
  140. if (!bi->uri)
  141. goto fail;
  142. os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
  143. chan ? "C:" : "", chan ? chan : "", chan ? ";" : "",
  144. mac ? "M:" : "", mac ? mac : "", mac ? ";" : "",
  145. info ? "I:" : "", info ? info : "", info ? ";" : "",
  146. pk);
  147. bi->id = wpas_dpp_next_id(wpa_s);
  148. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  149. ret = bi->id;
  150. bi = NULL;
  151. fail:
  152. os_free(curve);
  153. os_free(pk);
  154. os_free(chan);
  155. os_free(mac);
  156. os_free(info);
  157. str_clear_free(key);
  158. bin_clear_free(privkey, privkey_len);
  159. dpp_bootstrap_info_free(bi);
  160. return ret;
  161. }
  162. static struct dpp_bootstrap_info *
  163. dpp_bootstrap_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
  164. {
  165. struct dpp_bootstrap_info *bi;
  166. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  167. list) {
  168. if (bi->id == id)
  169. return bi;
  170. }
  171. return NULL;
  172. }
  173. static int dpp_bootstrap_del(struct wpa_supplicant *wpa_s, unsigned int id)
  174. {
  175. struct dpp_bootstrap_info *bi, *tmp;
  176. int found = 0;
  177. dl_list_for_each_safe(bi, tmp, &wpa_s->dpp_bootstrap,
  178. struct dpp_bootstrap_info, list) {
  179. if (id && bi->id != id)
  180. continue;
  181. found = 1;
  182. dl_list_del(&bi->list);
  183. dpp_bootstrap_info_free(bi);
  184. }
  185. if (id == 0)
  186. return 0; /* flush succeeds regardless of entries found */
  187. return found ? 0 : -1;
  188. }
  189. int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id)
  190. {
  191. unsigned int id_val;
  192. if (os_strcmp(id, "*") == 0) {
  193. id_val = 0;
  194. } else {
  195. id_val = atoi(id);
  196. if (id_val == 0)
  197. return -1;
  198. }
  199. return dpp_bootstrap_del(wpa_s, id_val);
  200. }
  201. const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
  202. unsigned int id)
  203. {
  204. struct dpp_bootstrap_info *bi;
  205. bi = dpp_bootstrap_get_id(wpa_s, id);
  206. if (!bi)
  207. return NULL;
  208. return bi->uri;
  209. }
  210. static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
  211. unsigned int freq, const u8 *dst,
  212. const u8 *src, const u8 *bssid,
  213. const u8 *data, size_t data_len,
  214. enum offchannel_send_action_result result)
  215. {
  216. wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
  217. " result=%s",
  218. freq, MAC2STR(dst),
  219. result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
  220. (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
  221. "FAILED"));
  222. if (!wpa_s->dpp_auth) {
  223. wpa_printf(MSG_DEBUG,
  224. "DPP: Ignore TX status since there is no ongoing authentication exchange");
  225. return;
  226. }
  227. if (wpa_s->dpp_auth->remove_on_tx_status) {
  228. wpa_printf(MSG_DEBUG,
  229. "DPP: Terminate authentication exchange due to an earlier error");
  230. dpp_auth_deinit(wpa_s->dpp_auth);
  231. wpa_s->dpp_auth = NULL;
  232. return;
  233. }
  234. if (!is_broadcast_ether_addr(dst) &&
  235. result != OFFCHANNEL_SEND_ACTION_SUCCESS) {
  236. wpa_printf(MSG_DEBUG,
  237. "DPP: Unicast DPP Action frame was not ACKed");
  238. /* TODO: In case of DPP Authentication Request frame, move to
  239. * the next channel immediately */
  240. }
  241. }
  242. static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
  243. {
  244. struct wpa_supplicant *wpa_s = eloop_ctx;
  245. if (!wpa_s->dpp_auth)
  246. return;
  247. wpa_printf(MSG_DEBUG, "DPP: Continue reply wait on channel %u MHz",
  248. wpa_s->dpp_auth->curr_freq);
  249. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
  250. }
  251. int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
  252. {
  253. const char *pos;
  254. struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
  255. struct wpabuf *msg;
  256. const u8 *dst;
  257. int res;
  258. int configurator = 1;
  259. unsigned int wait_time;
  260. pos = os_strstr(cmd, " peer=");
  261. if (!pos)
  262. return -1;
  263. pos += 6;
  264. peer_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  265. if (!peer_bi) {
  266. wpa_printf(MSG_INFO,
  267. "DPP: Could not find bootstrapping info for the identified peer");
  268. return -1;
  269. }
  270. pos = os_strstr(cmd, " own=");
  271. if (pos) {
  272. pos += 5;
  273. own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  274. if (!own_bi) {
  275. wpa_printf(MSG_INFO,
  276. "DPP: Could not find bootstrapping info for the identified local entry");
  277. return -1;
  278. }
  279. if (peer_bi->curve != own_bi->curve) {
  280. wpa_printf(MSG_INFO,
  281. "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
  282. peer_bi->curve->name, own_bi->curve->name);
  283. return -1;
  284. }
  285. }
  286. pos = os_strstr(cmd, " role=");
  287. if (pos) {
  288. pos += 6;
  289. if (os_strncmp(pos, "configurator", 12) == 0)
  290. configurator = 1;
  291. else if (os_strncmp(pos, "enrollee", 8) == 0)
  292. configurator = 0;
  293. else
  294. return -1;
  295. }
  296. if (wpa_s->dpp_auth) {
  297. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  298. offchannel_send_action_done(wpa_s);
  299. dpp_auth_deinit(wpa_s->dpp_auth);
  300. }
  301. wpa_s->dpp_auth = dpp_auth_init(wpa_s, peer_bi, own_bi, configurator);
  302. if (!wpa_s->dpp_auth)
  303. return -1;
  304. /* TODO: Support iteration over all frequencies and filtering of
  305. * frequencies based on locally enabled channels that allow initiation
  306. * of transmission. */
  307. if (peer_bi->num_freq > 0)
  308. wpa_s->dpp_auth->curr_freq = peer_bi->freq[0];
  309. else
  310. wpa_s->dpp_auth->curr_freq = 2412;
  311. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ,
  312. wpabuf_len(wpa_s->dpp_auth->req_attr));
  313. if (!msg)
  314. return -1;
  315. wpabuf_put_buf(msg, wpa_s->dpp_auth->req_attr);
  316. if (is_zero_ether_addr(peer_bi->mac_addr)) {
  317. dst = broadcast;
  318. } else {
  319. dst = peer_bi->mac_addr;
  320. os_memcpy(wpa_s->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
  321. ETH_ALEN);
  322. }
  323. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  324. wait_time = wpa_s->max_remain_on_chan;
  325. if (wait_time > 2000)
  326. wait_time = 2000;
  327. eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
  328. wpas_dpp_reply_wait_timeout,
  329. wpa_s, NULL);
  330. res = offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
  331. dst, wpa_s->own_addr, broadcast,
  332. wpabuf_head(msg), wpabuf_len(msg),
  333. wait_time, wpas_dpp_tx_status, 0);
  334. wpabuf_free(msg);
  335. return res;
  336. }
  337. struct wpas_dpp_listen_work {
  338. unsigned int freq;
  339. unsigned int duration;
  340. struct wpabuf *probe_resp_ie;
  341. };
  342. static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work *lwork)
  343. {
  344. if (!lwork)
  345. return;
  346. os_free(lwork);
  347. }
  348. static void wpas_dpp_listen_work_done(struct wpa_supplicant *wpa_s)
  349. {
  350. struct wpas_dpp_listen_work *lwork;
  351. if (!wpa_s->dpp_listen_work)
  352. return;
  353. lwork = wpa_s->dpp_listen_work->ctx;
  354. wpas_dpp_listen_work_free(lwork);
  355. radio_work_done(wpa_s->dpp_listen_work);
  356. wpa_s->dpp_listen_work = NULL;
  357. }
  358. static void dpp_start_listen_cb(struct wpa_radio_work *work, int deinit)
  359. {
  360. struct wpa_supplicant *wpa_s = work->wpa_s;
  361. struct wpas_dpp_listen_work *lwork = work->ctx;
  362. if (deinit) {
  363. if (work->started) {
  364. wpa_s->dpp_listen_work = NULL;
  365. wpas_dpp_listen_stop(wpa_s);
  366. }
  367. wpas_dpp_listen_work_free(lwork);
  368. return;
  369. }
  370. wpa_s->dpp_listen_work = work;
  371. wpa_s->dpp_pending_listen_freq = lwork->freq;
  372. if (wpa_drv_remain_on_channel(wpa_s, lwork->freq,
  373. wpa_s->max_remain_on_chan) < 0) {
  374. wpa_printf(MSG_DEBUG,
  375. "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
  376. lwork->freq);
  377. wpas_dpp_listen_work_done(wpa_s);
  378. wpa_s->dpp_pending_listen_freq = 0;
  379. return;
  380. }
  381. wpa_s->off_channel_freq = 0;
  382. wpa_s->roc_waiting_drv_freq = lwork->freq;
  383. }
  384. static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
  385. unsigned int freq)
  386. {
  387. struct wpas_dpp_listen_work *lwork;
  388. if (wpa_s->dpp_listen_work) {
  389. wpa_printf(MSG_DEBUG,
  390. "DPP: Reject start_listen since dpp_listen_work already exists");
  391. return -1;
  392. }
  393. if (wpa_s->dpp_listen_freq)
  394. wpas_dpp_listen_stop(wpa_s);
  395. wpa_s->dpp_listen_freq = freq;
  396. lwork = os_zalloc(sizeof(*lwork));
  397. if (!lwork)
  398. return -1;
  399. lwork->freq = freq;
  400. if (radio_add_work(wpa_s, freq, "dpp-listen", 0, dpp_start_listen_cb,
  401. lwork) < 0) {
  402. wpas_dpp_listen_work_free(lwork);
  403. return -1;
  404. }
  405. return 0;
  406. }
  407. int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd)
  408. {
  409. int freq;
  410. freq = atoi(cmd);
  411. if (freq <= 0)
  412. return -1;
  413. if (os_strstr(cmd, " role=configurator"))
  414. wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
  415. else if (os_strstr(cmd, " role=enrollee"))
  416. wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
  417. else
  418. wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
  419. DPP_CAPAB_ENROLLEE;
  420. wpa_s->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
  421. if (wpa_s->dpp_listen_freq == (unsigned int) freq) {
  422. wpa_printf(MSG_DEBUG, "DPP: Already listening on %u MHz",
  423. freq);
  424. return 0;
  425. }
  426. return wpas_dpp_listen_start(wpa_s, freq);
  427. }
  428. void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s)
  429. {
  430. if (!wpa_s->dpp_listen_freq)
  431. return;
  432. wpa_printf(MSG_DEBUG, "DPP: Stop listen on %u MHz",
  433. wpa_s->dpp_listen_freq);
  434. wpa_drv_cancel_remain_on_channel(wpa_s);
  435. wpa_s->dpp_listen_freq = 0;
  436. wpas_dpp_listen_work_done(wpa_s);
  437. }
  438. void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
  439. unsigned int freq)
  440. {
  441. if (!wpa_s->dpp_listen_freq && !wpa_s->dpp_pending_listen_freq)
  442. return;
  443. wpa_printf(MSG_DEBUG,
  444. "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
  445. wpa_s->off_channel_freq, wpa_s->dpp_pending_listen_freq,
  446. wpa_s->roc_waiting_drv_freq, freq);
  447. if (wpa_s->off_channel_freq &&
  448. wpa_s->off_channel_freq == wpa_s->dpp_pending_listen_freq) {
  449. wpa_printf(MSG_DEBUG, "DPP: Listen on %u MHz started", freq);
  450. wpa_s->dpp_pending_listen_freq = 0;
  451. } else {
  452. wpa_printf(MSG_DEBUG,
  453. "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
  454. wpa_s->off_channel_freq,
  455. wpa_s->dpp_pending_listen_freq, freq);
  456. }
  457. }
  458. void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
  459. unsigned int freq)
  460. {
  461. wpas_dpp_listen_work_done(wpa_s);
  462. if (wpa_s->dpp_auth) {
  463. /* Continue listen with a new remain-on-channel */
  464. wpa_printf(MSG_DEBUG,
  465. "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
  466. wpa_s->dpp_auth->curr_freq);
  467. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
  468. return;
  469. }
  470. if (wpa_s->dpp_listen_freq) {
  471. /* Continue listen with a new remain-on-channel */
  472. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_listen_freq);
  473. }
  474. }
  475. static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
  476. const u8 *buf, size_t len, unsigned int freq)
  477. {
  478. const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
  479. u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
  480. struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
  481. struct wpabuf *msg;
  482. wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
  483. MAC2STR(src));
  484. wrapped_data = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
  485. &wrapped_data_len);
  486. if (!wrapped_data) {
  487. wpa_printf(MSG_DEBUG,
  488. "DPP: Missing required Wrapped data attribute");
  489. return;
  490. }
  491. wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped data",
  492. wrapped_data, wrapped_data_len);
  493. r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
  494. &r_bootstrap_len);
  495. if (!r_bootstrap || r_bootstrap > wrapped_data ||
  496. r_bootstrap_len != SHA256_MAC_LEN) {
  497. wpa_printf(MSG_DEBUG,
  498. "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
  499. return;
  500. }
  501. wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
  502. r_bootstrap, r_bootstrap_len);
  503. i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
  504. &i_bootstrap_len);
  505. if (!i_bootstrap || i_bootstrap > wrapped_data ||
  506. i_bootstrap_len != SHA256_MAC_LEN) {
  507. wpa_printf(MSG_DEBUG,
  508. "DPP: Missing or invalid required Initiator Bootstrapping Key Hash attribute");
  509. return;
  510. }
  511. wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
  512. i_bootstrap, i_bootstrap_len);
  513. /* Try to find own and peer bootstrapping key matches based on the
  514. * received hash values */
  515. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  516. list) {
  517. if (!own_bi && bi->own &&
  518. os_memcmp(bi->pubkey_hash, r_bootstrap,
  519. SHA256_MAC_LEN) == 0) {
  520. wpa_printf(MSG_DEBUG,
  521. "DPP: Found matching own bootstrapping information");
  522. own_bi = bi;
  523. }
  524. if (!peer_bi && !bi->own &&
  525. os_memcmp(bi->pubkey_hash, i_bootstrap,
  526. SHA256_MAC_LEN) == 0) {
  527. wpa_printf(MSG_DEBUG,
  528. "DPP: Found matching peer bootstrapping information");
  529. peer_bi = bi;
  530. }
  531. if (own_bi && peer_bi)
  532. break;
  533. }
  534. if (!own_bi) {
  535. wpa_printf(MSG_DEBUG,
  536. "DPP: No matching own bootstrapping key found - ignore message");
  537. return;
  538. }
  539. if (wpa_s->dpp_auth) {
  540. wpa_printf(MSG_DEBUG,
  541. "DPP: Already in DPP authentication exchange - ignore new one");
  542. return;
  543. }
  544. wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s, wpa_s->dpp_allowed_roles,
  545. wpa_s->dpp_qr_mutual,
  546. peer_bi, own_bi, freq, buf,
  547. wrapped_data, wrapped_data_len);
  548. if (!wpa_s->dpp_auth) {
  549. wpa_printf(MSG_DEBUG, "DPP: No response generated");
  550. return;
  551. }
  552. os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN);
  553. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
  554. wpabuf_len(wpa_s->dpp_auth->resp_attr));
  555. if (!msg)
  556. return;
  557. wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
  558. offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
  559. src, wpa_s->own_addr, broadcast,
  560. wpabuf_head(msg), wpabuf_len(msg),
  561. 500, wpas_dpp_tx_status, 0);
  562. wpabuf_free(msg);
  563. }
  564. static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
  565. const u8 *buf, size_t len)
  566. {
  567. struct dpp_authentication *auth = wpa_s->dpp_auth;
  568. struct wpabuf *msg, *attr;
  569. wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
  570. MAC2STR(src));
  571. if (!auth) {
  572. wpa_printf(MSG_DEBUG,
  573. "DPP: No DPP Authentication in progress - drop");
  574. return;
  575. }
  576. if (!is_zero_ether_addr(auth->peer_mac_addr) &&
  577. os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
  578. wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
  579. MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
  580. return;
  581. }
  582. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  583. attr = dpp_auth_resp_rx(auth, buf, len);
  584. if (!attr) {
  585. if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
  586. wpa_printf(MSG_DEBUG,
  587. "DPP: Start wait for full response");
  588. offchannel_send_action_done(wpa_s);
  589. wpas_dpp_listen_start(wpa_s, auth->curr_freq);
  590. return;
  591. }
  592. wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
  593. return;
  594. }
  595. os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
  596. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, wpabuf_len(attr));
  597. if (!msg) {
  598. wpabuf_free(attr);
  599. return;
  600. }
  601. wpabuf_put_buf(msg, attr);
  602. wpabuf_free(attr);
  603. offchannel_send_action(wpa_s, auth->curr_freq,
  604. src, wpa_s->own_addr, broadcast,
  605. wpabuf_head(msg), wpabuf_len(msg),
  606. 500, wpas_dpp_tx_status, 0);
  607. wpabuf_free(msg);
  608. wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
  609. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=1");
  610. }
  611. static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
  612. const u8 *buf, size_t len)
  613. {
  614. struct dpp_authentication *auth = wpa_s->dpp_auth;
  615. wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
  616. MAC2STR(src));
  617. if (!auth) {
  618. wpa_printf(MSG_DEBUG,
  619. "DPP: No DPP Authentication in progress - drop");
  620. return;
  621. }
  622. if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
  623. wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
  624. MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
  625. return;
  626. }
  627. if (dpp_auth_conf_rx(auth, buf, len) < 0) {
  628. wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
  629. return;
  630. }
  631. wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
  632. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=0");
  633. }
  634. void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
  635. const u8 *buf, size_t len, unsigned int freq)
  636. {
  637. enum dpp_public_action_frame_type type;
  638. if (len < 1)
  639. return;
  640. type = buf[0];
  641. buf++;
  642. len--;
  643. wpa_printf(MSG_DEBUG,
  644. "DPP: Received DPP Public Action frame type %d from "
  645. MACSTR " freq=%u",
  646. type, MAC2STR(src), freq);
  647. wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
  648. if (dpp_check_attrs(buf, len) < 0)
  649. return;
  650. switch (type) {
  651. case DPP_PA_AUTHENTICATION_REQ:
  652. wpas_dpp_rx_auth_req(wpa_s, src, buf, len, freq);
  653. break;
  654. case DPP_PA_AUTHENTICATION_RESP:
  655. wpas_dpp_rx_auth_resp(wpa_s, src, buf, len);
  656. break;
  657. case DPP_PA_AUTHENTICATION_CONF:
  658. wpas_dpp_rx_auth_conf(wpa_s, src, buf, len);
  659. break;
  660. default:
  661. wpa_printf(MSG_DEBUG,
  662. "DPP: Ignored unsupported frame subtype %d", type);
  663. break;
  664. }
  665. }
  666. int wpas_dpp_init(struct wpa_supplicant *wpa_s)
  667. {
  668. dl_list_init(&wpa_s->dpp_bootstrap);
  669. wpa_s->dpp_init_done = 1;
  670. return 0;
  671. }
  672. void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
  673. {
  674. if (!wpa_s->dpp_init_done)
  675. return;
  676. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  677. offchannel_send_action_done(wpa_s);
  678. wpas_dpp_listen_stop(wpa_s);
  679. dpp_bootstrap_del(wpa_s, 0);
  680. dpp_auth_deinit(wpa_s->dpp_auth);
  681. wpa_s->dpp_auth = NULL;
  682. }