18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / EAP Authenticator state machine internal structures (RFC 4137)
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef EAP_I_H
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_I_H
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpabuf.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_common.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* RFC 4137 - EAP Standalone Authenticator */
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct eap_method - EAP method interface
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This structure defines the EAP method interface. Each method will need to
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * register its own EAP type, EAP name, and set of function pointers for method
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * specific operations. This interface is based on section 5.4 of RFC 4137.
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_method {
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int vendor;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EapType method;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *name;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void * (*init)(struct eap_sm *sm);
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void * (*initPickUp)(struct eap_sm *sm);
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void (*reset)(struct eap_sm *sm, void *priv);
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf * (*buildReq)(struct eap_sm *sm, void *priv, u8 id);
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int (*getTimeout)(struct eap_sm *sm, void *priv);
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean (*check)(struct eap_sm *sm, void *priv,
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 struct wpabuf *respData);
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void (*process)(struct eap_sm *sm, void *priv,
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			struct wpabuf *respData);
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean (*isDone)(struct eap_sm *sm, void *priv);
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 * (*getKey)(struct eap_sm *sm, void *priv, size_t *len);
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* isSuccess is not specified in draft-ietf-eap-statemachine-05.txt,
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * but it is useful in implementing Policy.getDecision() */
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean (*isSuccess)(struct eap_sm *sm, void *priv);
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/**
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * free - Free EAP method data
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * @method: Pointer to the method data registered with
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * eap_server_method_register().
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * This function will be called when the EAP method is being
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * unregistered. If the EAP method allocated resources during
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * registration (e.g., allocated struct eap_method), they should be
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * freed in this function. No other method functions will be called
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * after this call. If this function is not defined (i.e., function
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * pointer is %NULL), a default handler is used to release the method
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * data with free(method). This is suitable for most cases.
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void (*free)(struct eap_method *method);
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_SERVER_METHOD_INTERFACE_VERSION 1
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/**
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * version - Version of the EAP server method interface
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * The EAP server method implementation should set this variable to
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * EAP_SERVER_METHOD_INTERFACE_VERSION. This is used to verify that the
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * EAP method is using supported API version when using dynamically
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * loadable EAP methods.
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int version;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/**
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * next - Pointer to the next EAP method
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * This variable is used internally in the EAP method registration code
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * to create a linked list of registered EAP methods.
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eap_method *next;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/**
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * get_emsk - Get EAP method specific keying extended material (EMSK)
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * @priv: Pointer to private EAP method data from eap_method::init()
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * @len: Pointer to a variable to store EMSK length
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Returns: EMSK or %NULL if not available
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * This function can be used to get the extended keying material from
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * the EAP method. The key may already be stored in the method-specific
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * private data or this function may derive the key.
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len);
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct eap_sm - EAP server state machine data
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sm {
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum {
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_DISABLED, EAP_INITIALIZE, EAP_IDLE, EAP_RECEIVED,
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_INTEGRITY_CHECK, EAP_METHOD_RESPONSE, EAP_METHOD_REQUEST,
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_PROPOSE_METHOD, EAP_SELECT_ACTION, EAP_SEND_REQUEST,
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_DISCARD, EAP_NAK, EAP_RETRANSMIT, EAP_SUCCESS, EAP_FAILURE,
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_TIMEOUT_FAILURE, EAP_PICK_UP_METHOD,
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_INITIALIZE_PASSTHROUGH, EAP_IDLE2, EAP_RETRANSMIT2,
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_RECEIVED2, EAP_DISCARD2, EAP_SEND_REQUEST2,
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_AAA_REQUEST, EAP_AAA_RESPONSE, EAP_AAA_IDLE,
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		EAP_TIMEOUT_FAILURE2, EAP_FAILURE2, EAP_SUCCESS2
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} EAP_state;
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Constants */
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int MaxRetrans;
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eap_eapol_interface eap_if;
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Full authenticator state machine local variables */
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Long-term (maintained between packets) */
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EapType currentMethod;
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int currentId;
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum {
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		METHOD_PROPOSED, METHOD_CONTINUE, METHOD_END
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} methodState;
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int retransCount;
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *lastReqData;
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int methodTimeout;
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Short-term (not maintained between packets) */
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean rxResp;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int respId;
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EapType respMethod;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int respVendor;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 respVendorMethod;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean ignore;
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum {
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DECISION_SUCCESS, DECISION_FAILURE, DECISION_CONTINUE,
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DECISION_PASSTHROUGH
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} decision;
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Miscellaneous variables */
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct eap_method *m; /* selected EAP method */
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* not defined in RFC 4137 */
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean changed;
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *eapol_ctx, *msg_ctx;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eapol_callbacks *eapol_cb;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *eap_method_priv;
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *identity;
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t identity_len;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Whether Phase 2 method should validate identity match */
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int require_identity_match;
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int lastId; /* Identifier used in the last EAP-Packet */
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eap_user *user;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int user_eap_method_index;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int init_phase2;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *ssl_ctx;
1544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt	struct eap_sim_db_data *eap_sim_db_priv;
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean backend_auth;
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean update_user;
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int eap_server;
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int num_rounds;
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum {
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		METHOD_PENDING_NONE, METHOD_PENDING_WAIT, METHOD_PENDING_CONT
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} method_pending;
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *auth_challenge;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *peer_challenge;
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *pac_opaque_encr_key;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *eap_fast_a_id;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t eap_fast_a_id_len;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *eap_fast_a_id_info;
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum {
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		NO_PROV, ANON_PROV, AUTH_PROV, BOTH_PROV
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} eap_fast_prov;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pac_key_lifetime;
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pac_key_refresh_time;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int eap_sim_aka_result_ind;
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int tnc;
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 pwd_group;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_context *wps;
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *assoc_wps_ie;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *assoc_p2p_ie;
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	Boolean start_reauth;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer_addr[ETH_ALEN];
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Fragmentation size for EAP method init() handler */
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int fragment_size;
18987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen
19087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	int pbc_in_m1;
19134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
19234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	const u8 *server_id;
19334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	size_t server_id_len;
194818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
195818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
196818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	u32 tls_test_flags;
197818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 int phase2);
202818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid eap_log_msg(struct eap_sm *sm, const char *fmt, ...)
203818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry ShmidtPRINTF_FORMAT(2, 3);
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len);
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_I_H */
207