wps_enrollee.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. /*
  2. * Wi-Fi Protected Setup - Enrollee
  3. * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "crypto/crypto.h"
  17. #include "crypto/sha256.h"
  18. #include "wps_i.h"
  19. #include "wps_dev_attr.h"
  20. static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
  21. {
  22. wpa_printf(MSG_DEBUG, "WPS: * MAC Address");
  23. wpabuf_put_be16(msg, ATTR_MAC_ADDR);
  24. wpabuf_put_be16(msg, ETH_ALEN);
  25. wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
  26. return 0;
  27. }
  28. static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
  29. {
  30. u8 state;
  31. if (wps->wps->ap)
  32. state = wps->wps->wps_state;
  33. else
  34. state = WPS_STATE_NOT_CONFIGURED;
  35. wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)",
  36. state);
  37. wpabuf_put_be16(msg, ATTR_WPS_STATE);
  38. wpabuf_put_be16(msg, 1);
  39. wpabuf_put_u8(msg, state);
  40. return 0;
  41. }
  42. static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
  43. {
  44. u8 *hash;
  45. const u8 *addr[4];
  46. size_t len[4];
  47. if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
  48. return -1;
  49. wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
  50. wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
  51. wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
  52. if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
  53. wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
  54. "E-Hash derivation");
  55. return -1;
  56. }
  57. wpa_printf(MSG_DEBUG, "WPS: * E-Hash1");
  58. wpabuf_put_be16(msg, ATTR_E_HASH1);
  59. wpabuf_put_be16(msg, SHA256_MAC_LEN);
  60. hash = wpabuf_put(msg, SHA256_MAC_LEN);
  61. /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
  62. addr[0] = wps->snonce;
  63. len[0] = WPS_SECRET_NONCE_LEN;
  64. addr[1] = wps->psk1;
  65. len[1] = WPS_PSK_LEN;
  66. addr[2] = wpabuf_head(wps->dh_pubkey_e);
  67. len[2] = wpabuf_len(wps->dh_pubkey_e);
  68. addr[3] = wpabuf_head(wps->dh_pubkey_r);
  69. len[3] = wpabuf_len(wps->dh_pubkey_r);
  70. hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
  71. wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
  72. wpa_printf(MSG_DEBUG, "WPS: * E-Hash2");
  73. wpabuf_put_be16(msg, ATTR_E_HASH2);
  74. wpabuf_put_be16(msg, SHA256_MAC_LEN);
  75. hash = wpabuf_put(msg, SHA256_MAC_LEN);
  76. /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
  77. addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
  78. addr[1] = wps->psk2;
  79. hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
  80. wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
  81. return 0;
  82. }
  83. static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
  84. {
  85. wpa_printf(MSG_DEBUG, "WPS: * E-SNonce1");
  86. wpabuf_put_be16(msg, ATTR_E_SNONCE1);
  87. wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
  88. wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
  89. return 0;
  90. }
  91. static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
  92. {
  93. wpa_printf(MSG_DEBUG, "WPS: * E-SNonce2");
  94. wpabuf_put_be16(msg, ATTR_E_SNONCE2);
  95. wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
  96. wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
  97. WPS_SECRET_NONCE_LEN);
  98. return 0;
  99. }
  100. static struct wpabuf * wps_build_m1(struct wps_data *wps)
  101. {
  102. struct wpabuf *msg;
  103. if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
  104. return NULL;
  105. wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
  106. wps->nonce_e, WPS_NONCE_LEN);
  107. wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
  108. msg = wpabuf_alloc(1000);
  109. if (msg == NULL)
  110. return NULL;
  111. if (wps_build_version(msg) ||
  112. wps_build_msg_type(msg, WPS_M1) ||
  113. wps_build_uuid_e(msg, wps->uuid_e) ||
  114. wps_build_mac_addr(wps, msg) ||
  115. wps_build_enrollee_nonce(wps, msg) ||
  116. wps_build_public_key(wps, msg) ||
  117. wps_build_auth_type_flags(wps, msg) ||
  118. wps_build_encr_type_flags(wps, msg) ||
  119. wps_build_conn_type_flags(wps, msg) ||
  120. wps_build_config_methods(msg, wps->wps->config_methods) ||
  121. wps_build_wps_state(wps, msg) ||
  122. wps_build_device_attrs(&wps->wps->dev, msg) ||
  123. wps_build_rf_bands(&wps->wps->dev, msg) ||
  124. wps_build_assoc_state(wps, msg) ||
  125. wps_build_dev_password_id(msg, wps->dev_pw_id) ||
  126. wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
  127. wps_build_os_version(&wps->wps->dev, msg) ||
  128. wps_build_version2(msg)) {
  129. wpabuf_free(msg);
  130. return NULL;
  131. }
  132. wps->state = RECV_M2;
  133. return msg;
  134. }
  135. static struct wpabuf * wps_build_m3(struct wps_data *wps)
  136. {
  137. struct wpabuf *msg;
  138. wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
  139. if (wps->dev_password == NULL) {
  140. wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
  141. return NULL;
  142. }
  143. wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
  144. msg = wpabuf_alloc(1000);
  145. if (msg == NULL)
  146. return NULL;
  147. if (wps_build_version(msg) ||
  148. wps_build_msg_type(msg, WPS_M3) ||
  149. wps_build_registrar_nonce(wps, msg) ||
  150. wps_build_e_hash(wps, msg) ||
  151. wps_build_version2(msg) ||
  152. wps_build_authenticator(wps, msg)) {
  153. wpabuf_free(msg);
  154. return NULL;
  155. }
  156. wps->state = RECV_M4;
  157. return msg;
  158. }
  159. static struct wpabuf * wps_build_m5(struct wps_data *wps)
  160. {
  161. struct wpabuf *msg, *plain;
  162. wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
  163. plain = wpabuf_alloc(200);
  164. if (plain == NULL)
  165. return NULL;
  166. msg = wpabuf_alloc(1000);
  167. if (msg == NULL) {
  168. wpabuf_free(plain);
  169. return NULL;
  170. }
  171. if (wps_build_version(msg) ||
  172. wps_build_msg_type(msg, WPS_M5) ||
  173. wps_build_registrar_nonce(wps, msg) ||
  174. wps_build_e_snonce1(wps, plain) ||
  175. wps_build_key_wrap_auth(wps, plain) ||
  176. wps_build_encr_settings(wps, msg, plain) ||
  177. wps_build_version2(msg) ||
  178. wps_build_authenticator(wps, msg)) {
  179. wpabuf_free(plain);
  180. wpabuf_free(msg);
  181. return NULL;
  182. }
  183. wpabuf_free(plain);
  184. wps->state = RECV_M6;
  185. return msg;
  186. }
  187. static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
  188. {
  189. wpa_printf(MSG_DEBUG, "WPS: * SSID");
  190. wpabuf_put_be16(msg, ATTR_SSID);
  191. wpabuf_put_be16(msg, wps->wps->ssid_len);
  192. wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
  193. return 0;
  194. }
  195. static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
  196. {
  197. wpa_printf(MSG_DEBUG, "WPS: * Authentication Type");
  198. wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
  199. wpabuf_put_be16(msg, 2);
  200. wpabuf_put_be16(msg, wps->wps->auth_types);
  201. return 0;
  202. }
  203. static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
  204. {
  205. wpa_printf(MSG_DEBUG, "WPS: * Encryption Type");
  206. wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
  207. wpabuf_put_be16(msg, 2);
  208. wpabuf_put_be16(msg, wps->wps->encr_types);
  209. return 0;
  210. }
  211. static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
  212. {
  213. wpa_printf(MSG_DEBUG, "WPS: * Network Key");
  214. wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
  215. wpabuf_put_be16(msg, wps->wps->network_key_len);
  216. wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
  217. return 0;
  218. }
  219. static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
  220. {
  221. wpa_printf(MSG_DEBUG, "WPS: * MAC Address (AP BSSID)");
  222. wpabuf_put_be16(msg, ATTR_MAC_ADDR);
  223. wpabuf_put_be16(msg, ETH_ALEN);
  224. wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
  225. return 0;
  226. }
  227. static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
  228. {
  229. if (wps->wps->ap_settings) {
  230. wpa_printf(MSG_DEBUG, "WPS: * AP Settings (pre-configured)");
  231. wpabuf_put_data(plain, wps->wps->ap_settings,
  232. wps->wps->ap_settings_len);
  233. return 0;
  234. }
  235. return wps_build_cred_ssid(wps, plain) ||
  236. wps_build_cred_mac_addr(wps, plain) ||
  237. wps_build_cred_auth_type(wps, plain) ||
  238. wps_build_cred_encr_type(wps, plain) ||
  239. wps_build_cred_network_key(wps, plain);
  240. }
  241. static struct wpabuf * wps_build_m7(struct wps_data *wps)
  242. {
  243. struct wpabuf *msg, *plain;
  244. wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
  245. plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
  246. if (plain == NULL)
  247. return NULL;
  248. msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
  249. if (msg == NULL) {
  250. wpabuf_free(plain);
  251. return NULL;
  252. }
  253. if (wps_build_version(msg) ||
  254. wps_build_msg_type(msg, WPS_M7) ||
  255. wps_build_registrar_nonce(wps, msg) ||
  256. wps_build_e_snonce2(wps, plain) ||
  257. (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
  258. wps_build_key_wrap_auth(wps, plain) ||
  259. wps_build_encr_settings(wps, msg, plain) ||
  260. wps_build_version2(msg) ||
  261. wps_build_authenticator(wps, msg)) {
  262. wpabuf_free(plain);
  263. wpabuf_free(msg);
  264. return NULL;
  265. }
  266. wpabuf_free(plain);
  267. if (wps->wps->ap && wps->wps->registrar) {
  268. /*
  269. * If the Registrar is only learning our current configuration,
  270. * it may not continue protocol run to successful completion.
  271. * Store information here to make sure it remains available.
  272. */
  273. wps_device_store(wps->wps->registrar, &wps->peer_dev,
  274. wps->uuid_r);
  275. }
  276. wps->state = RECV_M8;
  277. return msg;
  278. }
  279. static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
  280. {
  281. struct wpabuf *msg;
  282. wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
  283. msg = wpabuf_alloc(1000);
  284. if (msg == NULL)
  285. return NULL;
  286. if (wps_build_version(msg) ||
  287. wps_build_msg_type(msg, WPS_WSC_DONE) ||
  288. wps_build_enrollee_nonce(wps, msg) ||
  289. wps_build_registrar_nonce(wps, msg) ||
  290. wps_build_version2(msg)) {
  291. wpabuf_free(msg);
  292. return NULL;
  293. }
  294. if (wps->wps->ap)
  295. wps->state = RECV_ACK;
  296. else {
  297. wps_success_event(wps->wps);
  298. wps->state = WPS_FINISHED;
  299. }
  300. return msg;
  301. }
  302. static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
  303. {
  304. struct wpabuf *msg;
  305. wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
  306. msg = wpabuf_alloc(1000);
  307. if (msg == NULL)
  308. return NULL;
  309. if (wps_build_version(msg) ||
  310. wps_build_msg_type(msg, WPS_WSC_ACK) ||
  311. wps_build_enrollee_nonce(wps, msg) ||
  312. wps_build_registrar_nonce(wps, msg) ||
  313. wps_build_version2(msg)) {
  314. wpabuf_free(msg);
  315. return NULL;
  316. }
  317. return msg;
  318. }
  319. static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
  320. {
  321. struct wpabuf *msg;
  322. wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
  323. msg = wpabuf_alloc(1000);
  324. if (msg == NULL)
  325. return NULL;
  326. if (wps_build_version(msg) ||
  327. wps_build_msg_type(msg, WPS_WSC_NACK) ||
  328. wps_build_enrollee_nonce(wps, msg) ||
  329. wps_build_registrar_nonce(wps, msg) ||
  330. wps_build_config_error(msg, wps->config_error) ||
  331. wps_build_version2(msg)) {
  332. wpabuf_free(msg);
  333. return NULL;
  334. }
  335. return msg;
  336. }
  337. struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
  338. enum wsc_op_code *op_code)
  339. {
  340. struct wpabuf *msg;
  341. switch (wps->state) {
  342. case SEND_M1:
  343. msg = wps_build_m1(wps);
  344. *op_code = WSC_MSG;
  345. break;
  346. case SEND_M3:
  347. msg = wps_build_m3(wps);
  348. *op_code = WSC_MSG;
  349. break;
  350. case SEND_M5:
  351. msg = wps_build_m5(wps);
  352. *op_code = WSC_MSG;
  353. break;
  354. case SEND_M7:
  355. msg = wps_build_m7(wps);
  356. *op_code = WSC_MSG;
  357. break;
  358. case RECEIVED_M2D:
  359. if (wps->wps->ap) {
  360. msg = wps_build_wsc_nack(wps);
  361. *op_code = WSC_NACK;
  362. break;
  363. }
  364. msg = wps_build_wsc_ack(wps);
  365. *op_code = WSC_ACK;
  366. if (msg) {
  367. /* Another M2/M2D may be received */
  368. wps->state = RECV_M2;
  369. }
  370. break;
  371. case SEND_WSC_NACK:
  372. msg = wps_build_wsc_nack(wps);
  373. *op_code = WSC_NACK;
  374. break;
  375. case WPS_MSG_DONE:
  376. msg = wps_build_wsc_done(wps);
  377. *op_code = WSC_Done;
  378. break;
  379. default:
  380. wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
  381. "a message", wps->state);
  382. msg = NULL;
  383. break;
  384. }
  385. if (*op_code == WSC_MSG && msg) {
  386. /* Save a copy of the last message for Authenticator derivation
  387. */
  388. wpabuf_free(wps->last_msg);
  389. wps->last_msg = wpabuf_dup(msg);
  390. }
  391. return msg;
  392. }
  393. static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
  394. {
  395. if (r_nonce == NULL) {
  396. wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
  397. return -1;
  398. }
  399. os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
  400. wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
  401. wps->nonce_r, WPS_NONCE_LEN);
  402. return 0;
  403. }
  404. static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
  405. {
  406. if (e_nonce == NULL) {
  407. wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
  408. return -1;
  409. }
  410. if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
  411. wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
  412. return -1;
  413. }
  414. return 0;
  415. }
  416. static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
  417. {
  418. if (uuid_r == NULL) {
  419. wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
  420. return -1;
  421. }
  422. os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
  423. wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
  424. return 0;
  425. }
  426. static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
  427. size_t pk_len)
  428. {
  429. if (pk == NULL || pk_len == 0) {
  430. wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
  431. return -1;
  432. }
  433. #ifdef CONFIG_WPS_OOB
  434. if (wps->dev_pw_id != DEV_PW_DEFAULT &&
  435. wps->wps->oob_conf.pubkey_hash) {
  436. const u8 *addr[1];
  437. u8 hash[WPS_HASH_LEN];
  438. addr[0] = pk;
  439. sha256_vector(1, addr, &pk_len, hash);
  440. if (os_memcmp(hash,
  441. wpabuf_head(wps->wps->oob_conf.pubkey_hash),
  442. WPS_OOB_PUBKEY_HASH_LEN) != 0) {
  443. wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
  444. return -1;
  445. }
  446. }
  447. #endif /* CONFIG_WPS_OOB */
  448. wpabuf_free(wps->dh_pubkey_r);
  449. wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
  450. if (wps->dh_pubkey_r == NULL)
  451. return -1;
  452. if (wps_derive_keys(wps) < 0)
  453. return -1;
  454. return 0;
  455. }
  456. static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
  457. {
  458. if (r_hash1 == NULL) {
  459. wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
  460. return -1;
  461. }
  462. os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
  463. wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
  464. return 0;
  465. }
  466. static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
  467. {
  468. if (r_hash2 == NULL) {
  469. wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
  470. return -1;
  471. }
  472. os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
  473. wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
  474. return 0;
  475. }
  476. static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
  477. {
  478. u8 hash[SHA256_MAC_LEN];
  479. const u8 *addr[4];
  480. size_t len[4];
  481. if (r_snonce1 == NULL) {
  482. wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
  483. return -1;
  484. }
  485. wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
  486. WPS_SECRET_NONCE_LEN);
  487. /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
  488. addr[0] = r_snonce1;
  489. len[0] = WPS_SECRET_NONCE_LEN;
  490. addr[1] = wps->psk1;
  491. len[1] = WPS_PSK_LEN;
  492. addr[2] = wpabuf_head(wps->dh_pubkey_e);
  493. len[2] = wpabuf_len(wps->dh_pubkey_e);
  494. addr[3] = wpabuf_head(wps->dh_pubkey_r);
  495. len[3] = wpabuf_len(wps->dh_pubkey_r);
  496. hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
  497. if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
  498. wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
  499. "not match with the pre-committed value");
  500. wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
  501. wps_pwd_auth_fail_event(wps->wps, 1, 1);
  502. return -1;
  503. }
  504. wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
  505. "half of the device password");
  506. return 0;
  507. }
  508. static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
  509. {
  510. u8 hash[SHA256_MAC_LEN];
  511. const u8 *addr[4];
  512. size_t len[4];
  513. if (r_snonce2 == NULL) {
  514. wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
  515. return -1;
  516. }
  517. wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
  518. WPS_SECRET_NONCE_LEN);
  519. /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
  520. addr[0] = r_snonce2;
  521. len[0] = WPS_SECRET_NONCE_LEN;
  522. addr[1] = wps->psk2;
  523. len[1] = WPS_PSK_LEN;
  524. addr[2] = wpabuf_head(wps->dh_pubkey_e);
  525. len[2] = wpabuf_len(wps->dh_pubkey_e);
  526. addr[3] = wpabuf_head(wps->dh_pubkey_r);
  527. len[3] = wpabuf_len(wps->dh_pubkey_r);
  528. hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
  529. if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
  530. wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
  531. "not match with the pre-committed value");
  532. wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
  533. wps_pwd_auth_fail_event(wps->wps, 1, 2);
  534. return -1;
  535. }
  536. wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
  537. "half of the device password");
  538. return 0;
  539. }
  540. static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
  541. size_t cred_len, int wps2)
  542. {
  543. struct wps_parse_attr attr;
  544. struct wpabuf msg;
  545. wpa_printf(MSG_DEBUG, "WPS: Received Credential");
  546. os_memset(&wps->cred, 0, sizeof(wps->cred));
  547. wpabuf_set(&msg, cred, cred_len);
  548. if (wps_parse_msg(&msg, &attr) < 0 ||
  549. wps_process_cred(&attr, &wps->cred))
  550. return -1;
  551. if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
  552. 0) {
  553. wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
  554. MACSTR ") does not match with own address (" MACSTR
  555. ")", MAC2STR(wps->cred.mac_addr),
  556. MAC2STR(wps->wps->dev.mac_addr));
  557. /*
  558. * In theory, this could be consider fatal error, but there are
  559. * number of deployed implementations using other address here
  560. * due to unclarity in the specification. For interoperability
  561. * reasons, allow this to be processed since we do not really
  562. * use the MAC Address information for anything.
  563. */
  564. #ifdef CONFIG_WPS_STRICT
  565. if (wps2) {
  566. wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
  567. "MAC Address in AP Settings");
  568. return -1;
  569. }
  570. #endif /* CONFIG_WPS_STRICT */
  571. }
  572. if (wps->wps->cred_cb) {
  573. wps->cred.cred_attr = cred - 4;
  574. wps->cred.cred_attr_len = cred_len + 4;
  575. wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
  576. wps->cred.cred_attr = NULL;
  577. wps->cred.cred_attr_len = 0;
  578. }
  579. return 0;
  580. }
  581. static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
  582. size_t cred_len[], size_t num_cred, int wps2)
  583. {
  584. size_t i;
  585. if (wps->wps->ap)
  586. return 0;
  587. if (num_cred == 0) {
  588. wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
  589. "received");
  590. return -1;
  591. }
  592. for (i = 0; i < num_cred; i++) {
  593. if (wps_process_cred_e(wps, cred[i], cred_len[i], wps2))
  594. return -1;
  595. }
  596. return 0;
  597. }
  598. static int wps_process_ap_settings_e(struct wps_data *wps,
  599. struct wps_parse_attr *attr,
  600. struct wpabuf *attrs, int wps2)
  601. {
  602. struct wps_credential cred;
  603. if (!wps->wps->ap)
  604. return 0;
  605. if (wps_process_ap_settings(attr, &cred) < 0)
  606. return -1;
  607. wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
  608. "Registrar");
  609. if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
  610. 0) {
  611. wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
  612. MACSTR ") does not match with own address (" MACSTR
  613. ")", MAC2STR(cred.mac_addr),
  614. MAC2STR(wps->wps->dev.mac_addr));
  615. /*
  616. * In theory, this could be consider fatal error, but there are
  617. * number of deployed implementations using other address here
  618. * due to unclarity in the specification. For interoperability
  619. * reasons, allow this to be processed since we do not really
  620. * use the MAC Address information for anything.
  621. */
  622. #ifdef CONFIG_WPS_STRICT
  623. if (wps2) {
  624. wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
  625. "MAC Address in AP Settings");
  626. return -1;
  627. }
  628. #endif /* CONFIG_WPS_STRICT */
  629. }
  630. if (!(cred.encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES)))
  631. {
  632. if (cred.encr_type & WPS_ENCR_WEP) {
  633. wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
  634. "due to WEP configuration");
  635. return -1;
  636. }
  637. wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
  638. "invalid encr_type 0x%x", cred.encr_type);
  639. return -1;
  640. }
  641. #ifdef CONFIG_WPS_STRICT
  642. if (wps2) {
  643. if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
  644. WPS_ENCR_TKIP ||
  645. (cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
  646. WPS_AUTH_WPAPSK) {
  647. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
  648. "AP Settings: WPA-Personal/TKIP only");
  649. return -1;
  650. }
  651. }
  652. #endif /* CONFIG_WPS_STRICT */
  653. if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == WPS_ENCR_TKIP)
  654. {
  655. wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
  656. "TKIP+AES");
  657. cred.encr_type |= WPS_ENCR_AES;
  658. }
  659. if ((cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
  660. WPS_AUTH_WPAPSK) {
  661. wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
  662. "WPAPSK+WPA2PSK");
  663. cred.auth_type |= WPS_AUTH_WPA2PSK;
  664. }
  665. if (wps->wps->cred_cb) {
  666. cred.cred_attr = wpabuf_head(attrs);
  667. cred.cred_attr_len = wpabuf_len(attrs);
  668. wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
  669. }
  670. return 0;
  671. }
  672. static enum wps_process_res wps_process_m2(struct wps_data *wps,
  673. const struct wpabuf *msg,
  674. struct wps_parse_attr *attr)
  675. {
  676. wpa_printf(MSG_DEBUG, "WPS: Received M2");
  677. if (wps->state != RECV_M2) {
  678. wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
  679. "receiving M2", wps->state);
  680. wps->state = SEND_WSC_NACK;
  681. return WPS_CONTINUE;
  682. }
  683. if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
  684. wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
  685. wps_process_uuid_r(wps, attr->uuid_r)) {
  686. wps->state = SEND_WSC_NACK;
  687. return WPS_CONTINUE;
  688. }
  689. if (wps->wps->ap &&
  690. (wps->wps->ap_setup_locked || wps->dev_password == NULL)) {
  691. wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
  692. "registration of a new Registrar");
  693. wps->config_error = WPS_CFG_SETUP_LOCKED;
  694. wps->state = SEND_WSC_NACK;
  695. return WPS_CONTINUE;
  696. }
  697. if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
  698. wps_process_authenticator(wps, attr->authenticator, msg) ||
  699. wps_process_device_attrs(&wps->peer_dev, attr)) {
  700. wps->state = SEND_WSC_NACK;
  701. return WPS_CONTINUE;
  702. }
  703. wps->state = SEND_M3;
  704. return WPS_CONTINUE;
  705. }
  706. static enum wps_process_res wps_process_m2d(struct wps_data *wps,
  707. struct wps_parse_attr *attr)
  708. {
  709. wpa_printf(MSG_DEBUG, "WPS: Received M2D");
  710. if (wps->state != RECV_M2) {
  711. wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
  712. "receiving M2D", wps->state);
  713. wps->state = SEND_WSC_NACK;
  714. return WPS_CONTINUE;
  715. }
  716. wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
  717. attr->manufacturer, attr->manufacturer_len);
  718. wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
  719. attr->model_name, attr->model_name_len);
  720. wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
  721. attr->model_number, attr->model_number_len);
  722. wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
  723. attr->serial_number, attr->serial_number_len);
  724. wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
  725. attr->dev_name, attr->dev_name_len);
  726. if (wps->wps->event_cb) {
  727. union wps_event_data data;
  728. struct wps_event_m2d *m2d = &data.m2d;
  729. os_memset(&data, 0, sizeof(data));
  730. if (attr->config_methods)
  731. m2d->config_methods =
  732. WPA_GET_BE16(attr->config_methods);
  733. m2d->manufacturer = attr->manufacturer;
  734. m2d->manufacturer_len = attr->manufacturer_len;
  735. m2d->model_name = attr->model_name;
  736. m2d->model_name_len = attr->model_name_len;
  737. m2d->model_number = attr->model_number;
  738. m2d->model_number_len = attr->model_number_len;
  739. m2d->serial_number = attr->serial_number;
  740. m2d->serial_number_len = attr->serial_number_len;
  741. m2d->dev_name = attr->dev_name;
  742. m2d->dev_name_len = attr->dev_name_len;
  743. m2d->primary_dev_type = attr->primary_dev_type;
  744. if (attr->config_error)
  745. m2d->config_error =
  746. WPA_GET_BE16(attr->config_error);
  747. if (attr->dev_password_id)
  748. m2d->dev_password_id =
  749. WPA_GET_BE16(attr->dev_password_id);
  750. wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
  751. }
  752. wps->state = RECEIVED_M2D;
  753. return WPS_CONTINUE;
  754. }
  755. static enum wps_process_res wps_process_m4(struct wps_data *wps,
  756. const struct wpabuf *msg,
  757. struct wps_parse_attr *attr)
  758. {
  759. struct wpabuf *decrypted;
  760. struct wps_parse_attr eattr;
  761. wpa_printf(MSG_DEBUG, "WPS: Received M4");
  762. if (wps->state != RECV_M4) {
  763. wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
  764. "receiving M4", wps->state);
  765. wps->state = SEND_WSC_NACK;
  766. return WPS_CONTINUE;
  767. }
  768. if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
  769. wps_process_authenticator(wps, attr->authenticator, msg) ||
  770. wps_process_r_hash1(wps, attr->r_hash1) ||
  771. wps_process_r_hash2(wps, attr->r_hash2)) {
  772. wps->state = SEND_WSC_NACK;
  773. return WPS_CONTINUE;
  774. }
  775. decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
  776. attr->encr_settings_len);
  777. if (decrypted == NULL) {
  778. wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
  779. "Settings attribute");
  780. wps->state = SEND_WSC_NACK;
  781. return WPS_CONTINUE;
  782. }
  783. wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
  784. "attribute");
  785. if (wps_parse_msg(decrypted, &eattr) < 0 ||
  786. wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
  787. wps_process_r_snonce1(wps, eattr.r_snonce1)) {
  788. wpabuf_free(decrypted);
  789. wps->state = SEND_WSC_NACK;
  790. return WPS_CONTINUE;
  791. }
  792. wpabuf_free(decrypted);
  793. wps->state = SEND_M5;
  794. return WPS_CONTINUE;
  795. }
  796. static enum wps_process_res wps_process_m6(struct wps_data *wps,
  797. const struct wpabuf *msg,
  798. struct wps_parse_attr *attr)
  799. {
  800. struct wpabuf *decrypted;
  801. struct wps_parse_attr eattr;
  802. wpa_printf(MSG_DEBUG, "WPS: Received M6");
  803. if (wps->state != RECV_M6) {
  804. wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
  805. "receiving M6", wps->state);
  806. wps->state = SEND_WSC_NACK;
  807. return WPS_CONTINUE;
  808. }
  809. if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
  810. wps_process_authenticator(wps, attr->authenticator, msg)) {
  811. wps->state = SEND_WSC_NACK;
  812. return WPS_CONTINUE;
  813. }
  814. decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
  815. attr->encr_settings_len);
  816. if (decrypted == NULL) {
  817. wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
  818. "Settings attribute");
  819. wps->state = SEND_WSC_NACK;
  820. return WPS_CONTINUE;
  821. }
  822. wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
  823. "attribute");
  824. if (wps_parse_msg(decrypted, &eattr) < 0 ||
  825. wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
  826. wps_process_r_snonce2(wps, eattr.r_snonce2)) {
  827. wpabuf_free(decrypted);
  828. wps->state = SEND_WSC_NACK;
  829. return WPS_CONTINUE;
  830. }
  831. wpabuf_free(decrypted);
  832. wps->state = SEND_M7;
  833. return WPS_CONTINUE;
  834. }
  835. static enum wps_process_res wps_process_m8(struct wps_data *wps,
  836. const struct wpabuf *msg,
  837. struct wps_parse_attr *attr)
  838. {
  839. struct wpabuf *decrypted;
  840. struct wps_parse_attr eattr;
  841. wpa_printf(MSG_DEBUG, "WPS: Received M8");
  842. if (wps->state != RECV_M8) {
  843. wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
  844. "receiving M8", wps->state);
  845. wps->state = SEND_WSC_NACK;
  846. return WPS_CONTINUE;
  847. }
  848. if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
  849. wps_process_authenticator(wps, attr->authenticator, msg)) {
  850. wps->state = SEND_WSC_NACK;
  851. return WPS_CONTINUE;
  852. }
  853. decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
  854. attr->encr_settings_len);
  855. if (decrypted == NULL) {
  856. wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
  857. "Settings attribute");
  858. wps->state = SEND_WSC_NACK;
  859. return WPS_CONTINUE;
  860. }
  861. wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
  862. "attribute");
  863. if (wps_parse_msg(decrypted, &eattr) < 0 ||
  864. wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
  865. wps_process_creds(wps, eattr.cred, eattr.cred_len,
  866. eattr.num_cred, attr->version2 != NULL) ||
  867. wps_process_ap_settings_e(wps, &eattr, decrypted,
  868. attr->version2 != NULL)) {
  869. wpabuf_free(decrypted);
  870. wps->state = SEND_WSC_NACK;
  871. return WPS_CONTINUE;
  872. }
  873. wpabuf_free(decrypted);
  874. wps->state = WPS_MSG_DONE;
  875. return WPS_CONTINUE;
  876. }
  877. static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
  878. const struct wpabuf *msg)
  879. {
  880. struct wps_parse_attr attr;
  881. enum wps_process_res ret = WPS_CONTINUE;
  882. wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
  883. if (wps_parse_msg(msg, &attr) < 0)
  884. return WPS_FAILURE;
  885. if (attr.enrollee_nonce == NULL ||
  886. os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
  887. wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
  888. return WPS_FAILURE;
  889. }
  890. if (attr.msg_type == NULL) {
  891. wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
  892. return WPS_FAILURE;
  893. }
  894. switch (*attr.msg_type) {
  895. case WPS_M2:
  896. ret = wps_process_m2(wps, msg, &attr);
  897. break;
  898. case WPS_M2D:
  899. ret = wps_process_m2d(wps, &attr);
  900. break;
  901. case WPS_M4:
  902. ret = wps_process_m4(wps, msg, &attr);
  903. if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
  904. wps_fail_event(wps->wps, WPS_M4);
  905. break;
  906. case WPS_M6:
  907. ret = wps_process_m6(wps, msg, &attr);
  908. if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
  909. wps_fail_event(wps->wps, WPS_M6);
  910. break;
  911. case WPS_M8:
  912. ret = wps_process_m8(wps, msg, &attr);
  913. if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
  914. wps_fail_event(wps->wps, WPS_M8);
  915. break;
  916. default:
  917. wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
  918. *attr.msg_type);
  919. return WPS_FAILURE;
  920. }
  921. /*
  922. * Save a copy of the last message for Authenticator derivation if we
  923. * are continuing. However, skip M2D since it is not authenticated and
  924. * neither is the ACK/NACK response frame. This allows the possibly
  925. * following M2 to be processed correctly by using the previously sent
  926. * M1 in Authenticator derivation.
  927. */
  928. if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
  929. /* Save a copy of the last message for Authenticator derivation
  930. */
  931. wpabuf_free(wps->last_msg);
  932. wps->last_msg = wpabuf_dup(msg);
  933. }
  934. return ret;
  935. }
  936. static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
  937. const struct wpabuf *msg)
  938. {
  939. struct wps_parse_attr attr;
  940. wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
  941. if (wps_parse_msg(msg, &attr) < 0)
  942. return WPS_FAILURE;
  943. if (attr.msg_type == NULL) {
  944. wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
  945. return WPS_FAILURE;
  946. }
  947. if (*attr.msg_type != WPS_WSC_ACK) {
  948. wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
  949. *attr.msg_type);
  950. return WPS_FAILURE;
  951. }
  952. if (attr.registrar_nonce == NULL ||
  953. os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
  954. {
  955. wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
  956. return WPS_FAILURE;
  957. }
  958. if (attr.enrollee_nonce == NULL ||
  959. os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
  960. wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
  961. return WPS_FAILURE;
  962. }
  963. if (wps->state == RECV_ACK && wps->wps->ap) {
  964. wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
  965. "completed successfully");
  966. wps_success_event(wps->wps);
  967. wps->state = WPS_FINISHED;
  968. return WPS_DONE;
  969. }
  970. return WPS_FAILURE;
  971. }
  972. static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
  973. const struct wpabuf *msg)
  974. {
  975. struct wps_parse_attr attr;
  976. wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
  977. if (wps_parse_msg(msg, &attr) < 0)
  978. return WPS_FAILURE;
  979. if (attr.msg_type == NULL) {
  980. wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
  981. return WPS_FAILURE;
  982. }
  983. if (*attr.msg_type != WPS_WSC_NACK) {
  984. wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
  985. *attr.msg_type);
  986. return WPS_FAILURE;
  987. }
  988. if (attr.registrar_nonce == NULL ||
  989. os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
  990. {
  991. wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
  992. wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
  993. attr.registrar_nonce, WPS_NONCE_LEN);
  994. wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
  995. wps->nonce_r, WPS_NONCE_LEN);
  996. return WPS_FAILURE;
  997. }
  998. if (attr.enrollee_nonce == NULL ||
  999. os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
  1000. wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
  1001. wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
  1002. attr.enrollee_nonce, WPS_NONCE_LEN);
  1003. wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
  1004. wps->nonce_e, WPS_NONCE_LEN);
  1005. return WPS_FAILURE;
  1006. }
  1007. if (attr.config_error == NULL) {
  1008. wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
  1009. "in WSC_NACK");
  1010. return WPS_FAILURE;
  1011. }
  1012. wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
  1013. "Configuration Error %d", WPA_GET_BE16(attr.config_error));
  1014. switch (wps->state) {
  1015. case RECV_M4:
  1016. wps_fail_event(wps->wps, WPS_M3);
  1017. break;
  1018. case RECV_M6:
  1019. wps_fail_event(wps->wps, WPS_M5);
  1020. break;
  1021. case RECV_M8:
  1022. wps_fail_event(wps->wps, WPS_M7);
  1023. break;
  1024. default:
  1025. break;
  1026. }
  1027. /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
  1028. * Enrollee is Authenticator */
  1029. wps->state = SEND_WSC_NACK;
  1030. return WPS_FAILURE;
  1031. }
  1032. enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
  1033. enum wsc_op_code op_code,
  1034. const struct wpabuf *msg)
  1035. {
  1036. wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
  1037. "op_code=%d)",
  1038. (unsigned long) wpabuf_len(msg), op_code);
  1039. if (op_code == WSC_UPnP) {
  1040. /* Determine the OpCode based on message type attribute */
  1041. struct wps_parse_attr attr;
  1042. if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
  1043. if (*attr.msg_type == WPS_WSC_ACK)
  1044. op_code = WSC_ACK;
  1045. else if (*attr.msg_type == WPS_WSC_NACK)
  1046. op_code = WSC_NACK;
  1047. }
  1048. }
  1049. switch (op_code) {
  1050. case WSC_MSG:
  1051. case WSC_UPnP:
  1052. return wps_process_wsc_msg(wps, msg);
  1053. case WSC_ACK:
  1054. return wps_process_wsc_ack(wps, msg);
  1055. case WSC_NACK:
  1056. return wps_process_wsc_nack(wps, msg);
  1057. default:
  1058. wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
  1059. return WPS_FAILURE;
  1060. }
  1061. }