1189251Ssam/*
2189251Ssam * Wi-Fi Protected Setup - internal definitions
3214734Srpaulo * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
4189251Ssam *
5189251Ssam * This program is free software; you can redistribute it and/or modify
6189251Ssam * it under the terms of the GNU General Public License version 2 as
7189251Ssam * published by the Free Software Foundation.
8189251Ssam *
9189251Ssam * Alternatively, this software may be distributed under the terms of BSD
10189251Ssam * license.
11189251Ssam *
12189251Ssam * See README and COPYING for more details.
13189251Ssam */
14189251Ssam
15189251Ssam#ifndef WPS_I_H
16189251Ssam#define WPS_I_H
17189251Ssam
18189251Ssam#include "wps.h"
19189251Ssam
20189251Ssam/**
21189251Ssam * struct wps_data - WPS registration protocol data
22189251Ssam *
23189251Ssam * This data is stored at the EAP-WSC server/peer method and it is kept for a
24189251Ssam * single registration protocol run.
25189251Ssam */
26189251Ssamstruct wps_data {
27189251Ssam	/**
28189251Ssam	 * wps - Pointer to long term WPS context
29189251Ssam	 */
30189251Ssam	struct wps_context *wps;
31189251Ssam
32189251Ssam	/**
33189251Ssam	 * registrar - Whether this end is a Registrar
34189251Ssam	 */
35189251Ssam	int registrar;
36189251Ssam
37214734Srpaulo	/**
38214734Srpaulo	 * er - Whether the local end is an external registrar
39214734Srpaulo	 */
40214734Srpaulo	int er;
41214734Srpaulo
42189251Ssam	enum {
43189251Ssam		/* Enrollee states */
44189251Ssam		SEND_M1, RECV_M2, SEND_M3, RECV_M4, SEND_M5, RECV_M6, SEND_M7,
45189251Ssam		RECV_M8, RECEIVED_M2D, WPS_MSG_DONE, RECV_ACK, WPS_FINISHED,
46189251Ssam		SEND_WSC_NACK,
47189251Ssam
48189251Ssam		/* Registrar states */
49189251Ssam		RECV_M1, SEND_M2, RECV_M3, SEND_M4, RECV_M5, SEND_M6,
50189251Ssam		RECV_M7, SEND_M8, RECV_DONE, SEND_M2D, RECV_M2D_ACK
51189251Ssam	} state;
52189251Ssam
53189251Ssam	u8 uuid_e[WPS_UUID_LEN];
54189251Ssam	u8 uuid_r[WPS_UUID_LEN];
55189251Ssam	u8 mac_addr_e[ETH_ALEN];
56189251Ssam	u8 nonce_e[WPS_NONCE_LEN];
57189251Ssam	u8 nonce_r[WPS_NONCE_LEN];
58189251Ssam	u8 psk1[WPS_PSK_LEN];
59189251Ssam	u8 psk2[WPS_PSK_LEN];
60189251Ssam	u8 snonce[2 * WPS_SECRET_NONCE_LEN];
61189251Ssam	u8 peer_hash1[WPS_HASH_LEN];
62189251Ssam	u8 peer_hash2[WPS_HASH_LEN];
63189251Ssam
64189251Ssam	struct wpabuf *dh_privkey;
65189251Ssam	struct wpabuf *dh_pubkey_e;
66189251Ssam	struct wpabuf *dh_pubkey_r;
67189251Ssam	u8 authkey[WPS_AUTHKEY_LEN];
68189251Ssam	u8 keywrapkey[WPS_KEYWRAPKEY_LEN];
69189251Ssam	u8 emsk[WPS_EMSK_LEN];
70189251Ssam
71189251Ssam	struct wpabuf *last_msg;
72189251Ssam
73189251Ssam	u8 *dev_password;
74189251Ssam	size_t dev_password_len;
75189251Ssam	u16 dev_pw_id;
76189251Ssam	int pbc;
77189251Ssam
78189251Ssam	/**
79189251Ssam	 * request_type - Request Type attribute from (Re)AssocReq
80189251Ssam	 */
81189251Ssam	u8 request_type;
82189251Ssam
83189251Ssam	/**
84189251Ssam	 * encr_type - Available encryption types
85189251Ssam	 */
86189251Ssam	u16 encr_type;
87189251Ssam
88189251Ssam	/**
89189251Ssam	 * auth_type - Available authentication types
90189251Ssam	 */
91189251Ssam	u16 auth_type;
92189251Ssam
93189251Ssam	u8 *new_psk;
94189251Ssam	size_t new_psk_len;
95189251Ssam
96189251Ssam	int wps_pin_revealed;
97189251Ssam	struct wps_credential cred;
98189251Ssam
99189251Ssam	struct wps_device_data peer_dev;
100189251Ssam
101189251Ssam	/**
102189251Ssam	 * config_error - Configuration Error value to be used in NACK
103189251Ssam	 */
104189251Ssam	u16 config_error;
105189251Ssam
106189251Ssam	int ext_reg;
107214734Srpaulo	int int_reg;
108214734Srpaulo
109214734Srpaulo	struct wps_credential *new_ap_settings;
110214734Srpaulo
111214734Srpaulo	void *dh_ctx;
112214734Srpaulo
113214734Srpaulo	void (*ap_settings_cb)(void *ctx, const struct wps_credential *cred);
114214734Srpaulo	void *ap_settings_cb_ctx;
115214734Srpaulo
116214734Srpaulo	struct wps_credential *use_cred;
117214734Srpaulo
118214734Srpaulo	int use_psk_key;
119189251Ssam};
120189251Ssam
121189251Ssam
122189251Ssamstruct wps_parse_attr {
123189251Ssam	/* fixed length fields */
124189251Ssam	const u8 *version; /* 1 octet */
125189251Ssam	const u8 *msg_type; /* 1 octet */
126189251Ssam	const u8 *enrollee_nonce; /* WPS_NONCE_LEN (16) octets */
127189251Ssam	const u8 *registrar_nonce; /* WPS_NONCE_LEN (16) octets */
128189251Ssam	const u8 *uuid_r; /* WPS_UUID_LEN (16) octets */
129189251Ssam	const u8 *uuid_e; /* WPS_UUID_LEN (16) octets */
130189251Ssam	const u8 *auth_type_flags; /* 2 octets */
131189251Ssam	const u8 *encr_type_flags; /* 2 octets */
132189251Ssam	const u8 *conn_type_flags; /* 1 octet */
133189251Ssam	const u8 *config_methods; /* 2 octets */
134189251Ssam	const u8 *sel_reg_config_methods; /* 2 octets */
135189251Ssam	const u8 *primary_dev_type; /* 8 octets */
136189251Ssam	const u8 *rf_bands; /* 1 octet */
137189251Ssam	const u8 *assoc_state; /* 2 octets */
138189251Ssam	const u8 *config_error; /* 2 octets */
139189251Ssam	const u8 *dev_password_id; /* 2 octets */
140214734Srpaulo	const u8 *oob_dev_password; /* WPS_OOB_DEVICE_PASSWORD_ATTR_LEN (54)
141214734Srpaulo				     * octets */
142189251Ssam	const u8 *os_version; /* 4 octets */
143189251Ssam	const u8 *wps_state; /* 1 octet */
144189251Ssam	const u8 *authenticator; /* WPS_AUTHENTICATOR_LEN (8) octets */
145189251Ssam	const u8 *r_hash1; /* WPS_HASH_LEN (32) octets */
146189251Ssam	const u8 *r_hash2; /* WPS_HASH_LEN (32) octets */
147189251Ssam	const u8 *e_hash1; /* WPS_HASH_LEN (32) octets */
148189251Ssam	const u8 *e_hash2; /* WPS_HASH_LEN (32) octets */
149189251Ssam	const u8 *r_snonce1; /* WPS_SECRET_NONCE_LEN (16) octets */
150189251Ssam	const u8 *r_snonce2; /* WPS_SECRET_NONCE_LEN (16) octets */
151189251Ssam	const u8 *e_snonce1; /* WPS_SECRET_NONCE_LEN (16) octets */
152189251Ssam	const u8 *e_snonce2; /* WPS_SECRET_NONCE_LEN (16) octets */
153189251Ssam	const u8 *key_wrap_auth; /* WPS_KWA_LEN (8) octets */
154189251Ssam	const u8 *auth_type; /* 2 octets */
155189251Ssam	const u8 *encr_type; /* 2 octets */
156189251Ssam	const u8 *network_idx; /* 1 octet */
157189251Ssam	const u8 *network_key_idx; /* 1 octet */
158189251Ssam	const u8 *mac_addr; /* ETH_ALEN (6) octets */
159189251Ssam	const u8 *key_prov_auto; /* 1 octet (Bool) */
160189251Ssam	const u8 *dot1x_enabled; /* 1 octet (Bool) */
161189251Ssam	const u8 *selected_registrar; /* 1 octet (Bool) */
162189251Ssam	const u8 *request_type; /* 1 octet */
163189251Ssam	const u8 *response_type; /* 1 octet */
164209158Srpaulo	const u8 *ap_setup_locked; /* 1 octet */
165189251Ssam
166189251Ssam	/* variable length fields */
167189251Ssam	const u8 *manufacturer;
168189251Ssam	size_t manufacturer_len;
169189251Ssam	const u8 *model_name;
170189251Ssam	size_t model_name_len;
171189251Ssam	const u8 *model_number;
172189251Ssam	size_t model_number_len;
173189251Ssam	const u8 *serial_number;
174189251Ssam	size_t serial_number_len;
175189251Ssam	const u8 *dev_name;
176189251Ssam	size_t dev_name_len;
177189251Ssam	const u8 *public_key;
178189251Ssam	size_t public_key_len;
179189251Ssam	const u8 *encr_settings;
180189251Ssam	size_t encr_settings_len;
181189251Ssam	const u8 *ssid; /* <= 32 octets */
182189251Ssam	size_t ssid_len;
183189251Ssam	const u8 *network_key; /* <= 64 octets */
184189251Ssam	size_t network_key_len;
185189251Ssam	const u8 *eap_type; /* <= 8 octets */
186189251Ssam	size_t eap_type_len;
187189251Ssam	const u8 *eap_identity; /* <= 64 octets */
188189251Ssam	size_t eap_identity_len;
189189251Ssam
190189251Ssam	/* attributes that can occur multiple times */
191189251Ssam#define MAX_CRED_COUNT 10
192189251Ssam	const u8 *cred[MAX_CRED_COUNT];
193189251Ssam	size_t cred_len[MAX_CRED_COUNT];
194189251Ssam	size_t num_cred;
195189251Ssam};
196189251Ssam
197189251Ssam/* wps_common.c */
198189251Ssamvoid wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
199189251Ssam	     const char *label, u8 *res, size_t res_len);
200189251Ssamint wps_derive_keys(struct wps_data *wps);
201189251Ssamvoid wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
202189251Ssam		    size_t dev_passwd_len);
203189251Ssamstruct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
204189251Ssam					  size_t encr_len);
205189251Ssamvoid wps_fail_event(struct wps_context *wps, enum wps_msg_type msg);
206189251Ssamvoid wps_success_event(struct wps_context *wps);
207189251Ssamvoid wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
208209158Srpaulovoid wps_pbc_overlap_event(struct wps_context *wps);
209209158Srpaulovoid wps_pbc_timeout_event(struct wps_context *wps);
210189251Ssam
211214734Srpauloextern struct oob_device_data oob_ufd_device_data;
212214734Srpauloextern struct oob_device_data oob_nfc_device_data;
213214734Srpauloextern struct oob_nfc_device_data oob_nfc_pn531_device_data;
214214734Srpaulo
215189251Ssam/* wps_attr_parse.c */
216189251Ssamint wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
217189251Ssam
218189251Ssam/* wps_attr_build.c */
219189251Ssamint wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
220189251Ssamint wps_build_req_type(struct wpabuf *msg, enum wps_request_type type);
221214734Srpauloint wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type);
222189251Ssamint wps_build_config_methods(struct wpabuf *msg, u16 methods);
223189251Ssamint wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid);
224189251Ssamint wps_build_dev_password_id(struct wpabuf *msg, u16 id);
225189251Ssamint wps_build_config_error(struct wpabuf *msg, u16 err);
226189251Ssamint wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg);
227189251Ssamint wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg);
228189251Ssamint wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
229189251Ssam			    struct wpabuf *plain);
230189251Ssamint wps_build_version(struct wpabuf *msg);
231189251Ssamint wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
232189251Ssamint wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
233189251Ssamint wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
234189251Ssamint wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg);
235189251Ssamint wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg);
236189251Ssamint wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg);
237189251Ssamint wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg);
238214734Srpauloint wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps);
239189251Ssam
240189251Ssam/* wps_attr_process.c */
241189251Ssamint wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
242189251Ssam			      const struct wpabuf *msg);
243189251Ssamint wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
244189251Ssam			      const u8 *key_wrap_auth);
245189251Ssamint wps_process_cred(struct wps_parse_attr *attr,
246189251Ssam		     struct wps_credential *cred);
247189251Ssamint wps_process_ap_settings(struct wps_parse_attr *attr,
248189251Ssam			    struct wps_credential *cred);
249189251Ssam
250189251Ssam/* wps_enrollee.c */
251189251Ssamstruct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
252189251Ssam				     enum wsc_op_code *op_code);
253189251Ssamenum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
254189251Ssam					      enum wsc_op_code op_code,
255189251Ssam					      const struct wpabuf *msg);
256189251Ssam
257189251Ssam/* wps_registrar.c */
258189251Ssamstruct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
259189251Ssam				      enum wsc_op_code *op_code);
260189251Ssamenum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
261189251Ssam					       enum wsc_op_code op_code,
262189251Ssam					       const struct wpabuf *msg);
263214734Srpauloint wps_build_cred(struct wps_data *wps, struct wpabuf *msg);
264214734Srpauloint wps_device_store(struct wps_registrar *reg,
265214734Srpaulo		     struct wps_device_data *dev, const u8 *uuid);
266214734Srpaulovoid wps_registrar_selected_registrar_changed(struct wps_registrar *reg);
267189251Ssam
268214734Srpaulo/* ndef.c */
269214734Srpaulostruct wpabuf * ndef_parse_wifi(struct wpabuf *buf);
270214734Srpaulostruct wpabuf * ndef_build_wifi(struct wpabuf *buf);
271189251Ssam
272189251Ssamstatic inline int wps_version_supported(const u8 *version)
273189251Ssam{
274189251Ssam	/* Require major version match, but allow minor version differences */
275189251Ssam	return version && (*version & 0xf0) == (WPS_VERSION & 0xf0);
276189251Ssam}
277189251Ssam
278189251Ssam#endif /* WPS_I_H */
279