1 /*
2  * hostapd / WPS integration
3  * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "utils/uuid.h"
14 #include "common/wpa_ctrl.h"
15 #include "common/ieee802_11_defs.h"
16 #include "common/ieee802_11_common.h"
17 #include "wps/wps.h"
18 #include "wps/wps_defs.h"
19 #include "wps/wps_dev_attr.h"
20 #include "wps/wps_attr_parse.h"
21 #include "hostapd.h"
22 #include "ap_config.h"
23 #include "wpa_auth.h"
24 #include "wpa_auth_i.h"
25 #include "sta_info.h"
26 #include "wps/wps_i.h"
27 #include "wps_hostapd.h"
28 #include "eap_server/eap_methods.h"
29 #include "ieee802_1x.h"
30 #include "esp_wps_i.h"
31 
32 static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
33 
hostapd_wps_set_ie_cb(void * ctx,struct wpabuf * beacon_ie,struct wpabuf * probe_resp_ie)34 static int hostapd_wps_set_ie_cb(void *ctx, struct wpabuf *beacon_ie,
35 				 struct wpabuf *probe_resp_ie)
36 {
37 	int ret;
38 
39 	wpa_printf(MSG_DEBUG, "WPS: Updating beacon IEs(%d) to driver", beacon_ie->used);
40 	ret = esp_wifi_set_appie_internal(WIFI_APPIE_RAM_BEACON,
41 			(uint8_t *)wpabuf_head(beacon_ie), beacon_ie->used, 0);
42 	if (ret != ESP_OK) {
43 		wpa_printf(MSG_ERROR, "WPS: Failed to update beacon IEs");
44 		goto cleanup;
45 	}
46 	wpa_printf(MSG_DEBUG, "WPS: Updating probe IEs(%d) to driver", probe_resp_ie->used);
47 	ret = esp_wifi_set_appie_internal(WIFI_APPIE_RAM_PROBE_RSP,
48 			(uint8_t *)wpabuf_head(probe_resp_ie), probe_resp_ie->used, 0);
49 
50 cleanup:
51 	wpabuf_free(beacon_ie);
52 	wpabuf_free(probe_resp_ie);
53 
54 	return ret;
55 }
56 
57 struct wps_stop_reg_data {
58 	struct hostapd_data *current_hapd;
59 	const u8 *uuid_e;
60 	const u8 *dev_pw;
61 	size_t dev_pw_len;
62 };
63 
wps_stop_registrar(struct hostapd_data * hapd,void * ctx)64 static int wps_stop_registrar(struct hostapd_data *hapd, void *ctx)
65 {
66 	struct wps_stop_reg_data *data = ctx;
67 	if (hapd != data->current_hapd && hapd->wps != NULL)
68 		wps_registrar_complete(hapd->wps->registrar, data->uuid_e,
69 				       data->dev_pw, data->dev_pw_len);
70 	return 0;
71 }
72 
hostapd_wps_eap_completed(struct hostapd_data * hapd)73 void hostapd_wps_eap_completed(struct hostapd_data *hapd)
74 {
75 }
76 
hostapd_wps_reg_success_cb(void * ctx,const u8 * mac_addr,const u8 * uuid_e,const u8 * dev_pw,size_t dev_pw_len)77 static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
78 				       const u8 *uuid_e, const u8 *dev_pw,
79 				       size_t dev_pw_len)
80 {
81 	struct hostapd_data *hapd = ctx;
82 	char uuid[40];
83 	struct wps_stop_reg_data data;
84 	if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
85 		return;
86 	wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s",
87 		MAC2STR(mac_addr), uuid);
88 	data.current_hapd = hapd;
89 	data.uuid_e = uuid_e;
90 	data.dev_pw = dev_pw;
91 	data.dev_pw_len = dev_pw_len;
92 	wps_stop_registrar(hapd, &data);
93 
94 	/* TODO add callback event for freeRTOS */
95 }
96 
97 
hostapd_wps_reenable_ap_pin(void * eloop_data,void * user_ctx)98 static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
99 {
100 	struct hostapd_data *hapd = eloop_data;
101 
102 	if (hapd->conf->ap_setup_locked)
103 		return;
104 	if (hapd->ap_pin_failures_consecutive >= 10)
105 		return;
106 
107 	wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
108 	wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
109 	hapd->wps->ap_setup_locked = 0;
110 	wps_registrar_update_ie(hapd->wps->registrar);
111 }
112 
hostapd_pwd_auth_fail(struct hostapd_data * hapd,struct wps_event_pwd_auth_fail * data)113 static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
114 				  struct wps_event_pwd_auth_fail *data)
115 {
116 	/* Update WPS Status - Authentication Failure */
117 	wifi_event_ap_wps_rg_fail_reason_t evt = {0};
118 
119 	wpa_printf(MSG_DEBUG, "WPS: Authentication failure update");
120 	hapd->wps_stats.status = WPS_FAILURE_STATUS;
121 	os_memcpy(hapd->wps_stats.peer_addr, data->peer_macaddr, ETH_ALEN);
122 
123 	os_memcpy(evt.peer_macaddr, data->peer_macaddr, ETH_ALEN);
124 	evt.reason = WPS_AP_FAIL_REASON_AUTH;
125 	esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_FAILED, &evt,
126 			sizeof(evt), OS_BLOCK);
127 }
128 
129 
wps_ap_pin_success(struct hostapd_data * hapd,void * ctx)130 static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx)
131 {
132 	if (hapd->conf->ap_pin == NULL || hapd->wps == NULL)
133 		return 0;
134 
135 	if (hapd->ap_pin_failures_consecutive == 0)
136 		return 0;
137 
138 	wpa_printf(MSG_DEBUG, "WPS: Clear consecutive AP PIN failure counter "
139 		   "- total validation failures %u (%u consecutive)",
140 		   hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
141 	hapd->ap_pin_failures_consecutive = 0;
142 
143 	return 0;
144 }
145 
146 
hostapd_wps_event_pbc_overlap(struct hostapd_data * hapd)147 static void hostapd_wps_event_pbc_overlap(struct hostapd_data *hapd)
148 {
149 	/* Update WPS Status - PBC Overlap */
150 
151 	hapd->wps_stats.pbc_status = WPS_PBC_STATUS_OVERLAP;
152 	esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, NULL, 0, OS_BLOCK);
153 }
154 
155 
hostapd_wps_event_pbc_timeout(struct hostapd_data * hapd)156 static void hostapd_wps_event_pbc_timeout(struct hostapd_data *hapd)
157 {
158 	/* Update WPS PBC Status:PBC Timeout */
159 	hapd->wps_stats.pbc_status = WPS_PBC_STATUS_TIMEOUT;
160 	esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_TIMEOUT, NULL, 0, OS_BLOCK);
161 }
162 
hostapd_wps_event_pin_timeout(struct hostapd_data * hapd)163 static void hostapd_wps_event_pin_timeout(struct hostapd_data *hapd)
164 {
165 	esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_TIMEOUT, NULL, 0, OS_BLOCK);
166 }
167 
hostapd_wps_event_pbc_disable(struct hostapd_data * hapd)168 static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd)
169 {
170 	/* Update WPS PBC status - Active */
171 	hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE;
172 }
173 
174 
hostapd_wps_event_success(struct hostapd_data * hapd,struct wps_event_success * success)175 static void hostapd_wps_event_success(struct hostapd_data *hapd,
176 				      struct wps_event_success *success)
177 {
178 	wifi_event_ap_wps_rg_success_t evt;
179 
180 	os_memcpy(evt.peer_macaddr, success->peer_macaddr, ETH_ALEN);
181 	esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_SUCCESS, &evt,
182 			sizeof(evt), OS_BLOCK);
183 }
184 
185 
hostapd_wps_event_fail(struct hostapd_data * hapd,struct wps_event_fail * fail)186 static void hostapd_wps_event_fail(struct hostapd_data *hapd,
187 				   struct wps_event_fail *fail)
188 {
189 	wifi_event_ap_wps_rg_fail_reason_t evt;
190 	if (fail->config_error > WPS_CFG_NO_ERROR)
191 		evt.reason = WPS_AP_FAIL_REASON_CONFIG;
192 	else
193 		evt.reason = WPS_AP_FAIL_REASON_NORMAL;
194 	os_memcpy(evt.peer_macaddr, fail->peer_macaddr, ETH_ALEN);
195 	esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_FAILED, &evt,
196 			sizeof(evt), OS_BLOCK);
197 }
198 
199 
hostapd_wps_event_cb(void * ctx,enum wps_event event,union wps_event_data * data)200 static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
201 				 union wps_event_data *data)
202 {
203 	struct hostapd_data *hapd = ctx;
204 
205 	switch (event) {
206 	case WPS_EV_FAIL:
207 		hostapd_wps_event_fail(hapd, &data->fail);
208 		break;
209 	case WPS_EV_SUCCESS:
210 		hostapd_wps_event_success(hapd, &data->success);
211 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_SUCCESS);
212 		break;
213 	case WPS_EV_PWD_AUTH_FAIL:
214 		hostapd_pwd_auth_fail(hapd, &data->pwd_auth_fail);
215 		break;
216 	case WPS_EV_PBC_OVERLAP:
217 		hostapd_wps_event_pbc_overlap(hapd);
218 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_OVERLAP);
219 		break;
220 	case WPS_EV_PBC_TIMEOUT:
221 		hostapd_wps_event_pbc_timeout(hapd);
222 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_TIMEOUT);
223 		break;
224 	case WPS_EV_SELECTED_REGISTRAR_TIMEOUT:
225 		hostapd_wps_event_pin_timeout(hapd);
226 	case WPS_EV_PBC_ACTIVE:
227 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ACTIVE);
228 		break;
229 	case WPS_EV_PBC_DISABLE:
230 		hostapd_wps_event_pbc_disable(hapd);
231 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_DISABLE);
232 		break;
233 	case WPS_EV_ER_AP_ADD:
234 		break;
235 	case WPS_EV_ER_AP_REMOVE:
236 		break;
237 	case WPS_EV_ER_ENROLLEE_ADD:
238 		break;
239 	case WPS_EV_ER_ENROLLEE_REMOVE:
240 		break;
241 	case WPS_EV_ER_AP_SETTINGS:
242 		break;
243 	case WPS_EV_ER_SET_SELECTED_REGISTRAR:
244 		break;
245 	case WPS_EV_AP_PIN_SUCCESS:
246 		wps_ap_pin_success(hapd, NULL);
247 		break;
248 	default:
249 		break;
250 	}
251 	if (hapd->wps_event_cb)
252 		hapd->wps_event_cb(hapd, event, data);
253 }
254 
255 
hostapd_wps_rf_band_cb(void * ctx)256 static int hostapd_wps_rf_band_cb(void *ctx)
257 {
258 	return WPS_RF_24GHZ;
259 }
260 
261 
hostapd_wps_clear_ies(struct hostapd_data * hapd,int deinit_only)262 static void hostapd_wps_clear_ies(struct hostapd_data *hapd, int deinit_only)
263 {
264 	esp_wifi_unset_appie_internal(WIFI_APPIE_RAM_BEACON);
265 	esp_wifi_unset_appie_internal(WIFI_APPIE_RAM_PROBE_RSP);
266 }
267 
hostapd_free_wps(struct wps_context * wps)268 static void hostapd_free_wps(struct wps_context *wps)
269 {
270 	int i;
271 
272 	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
273 		wpabuf_free(wps->dev.vendor_ext[i]);
274 	wps_device_data_free(&wps->dev);
275 	os_free(wps->network_key);
276 	wpabuf_free(wps->dh_pubkey);
277 	wpabuf_free(wps->dh_privkey);
278 	os_free(wps);
279 }
280 
hostapd_init_wps(struct hostapd_data * hapd,struct wps_data * wps_data,struct wps_context * wps)281 int hostapd_init_wps(struct hostapd_data *hapd, struct wps_data *wps_data, struct wps_context *wps)
282 {
283 	struct wps_registrar_config cfg;
284 
285 	wps->event_cb = hostapd_wps_event_cb;
286 	wps->rf_band_cb = hostapd_wps_rf_band_cb;
287 	wps->cb_ctx = hapd;
288 
289 	wps->wps_state = WPS_STATE_CONFIGURED;
290 	wps->ap_setup_locked = 0;
291 	wps->ap = 1;
292 
293 	/* build credentials to be given */
294 	hostapd_wps_config_ap(hapd, wps_data);
295 
296 	os_memset(&cfg, 0, sizeof(cfg));
297 	cfg.set_ie_cb = hostapd_wps_set_ie_cb;
298 	cfg.reg_success_cb = hostapd_wps_reg_success_cb;
299 	cfg.cb_ctx = hapd;
300 	cfg.disable_auto_conf = 1;
301 
302 	wps->registrar = wps_registrar_init(wps, &cfg);
303 	if (wps->registrar == NULL) {
304 		wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar");
305 		goto fail;
306 	}
307 
308 	hapd->wps = wps;
309 
310 	eap_server_identity_register();
311 	if (eap_server_wsc_register() < 0) {
312 		wpa_printf(MSG_ERROR, "Failed to register for wsc server");
313 	}
314 	if (ieee802_1x_init(hapd) < 0) {
315 		return 0;
316 	}
317 	return 0;
318 
319 fail:
320 	hostapd_free_wps(wps);
321 	return -1;
322 }
323 
324 #ifdef ESP_SUPPLICANT
ap_sta_server_sm_deinit(struct hostapd_data * hapd,struct sta_info * sta,void * ctx)325 static int ap_sta_server_sm_deinit(struct hostapd_data *hapd,
326 		struct sta_info *sta, void *ctx)
327 {
328 	ieee802_1x_free_station(hapd, sta);
329 	return 0;
330 }
331 #endif /* ESP_SUPPLICANT */
332 
hostapd_deinit_wps(struct hostapd_data * hapd)333 void hostapd_deinit_wps(struct hostapd_data *hapd)
334 {
335 	eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
336 	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
337 	if (hapd->wps == NULL) {
338 		hostapd_wps_clear_ies(hapd, 1);
339 		return;
340 	}
341 	wps_registrar_deinit(hapd->wps->registrar);
342 	hapd->wps->registrar = NULL;
343 
344 #ifdef ESP_SUPPLICANT
345 	ap_for_each_sta(hapd, ap_sta_server_sm_deinit, NULL);
346 #endif /* ESP_SUPPLICANT */
347 
348 	eap_server_unregister_methods();
349 	hapd->wps = NULL;
350 	hostapd_wps_clear_ies(hapd, 1);
351 }
352 
353 
hostapd_update_wps(struct hostapd_data * hapd)354 void hostapd_update_wps(struct hostapd_data *hapd)
355 {
356 	struct wps_context *wps = hapd->wps;
357 	struct hostapd_bss_config *conf = hapd->conf;
358 
359 	if (!wps)
360 		return;
361 
362 	os_memcpy(wps->ssid, conf->ssid.ssid, conf->ssid.ssid_len);
363 	wps->ssid_len = conf->ssid.ssid_len;
364 
365 	/* Clear WPS settings, then fill them again */
366 	hostapd_wps_config_ap(hapd, NULL);
367 
368 	wps_registrar_update_ie(wps->registrar);
369 }
370 
hostapd_wps_add_pin(struct hostapd_data * hapd,const u8 * pin)371 int hostapd_wps_add_pin(struct hostapd_data *hapd, const u8 *pin)
372 {
373 	int ret;
374 
375 	if (hapd->wps == NULL)
376 		return 0;
377 	ret = wps_registrar_add_pin(hapd->wps->registrar, NULL,
378 				    NULL, pin, 8, 120);
379 	return ret;
380 }
381 
hostapd_wps_button_pushed(struct hostapd_data * hapd,const u8 * p2p_dev_addr)382 int hostapd_wps_button_pushed(struct hostapd_data *hapd,
383 			      const u8 *p2p_dev_addr)
384 {
385 	if (hapd->wps) {
386 		return wps_registrar_button_pushed(hapd->wps->registrar,
387 						   p2p_dev_addr);
388 	}
389 	return 0;
390 }
391 
392 
wps_cancel(struct hostapd_data * hapd)393 static int wps_cancel(struct hostapd_data *hapd)
394 {
395 	if (hapd->wps) {
396 		wps_registrar_wps_cancel(hapd->wps->registrar);
397 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_CANCEL);
398 	}
399 
400 	return 0;
401 }
402 
403 
hostapd_wps_cancel(struct hostapd_data * hapd)404 int hostapd_wps_cancel(struct hostapd_data *hapd)
405 {
406 	int ret;
407 
408 	ret = wps_cancel(hapd);
409 	return ret;
410 }
411 
412 
hostapd_wps_ap_pin_timeout(void * eloop_data,void * user_ctx)413 static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
414 {
415 	struct hostapd_data *hapd = eloop_data;
416 	wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
417 	hostapd_wps_ap_pin_disable(hapd);
418 	wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_PIN_DISABLED);
419 }
420 
421 
hostapd_wps_ap_pin_enable(struct hostapd_data * hapd,int timeout)422 static void hostapd_wps_ap_pin_enable(struct hostapd_data *hapd, int timeout)
423 {
424 	wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
425 	hapd->ap_pin_failures = 0;
426 	hapd->ap_pin_failures_consecutive = 0;
427 	hapd->conf->ap_setup_locked = 0;
428 	if (hapd->wps->ap_setup_locked) {
429 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
430 		hapd->wps->ap_setup_locked = 0;
431 		wps_registrar_update_ie(hapd->wps->registrar);
432 	}
433 	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
434 	if (timeout > 0)
435 		eloop_register_timeout(timeout, 0,
436 				       hostapd_wps_ap_pin_timeout, hapd, NULL);
437 }
438 
wps_ap_pin_disable(struct hostapd_data * hapd)439 static int wps_ap_pin_disable(struct hostapd_data *hapd)
440 {
441 	os_free(hapd->conf->ap_pin);
442 	hapd->conf->ap_pin = NULL;
443 	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
444 	return 0;
445 }
446 
447 
hostapd_wps_ap_pin_disable(struct hostapd_data * hapd)448 void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd)
449 {
450 	wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
451 	wps_ap_pin_disable(hapd);
452 }
453 
454 
455 struct wps_ap_pin_data {
456 	char pin_txt[9];
457 	int timeout;
458 };
459 
460 
wps_ap_pin_set(struct hostapd_data * hapd,void * ctx)461 static int wps_ap_pin_set(struct hostapd_data *hapd, void *ctx)
462 {
463 	struct wps_ap_pin_data *data = ctx;
464 
465 	if (!hapd->wps)
466 		return 0;
467 
468 	os_free(hapd->conf->ap_pin);
469 	hapd->conf->ap_pin = os_strdup(data->pin_txt);
470 	hostapd_wps_ap_pin_enable(hapd, data->timeout);
471 	return 0;
472 }
473 
474 
hostapd_wps_ap_pin_random(struct hostapd_data * hapd,int timeout)475 const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout)
476 {
477 	unsigned int pin;
478 	struct wps_ap_pin_data data;
479 
480 	if (wps_generate_pin(&pin) < 0)
481 		return NULL;
482 	os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%08u", pin);
483 	data.timeout = timeout;
484 	wps_ap_pin_set(hapd, &data);
485 	return hapd->conf->ap_pin;
486 }
487 
hostapd_wps_ap_pin_get(struct hostapd_data * hapd)488 const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd)
489 {
490 	return hapd->conf->ap_pin;
491 }
492 
493 
hostapd_wps_ap_pin_set(struct hostapd_data * hapd,const char * pin,int timeout)494 int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin,
495 			   int timeout)
496 {
497 	struct wps_ap_pin_data data;
498 	int ret;
499 
500 	ret = os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%s", pin);
501 	if (os_snprintf_error(sizeof(data.pin_txt), ret))
502 		return -1;
503 	data.timeout = timeout;
504 	return wps_ap_pin_set(hapd, &data);
505 }
506 
507 
hostapd_wps_config_ap(struct hostapd_data * hapd,struct wps_data * wps_data)508 int hostapd_wps_config_ap(struct hostapd_data *hapd, struct wps_data *wps_data)
509 {
510 	struct wps_credential cred = {0};
511 
512 	os_memcpy(cred.ssid, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
513 	cred.ssid_len = hapd->conf->ssid.ssid_len;
514 	cred.encr_type = WPS_ENCR_NONE;
515 	cred.auth_type = WPS_AUTH_OPEN;
516 
517 	if (hapd->wpa_auth->conf.wpa == WPA_PROTO_WPA) {
518 		cred.auth_type = WPS_AUTH_WPAPSK;
519 		cred.encr_type = WPS_ENCR_TKIP;
520 	} else if (hapd->wpa_auth->conf.wpa == WPA_PROTO_RSN) {
521 		cred.auth_type = WPS_AUTH_WPA2PSK;
522 		cred.encr_type = WPS_ENCR_AES;
523 	} else if (hapd->wpa_auth->conf.wpa == (WPA_PROTO_RSN | WPA_PROTO_WPA)) {
524 		cred.auth_type = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
525 		cred.encr_type = WPS_ENCR_AES;
526 	}
527 
528 	if (hapd->conf->ssid.wpa_passphrase) {
529 		cred.key_len = os_strlen(hapd->conf->ssid.wpa_passphrase);
530 		memcpy(cred.key, hapd->conf->ssid.wpa_passphrase, cred.key_len);
531 	}
532 	wps_data->use_cred = os_malloc(sizeof(struct wps_credential));
533 	if (!wps_data->use_cred) {
534 		wpa_printf(MSG_ERROR, "WPS: Disabling AP PIN");
535 		return -1;
536 	}
537 	os_memcpy(wps_data->use_cred, &cred, sizeof(struct wps_credential));
538 	return 0;
539 }
540