eap_i.h revision 252726
1189251Ssam/*
2189251Ssam * EAP peer state machines internal structures (RFC 4137)
3189251Ssam * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
4189251Ssam *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7189251Ssam */
8189251Ssam
9189251Ssam#ifndef EAP_I_H
10189251Ssam#define EAP_I_H
11189251Ssam
12189251Ssam#include "wpabuf.h"
13189251Ssam#include "eap_peer/eap.h"
14189251Ssam#include "eap_common/eap_common.h"
15189251Ssam
16189251Ssam/* RFC 4137 - EAP Peer state machine */
17189251Ssam
18189251Ssamtypedef enum {
19189251Ssam	DECISION_FAIL, DECISION_COND_SUCC, DECISION_UNCOND_SUCC
20189251Ssam} EapDecision;
21189251Ssam
22189251Ssamtypedef enum {
23189251Ssam	METHOD_NONE, METHOD_INIT, METHOD_CONT, METHOD_MAY_CONT, METHOD_DONE
24189251Ssam} EapMethodState;
25189251Ssam
26189251Ssam/**
27189251Ssam * struct eap_method_ret - EAP return values from struct eap_method::process()
28189251Ssam *
29189251Ssam * These structure contains OUT variables for the interface between peer state
30189251Ssam * machine and methods (RFC 4137, Sect. 4.2). eapRespData will be returned as
31189251Ssam * the return value of struct eap_method::process() so it is not included in
32189251Ssam * this structure.
33189251Ssam */
34189251Ssamstruct eap_method_ret {
35189251Ssam	/**
36189251Ssam	 * ignore - Whether method decided to drop the current packed (OUT)
37189251Ssam	 */
38189251Ssam	Boolean ignore;
39189251Ssam
40189251Ssam	/**
41189251Ssam	 * methodState - Method-specific state (IN/OUT)
42189251Ssam	 */
43189251Ssam	EapMethodState methodState;
44189251Ssam
45189251Ssam	/**
46189251Ssam	 * decision - Authentication decision (OUT)
47189251Ssam	 */
48189251Ssam	EapDecision decision;
49189251Ssam
50189251Ssam	/**
51189251Ssam	 * allowNotifications - Whether method allows notifications (OUT)
52189251Ssam	 */
53189251Ssam	Boolean allowNotifications;
54189251Ssam};
55189251Ssam
56189251Ssam
57189251Ssam/**
58189251Ssam * struct eap_method - EAP method interface
59189251Ssam * This structure defines the EAP method interface. Each method will need to
60189251Ssam * register its own EAP type, EAP name, and set of function pointers for method
61189251Ssam * specific operations. This interface is based on section 4.4 of RFC 4137.
62189251Ssam */
63189251Ssamstruct eap_method {
64189251Ssam	/**
65189251Ssam	 * vendor - EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
66189251Ssam	 */
67189251Ssam	int vendor;
68189251Ssam
69189251Ssam	/**
70189251Ssam	 * method - EAP type number (EAP_TYPE_*)
71189251Ssam	 */
72189251Ssam	EapType method;
73189251Ssam
74189251Ssam	/**
75189251Ssam	 * name - Name of the method (e.g., "TLS")
76189251Ssam	 */
77189251Ssam	const char *name;
78189251Ssam
79189251Ssam	/**
80189251Ssam	 * init - Initialize an EAP method
81189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
82189251Ssam	 * Returns: Pointer to allocated private data, or %NULL on failure
83189251Ssam	 *
84189251Ssam	 * This function is used to initialize the EAP method explicitly
85189251Ssam	 * instead of using METHOD_INIT state as specific in RFC 4137. The
86189251Ssam	 * method is expected to initialize it method-specific state and return
87189251Ssam	 * a pointer that will be used as the priv argument to other calls.
88189251Ssam	 */
89189251Ssam	void * (*init)(struct eap_sm *sm);
90189251Ssam
91189251Ssam	/**
92189251Ssam	 * deinit - Deinitialize an EAP method
93189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
94189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
95189251Ssam	 *
96189251Ssam	 * Deinitialize the EAP method and free any allocated private data.
97189251Ssam	 */
98189251Ssam	void (*deinit)(struct eap_sm *sm, void *priv);
99189251Ssam
100189251Ssam	/**
101189251Ssam	 * process - Process an EAP request
102189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
103189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
104189251Ssam	 * @ret: Return values from EAP request validation and processing
105189251Ssam	 * @reqData: EAP request to be processed (eapReqData)
106189251Ssam	 * Returns: Pointer to allocated EAP response packet (eapRespData)
107189251Ssam	 *
108189251Ssam	 * This function is a combination of m.check(), m.process(), and
109189251Ssam	 * m.buildResp() procedures defined in section 4.4 of RFC 4137 In other
110189251Ssam	 * words, this function validates the incoming request, processes it,
111189251Ssam	 * and build a response packet. m.check() and m.process() return values
112189251Ssam	 * are returned through struct eap_method_ret *ret variable. Caller is
113189251Ssam	 * responsible for freeing the returned EAP response packet.
114189251Ssam	 */
115189251Ssam	struct wpabuf * (*process)(struct eap_sm *sm, void *priv,
116189251Ssam				   struct eap_method_ret *ret,
117189251Ssam				   const struct wpabuf *reqData);
118189251Ssam
119189251Ssam	/**
120189251Ssam	 * isKeyAvailable - Find out whether EAP method has keying material
121189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
122189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
123189251Ssam	 * Returns: %TRUE if key material (eapKeyData) is available
124189251Ssam	 */
125189251Ssam	Boolean (*isKeyAvailable)(struct eap_sm *sm, void *priv);
126189251Ssam
127189251Ssam	/**
128189251Ssam	 * getKey - Get EAP method specific keying material (eapKeyData)
129189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
130189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
131189251Ssam	 * @len: Pointer to variable to store key length (eapKeyDataLen)
132189251Ssam	 * Returns: Keying material (eapKeyData) or %NULL if not available
133189251Ssam	 *
134189251Ssam	 * This function can be used to get the keying material from the EAP
135189251Ssam	 * method. The key may already be stored in the method-specific private
136189251Ssam	 * data or this function may derive the key.
137189251Ssam	 */
138189251Ssam	u8 * (*getKey)(struct eap_sm *sm, void *priv, size_t *len);
139189251Ssam
140189251Ssam	/**
141189251Ssam	 * get_status - Get EAP method status
142189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
143189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
144189251Ssam	 * @buf: Buffer for status information
145189251Ssam	 * @buflen: Maximum buffer length
146189251Ssam	 * @verbose: Whether to include verbose status information
147189251Ssam	 * Returns: Number of bytes written to buf
148189251Ssam	 *
149189251Ssam	 * Query EAP method for status information. This function fills in a
150189251Ssam	 * text area with current status information from the EAP method. If
151189251Ssam	 * the buffer (buf) is not large enough, status information will be
152189251Ssam	 * truncated to fit the buffer.
153189251Ssam	 */
154189251Ssam	int (*get_status)(struct eap_sm *sm, void *priv, char *buf,
155189251Ssam			  size_t buflen, int verbose);
156189251Ssam
157189251Ssam	/**
158189251Ssam	 * has_reauth_data - Whether method is ready for fast reauthentication
159189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
160189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
161189251Ssam	 * Returns: %TRUE or %FALSE based on whether fast reauthentication is
162189251Ssam	 * possible
163189251Ssam	 *
164189251Ssam	 * This function is an optional handler that only EAP methods
165189251Ssam	 * supporting fast re-authentication need to implement.
166189251Ssam	 */
167189251Ssam	Boolean (*has_reauth_data)(struct eap_sm *sm, void *priv);
168189251Ssam
169189251Ssam	/**
170189251Ssam	 * deinit_for_reauth - Release data that is not needed for fast re-auth
171189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
172189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
173189251Ssam	 *
174189251Ssam	 * This function is an optional handler that only EAP methods
175189251Ssam	 * supporting fast re-authentication need to implement. This is called
176189251Ssam	 * when authentication has been completed and EAP state machine is
177189251Ssam	 * requesting that enough state information is maintained for fast
178189251Ssam	 * re-authentication
179189251Ssam	 */
180189251Ssam	void (*deinit_for_reauth)(struct eap_sm *sm, void *priv);
181189251Ssam
182189251Ssam	/**
183189251Ssam	 * init_for_reauth - Prepare for start of fast re-authentication
184189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
185189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
186189251Ssam	 *
187189251Ssam	 * This function is an optional handler that only EAP methods
188189251Ssam	 * supporting fast re-authentication need to implement. This is called
189189251Ssam	 * when EAP authentication is started and EAP state machine is
190189251Ssam	 * requesting fast re-authentication to be used.
191189251Ssam	 */
192189251Ssam	void * (*init_for_reauth)(struct eap_sm *sm, void *priv);
193189251Ssam
194189251Ssam	/**
195189251Ssam	 * get_identity - Get method specific identity for re-authentication
196189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
197189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
198189251Ssam	 * @len: Length of the returned identity
199189251Ssam	 * Returns: Pointer to the method specific identity or %NULL if default
200189251Ssam	 * identity is to be used
201189251Ssam	 *
202189251Ssam	 * This function is an optional handler that only EAP methods
203189251Ssam	 * that use method specific identity need to implement.
204189251Ssam	 */
205189251Ssam	const u8 * (*get_identity)(struct eap_sm *sm, void *priv, size_t *len);
206189251Ssam
207189251Ssam	/**
208189251Ssam	 * free - Free EAP method data
209189251Ssam	 * @method: Pointer to the method data registered with
210189251Ssam	 * eap_peer_method_register().
211189251Ssam	 *
212189251Ssam	 * This function will be called when the EAP method is being
213189251Ssam	 * unregistered. If the EAP method allocated resources during
214189251Ssam	 * registration (e.g., allocated struct eap_method), they should be
215189251Ssam	 * freed in this function. No other method functions will be called
216189251Ssam	 * after this call. If this function is not defined (i.e., function
217189251Ssam	 * pointer is %NULL), a default handler is used to release the method
218189251Ssam	 * data with free(method). This is suitable for most cases.
219189251Ssam	 */
220189251Ssam	void (*free)(struct eap_method *method);
221189251Ssam
222189251Ssam#define EAP_PEER_METHOD_INTERFACE_VERSION 1
223189251Ssam	/**
224189251Ssam	 * version - Version of the EAP peer method interface
225189251Ssam	 *
226189251Ssam	 * The EAP peer method implementation should set this variable to
227189251Ssam	 * EAP_PEER_METHOD_INTERFACE_VERSION. This is used to verify that the
228189251Ssam	 * EAP method is using supported API version when using dynamically
229189251Ssam	 * loadable EAP methods.
230189251Ssam	 */
231189251Ssam	int version;
232189251Ssam
233189251Ssam	/**
234189251Ssam	 * next - Pointer to the next EAP method
235189251Ssam	 *
236189251Ssam	 * This variable is used internally in the EAP method registration code
237189251Ssam	 * to create a linked list of registered EAP methods.
238189251Ssam	 */
239189251Ssam	struct eap_method *next;
240189251Ssam
241189251Ssam#ifdef CONFIG_DYNAMIC_EAP_METHODS
242189251Ssam	/**
243189251Ssam	 * dl_handle - Handle for the dynamic library
244189251Ssam	 *
245189251Ssam	 * This variable is used internally in the EAP method registration code
246189251Ssam	 * to store a handle for the dynamic library. If the method is linked
247189251Ssam	 * in statically, this is %NULL.
248189251Ssam	 */
249189251Ssam	void *dl_handle;
250189251Ssam#endif /* CONFIG_DYNAMIC_EAP_METHODS */
251189251Ssam
252189251Ssam	/**
253189251Ssam	 * get_emsk - Get EAP method specific keying extended material (EMSK)
254189251Ssam	 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
255189251Ssam	 * @priv: Pointer to private EAP method data from eap_method::init()
256189251Ssam	 * @len: Pointer to a variable to store EMSK length
257189251Ssam	 * Returns: EMSK or %NULL if not available
258189251Ssam	 *
259189251Ssam	 * This function can be used to get the extended keying material from
260189251Ssam	 * the EAP method. The key may already be stored in the method-specific
261189251Ssam	 * private data or this function may derive the key.
262189251Ssam	 */
263189251Ssam	u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len);
264189251Ssam};
265189251Ssam
266189251Ssam
267189251Ssam/**
268189251Ssam * struct eap_sm - EAP state machine data
269189251Ssam */
270189251Ssamstruct eap_sm {
271189251Ssam	enum {
272189251Ssam		EAP_INITIALIZE, EAP_DISABLED, EAP_IDLE, EAP_RECEIVED,
273189251Ssam		EAP_GET_METHOD, EAP_METHOD, EAP_SEND_RESPONSE, EAP_DISCARD,
274189251Ssam		EAP_IDENTITY, EAP_NOTIFICATION, EAP_RETRANSMIT, EAP_SUCCESS,
275189251Ssam		EAP_FAILURE
276189251Ssam	} EAP_state;
277189251Ssam	/* Long-term local variables */
278189251Ssam	EapType selectedMethod;
279189251Ssam	EapMethodState methodState;
280189251Ssam	int lastId;
281189251Ssam	struct wpabuf *lastRespData;
282189251Ssam	EapDecision decision;
283189251Ssam	/* Short-term local variables */
284189251Ssam	Boolean rxReq;
285189251Ssam	Boolean rxSuccess;
286189251Ssam	Boolean rxFailure;
287189251Ssam	int reqId;
288189251Ssam	EapType reqMethod;
289189251Ssam	int reqVendor;
290189251Ssam	u32 reqVendorMethod;
291189251Ssam	Boolean ignore;
292189251Ssam	/* Constants */
293189251Ssam	int ClientTimeout;
294189251Ssam
295189251Ssam	/* Miscellaneous variables */
296189251Ssam	Boolean allowNotifications; /* peer state machine <-> methods */
297189251Ssam	struct wpabuf *eapRespData; /* peer to lower layer */
298189251Ssam	Boolean eapKeyAvailable; /* peer to lower layer */
299189251Ssam	u8 *eapKeyData; /* peer to lower layer */
300189251Ssam	size_t eapKeyDataLen; /* peer to lower layer */
301189251Ssam	const struct eap_method *m; /* selected EAP method */
302189251Ssam	/* not defined in RFC 4137 */
303189251Ssam	Boolean changed;
304189251Ssam	void *eapol_ctx;
305189251Ssam	struct eapol_callbacks *eapol_cb;
306189251Ssam	void *eap_method_priv;
307189251Ssam	int init_phase2;
308189251Ssam	int fast_reauth;
309189251Ssam
310189251Ssam	Boolean rxResp /* LEAP only */;
311189251Ssam	Boolean leap_done;
312189251Ssam	Boolean peap_done;
313189251Ssam	u8 req_md5[16]; /* MD5() of the current EAP packet */
314189251Ssam	u8 last_md5[16]; /* MD5() of the previously received EAP packet; used
315189251Ssam			  * in duplicate request detection. */
316189251Ssam
317189251Ssam	void *msg_ctx;
318189251Ssam	void *scard_ctx;
319189251Ssam	void *ssl_ctx;
320252726Srpaulo	void *ssl_ctx2;
321189251Ssam
322189251Ssam	unsigned int workaround;
323189251Ssam
324189251Ssam	/* Optional challenges generated in Phase 1 (EAP-FAST) */
325189251Ssam	u8 *peer_challenge, *auth_challenge;
326189251Ssam
327189251Ssam	int num_rounds;
328189251Ssam	int force_disabled;
329189251Ssam
330189251Ssam	struct wps_context *wps;
331189251Ssam
332189251Ssam	int prev_failure;
333252726Srpaulo
334252726Srpaulo	struct ext_password_data *ext_pw;
335252726Srpaulo	struct wpabuf *ext_pw_buf;
336189251Ssam};
337189251Ssam
338189251Ssamconst u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
339189251Ssamconst u8 * eap_get_config_password(struct eap_sm *sm, size_t *len);
340189251Ssamconst u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash);
341189251Ssamconst u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len);
342189251Ssamconst u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len);
343189251Ssamvoid eap_clear_config_otp(struct eap_sm *sm);
344189251Ssamconst char * eap_get_config_phase1(struct eap_sm *sm);
345189251Ssamconst char * eap_get_config_phase2(struct eap_sm *sm);
346252726Srpauloint eap_get_config_fragment_size(struct eap_sm *sm);
347189251Ssamstruct eap_peer_config * eap_get_config(struct eap_sm *sm);
348189251Ssamvoid eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob);
349189251Ssamconst struct wpa_config_blob *
350189251Ssameap_get_config_blob(struct eap_sm *sm, const char *name);
351189251Ssamvoid eap_notify_pending(struct eap_sm *sm);
352189251Ssamint eap_allowed_method(struct eap_sm *sm, int vendor, u32 method);
353189251Ssam
354189251Ssam#endif /* EAP_I_H */
355