1189251Ssam/* 2189251Ssam * EAPOL supplicant state machines 3252726Srpaulo * Copyright (c) 2004-2012, 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 EAPOL_SUPP_SM_H 10189251Ssam#define EAPOL_SUPP_SM_H 11189251Ssam 12214734Srpaulo#include "common/defs.h" 13189251Ssam 14189251Ssamtypedef enum { Unauthorized, Authorized } PortStatus; 15189251Ssamtypedef enum { Auto, ForceUnauthorized, ForceAuthorized } PortControl; 16189251Ssam 17189251Ssam/** 18189251Ssam * struct eapol_config - Per network configuration for EAPOL state machines 19189251Ssam */ 20189251Ssamstruct eapol_config { 21189251Ssam /** 22189251Ssam * accept_802_1x_keys - Accept IEEE 802.1X (non-WPA) EAPOL-Key frames 23189251Ssam * 24189251Ssam * This variable should be set to 1 when using EAPOL state machines 25189251Ssam * with non-WPA security policy to generate dynamic WEP keys. When 26189251Ssam * using WPA, this should be set to 0 so that WPA state machine can 27189251Ssam * process the EAPOL-Key frames. 28189251Ssam */ 29189251Ssam int accept_802_1x_keys; 30189251Ssam 31189251Ssam#define EAPOL_REQUIRE_KEY_UNICAST BIT(0) 32189251Ssam#define EAPOL_REQUIRE_KEY_BROADCAST BIT(1) 33189251Ssam /** 34189251Ssam * required_keys - Which EAPOL-Key packets are required 35189251Ssam * 36189251Ssam * This variable determines which EAPOL-Key packets are required before 37189251Ssam * marking connection authenticated. This is a bit field of 38189251Ssam * EAPOL_REQUIRE_KEY_UNICAST and EAPOL_REQUIRE_KEY_BROADCAST flags. 39189251Ssam */ 40189251Ssam int required_keys; 41189251Ssam 42189251Ssam /** 43189251Ssam * fast_reauth - Whether fast EAP reauthentication is enabled 44189251Ssam */ 45189251Ssam int fast_reauth; 46189251Ssam 47189251Ssam /** 48189251Ssam * workaround - Whether EAP workarounds are enabled 49189251Ssam */ 50189251Ssam unsigned int workaround; 51189251Ssam 52189251Ssam /** 53189251Ssam * eap_disabled - Whether EAP is disabled 54189251Ssam */ 55189251Ssam int eap_disabled; 56189251Ssam}; 57189251Ssam 58189251Ssamstruct eapol_sm; 59189251Ssamstruct wpa_config_blob; 60189251Ssam 61189251Ssam/** 62189251Ssam * struct eapol_ctx - Global (for all networks) EAPOL state machine context 63189251Ssam */ 64189251Ssamstruct eapol_ctx { 65189251Ssam /** 66189251Ssam * ctx - Pointer to arbitrary upper level context 67189251Ssam */ 68189251Ssam void *ctx; 69189251Ssam 70189251Ssam /** 71189251Ssam * preauth - IEEE 802.11i/RSN pre-authentication 72189251Ssam * 73189251Ssam * This EAPOL state machine is used for IEEE 802.11i/RSN 74189251Ssam * pre-authentication 75189251Ssam */ 76189251Ssam int preauth; 77189251Ssam 78189251Ssam /** 79189251Ssam * cb - Function to be called when EAPOL negotiation has been completed 80189251Ssam * @eapol: Pointer to EAPOL state machine data 81189251Ssam * @success: Whether the authentication was completed successfully 82189251Ssam * @ctx: Pointer to context data (cb_ctx) 83189251Ssam * 84189251Ssam * This optional callback function will be called when the EAPOL 85189251Ssam * authentication has been completed. This allows the owner of the 86189251Ssam * EAPOL state machine to process the key and terminate the EAPOL state 87189251Ssam * machine. Currently, this is used only in RSN pre-authentication. 88189251Ssam */ 89189251Ssam void (*cb)(struct eapol_sm *eapol, int success, void *ctx); 90189251Ssam 91189251Ssam /** 92189251Ssam * cb_ctx - Callback context for cb() 93189251Ssam */ 94189251Ssam void *cb_ctx; 95189251Ssam 96189251Ssam /** 97189251Ssam * msg_ctx - Callback context for wpa_msg() calls 98189251Ssam */ 99189251Ssam void *msg_ctx; 100189251Ssam 101189251Ssam /** 102189251Ssam * scard_ctx - Callback context for PC/SC scard_*() function calls 103189251Ssam * 104189251Ssam * This context can be updated with eapol_sm_register_scard_ctx(). 105189251Ssam */ 106189251Ssam void *scard_ctx; 107189251Ssam 108189251Ssam /** 109189251Ssam * eapol_send_ctx - Callback context for eapol_send() calls 110189251Ssam */ 111189251Ssam void *eapol_send_ctx; 112189251Ssam 113189251Ssam /** 114189251Ssam * eapol_done_cb - Function to be called at successful completion 115189251Ssam * @ctx: Callback context (ctx) 116189251Ssam * 117189251Ssam * This function is called at the successful completion of EAPOL 118189251Ssam * authentication. If dynamic WEP keys are used, this is called only 119189251Ssam * after all the expected keys have been received. 120189251Ssam */ 121189251Ssam void (*eapol_done_cb)(void *ctx); 122189251Ssam 123189251Ssam /** 124189251Ssam * eapol_send - Send EAPOL packets 125189251Ssam * @ctx: Callback context (eapol_send_ctx) 126189251Ssam * @type: EAPOL type (IEEE802_1X_TYPE_*) 127189251Ssam * @buf: Pointer to EAPOL payload 128189251Ssam * @len: Length of the EAPOL payload 129189251Ssam * Returns: 0 on success, -1 on failure 130189251Ssam */ 131189251Ssam int (*eapol_send)(void *ctx, int type, const u8 *buf, size_t len); 132189251Ssam 133189251Ssam /** 134189251Ssam * set_wep_key - Configure WEP keys 135189251Ssam * @ctx: Callback context (ctx) 136189251Ssam * @unicast: Non-zero = unicast, 0 = multicast/broadcast key 137189251Ssam * @keyidx: Key index (0..3) 138189251Ssam * @key: WEP key 139189251Ssam * @keylen: Length of the WEP key 140189251Ssam * Returns: 0 on success, -1 on failure 141189251Ssam */ 142189251Ssam int (*set_wep_key)(void *ctx, int unicast, int keyidx, 143189251Ssam const u8 *key, size_t keylen); 144189251Ssam 145189251Ssam /** 146189251Ssam * set_config_blob - Set or add a named configuration blob 147189251Ssam * @ctx: Callback context (ctx) 148189251Ssam * @blob: New value for the blob 149189251Ssam * 150189251Ssam * Adds a new configuration blob or replaces the current value of an 151189251Ssam * existing blob. 152189251Ssam */ 153189251Ssam void (*set_config_blob)(void *ctx, struct wpa_config_blob *blob); 154189251Ssam 155189251Ssam /** 156189251Ssam * get_config_blob - Get a named configuration blob 157189251Ssam * @ctx: Callback context (ctx) 158189251Ssam * @name: Name of the blob 159189251Ssam * Returns: Pointer to blob data or %NULL if not found 160189251Ssam */ 161189251Ssam const struct wpa_config_blob * (*get_config_blob)(void *ctx, 162189251Ssam const char *name); 163189251Ssam 164189251Ssam /** 165189251Ssam * aborted_cached - Notify that cached PMK attempt was aborted 166189251Ssam * @ctx: Callback context (ctx) 167189251Ssam */ 168189251Ssam void (*aborted_cached)(void *ctx); 169189251Ssam 170189251Ssam /** 171189251Ssam * opensc_engine_path - Path to the OpenSSL engine for opensc 172189251Ssam * 173189251Ssam * This is an OpenSSL specific configuration option for loading OpenSC 174189251Ssam * engine (engine_opensc.so); if %NULL, this engine is not loaded. 175189251Ssam */ 176189251Ssam const char *opensc_engine_path; 177189251Ssam 178189251Ssam /** 179189251Ssam * pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11 180189251Ssam * 181189251Ssam * This is an OpenSSL specific configuration option for loading PKCS#11 182189251Ssam * engine (engine_pkcs11.so); if %NULL, this engine is not loaded. 183189251Ssam */ 184189251Ssam const char *pkcs11_engine_path; 185189251Ssam 186189251Ssam /** 187189251Ssam * pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module 188189251Ssam * 189189251Ssam * This is an OpenSSL specific configuration option for configuring 190189251Ssam * path to OpenSC/PKCS#11 engine (opensc-pkcs11.so); if %NULL, this 191189251Ssam * module is not loaded. 192189251Ssam */ 193189251Ssam const char *pkcs11_module_path; 194189251Ssam 195189251Ssam /** 196189251Ssam * wps - WPS context data 197189251Ssam * 198189251Ssam * This is only used by EAP-WSC and can be left %NULL if not available. 199189251Ssam */ 200189251Ssam struct wps_context *wps; 201189251Ssam 202189251Ssam /** 203189251Ssam * eap_param_needed - Notify that EAP parameter is needed 204189251Ssam * @ctx: Callback context (ctx) 205252726Srpaulo * @field: Field indicator (e.g., WPA_CTRL_REQ_EAP_IDENTITY) 206189251Ssam * @txt: User readable text describing the required parameter 207189251Ssam */ 208252726Srpaulo void (*eap_param_needed)(void *ctx, enum wpa_ctrl_req_type field, 209189251Ssam const char *txt); 210214734Srpaulo 211214734Srpaulo /** 212214734Srpaulo * port_cb - Set port authorized/unauthorized callback (optional) 213214734Srpaulo * @ctx: Callback context (ctx) 214214734Srpaulo * @authorized: Whether the supplicant port is now in authorized state 215214734Srpaulo */ 216214734Srpaulo void (*port_cb)(void *ctx, int authorized); 217252726Srpaulo 218252726Srpaulo /** 219252726Srpaulo * cert_cb - Notification of a peer certificate 220252726Srpaulo * @ctx: Callback context (ctx) 221252726Srpaulo * @depth: Depth in certificate chain (0 = server) 222252726Srpaulo * @subject: Subject of the peer certificate 223252726Srpaulo * @cert_hash: SHA-256 hash of the certificate 224252726Srpaulo * @cert: Peer certificate 225252726Srpaulo */ 226252726Srpaulo void (*cert_cb)(void *ctx, int depth, const char *subject, 227252726Srpaulo const char *cert_hash, const struct wpabuf *cert); 228252726Srpaulo 229252726Srpaulo /** 230252726Srpaulo * cert_in_cb - Include server certificates in callback 231252726Srpaulo */ 232252726Srpaulo int cert_in_cb; 233252726Srpaulo 234252726Srpaulo /** 235252726Srpaulo * status_cb - Notification of a change in EAP status 236252726Srpaulo * @ctx: Callback context (ctx) 237252726Srpaulo * @status: Step in the process of EAP authentication 238252726Srpaulo * @parameter: Step-specific parameter, e.g., EAP method name 239252726Srpaulo */ 240252726Srpaulo void (*status_cb)(void *ctx, const char *status, 241252726Srpaulo const char *parameter); 242252726Srpaulo 243252726Srpaulo /** 244252726Srpaulo * set_anon_id - Set or add anonymous identity 245252726Srpaulo * @ctx: eapol_ctx from eap_peer_sm_init() call 246252726Srpaulo * @id: Anonymous identity (e.g., EAP-SIM pseudonym) 247252726Srpaulo * @len: Length of anonymous identity in octets 248252726Srpaulo */ 249252726Srpaulo void (*set_anon_id)(void *ctx, const u8 *id, size_t len); 250189251Ssam}; 251189251Ssam 252189251Ssam 253189251Ssamstruct eap_peer_config; 254252726Srpaulostruct ext_password_data; 255189251Ssam 256189251Ssam#ifdef IEEE8021X_EAPOL 257189251Ssamstruct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx); 258189251Ssamvoid eapol_sm_deinit(struct eapol_sm *sm); 259189251Ssamvoid eapol_sm_step(struct eapol_sm *sm); 260189251Ssamint eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen, 261189251Ssam int verbose); 262189251Ssamint eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen); 263189251Ssamvoid eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod, 264189251Ssam int startPeriod, int maxStart); 265189251Ssamint eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf, 266189251Ssam size_t len); 267189251Ssamvoid eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm); 268189251Ssamvoid eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled); 269189251Ssamvoid eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid); 270189251Ssamvoid eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success); 271189251Ssamvoid eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail); 272189251Ssamvoid eapol_sm_notify_config(struct eapol_sm *sm, 273189251Ssam struct eap_peer_config *config, 274189251Ssam const struct eapol_config *conf); 275189251Ssamint eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len); 276189251Ssamvoid eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff); 277189251Ssamvoid eapol_sm_notify_cached(struct eapol_sm *sm); 278189251Ssamvoid eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm, int attempt); 279189251Ssamvoid eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx); 280189251Ssamvoid eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl); 281189251Ssamvoid eapol_sm_notify_ctrl_attached(struct eapol_sm *sm); 282189251Ssamvoid eapol_sm_notify_ctrl_response(struct eapol_sm *sm); 283189251Ssamvoid eapol_sm_request_reauth(struct eapol_sm *sm); 284189251Ssamvoid eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm); 285189251Ssamvoid eapol_sm_invalidate_cached_session(struct eapol_sm *sm); 286252726Srpauloconst char * eapol_sm_get_method_name(struct eapol_sm *sm); 287252726Srpaulovoid eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, 288252726Srpaulo struct ext_password_data *ext); 289252726Srpauloint eapol_sm_failed(struct eapol_sm *sm); 290189251Ssam#else /* IEEE8021X_EAPOL */ 291189251Ssamstatic inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) 292189251Ssam{ 293189251Ssam free(ctx); 294189251Ssam return (struct eapol_sm *) 1; 295189251Ssam} 296189251Ssamstatic inline void eapol_sm_deinit(struct eapol_sm *sm) 297189251Ssam{ 298189251Ssam} 299189251Ssamstatic inline void eapol_sm_step(struct eapol_sm *sm) 300189251Ssam{ 301189251Ssam} 302189251Ssamstatic inline int eapol_sm_get_status(struct eapol_sm *sm, char *buf, 303189251Ssam size_t buflen, int verbose) 304189251Ssam{ 305189251Ssam return 0; 306189251Ssam} 307189251Ssamstatic inline int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, 308189251Ssam size_t buflen) 309189251Ssam{ 310189251Ssam return 0; 311189251Ssam} 312189251Ssamstatic inline void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, 313189251Ssam int authPeriod, int startPeriod, 314189251Ssam int maxStart) 315189251Ssam{ 316189251Ssam} 317189251Ssamstatic inline int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, 318189251Ssam const u8 *buf, size_t len) 319189251Ssam{ 320189251Ssam return 0; 321189251Ssam} 322189251Ssamstatic inline void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm) 323189251Ssam{ 324189251Ssam} 325189251Ssamstatic inline void eapol_sm_notify_portEnabled(struct eapol_sm *sm, 326189251Ssam Boolean enabled) 327189251Ssam{ 328189251Ssam} 329189251Ssamstatic inline void eapol_sm_notify_portValid(struct eapol_sm *sm, 330189251Ssam Boolean valid) 331189251Ssam{ 332189251Ssam} 333189251Ssamstatic inline void eapol_sm_notify_eap_success(struct eapol_sm *sm, 334189251Ssam Boolean success) 335189251Ssam{ 336189251Ssam} 337189251Ssamstatic inline void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail) 338189251Ssam{ 339189251Ssam} 340189251Ssamstatic inline void eapol_sm_notify_config(struct eapol_sm *sm, 341189251Ssam struct eap_peer_config *config, 342189251Ssam struct eapol_config *conf) 343189251Ssam{ 344189251Ssam} 345189251Ssamstatic inline int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len) 346189251Ssam{ 347189251Ssam return -1; 348189251Ssam} 349189251Ssamstatic inline void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff) 350189251Ssam{ 351189251Ssam} 352189251Ssamstatic inline void eapol_sm_notify_cached(struct eapol_sm *sm) 353189251Ssam{ 354189251Ssam} 355189251Ssam#define eapol_sm_notify_pmkid_attempt(sm, attempt) do { } while (0) 356189251Ssam#define eapol_sm_register_scard_ctx(sm, ctx) do { } while (0) 357189251Ssamstatic inline void eapol_sm_notify_portControl(struct eapol_sm *sm, 358189251Ssam PortControl portControl) 359189251Ssam{ 360189251Ssam} 361189251Ssamstatic inline void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm) 362189251Ssam{ 363189251Ssam} 364189251Ssamstatic inline void eapol_sm_notify_ctrl_response(struct eapol_sm *sm) 365189251Ssam{ 366189251Ssam} 367189251Ssamstatic inline void eapol_sm_request_reauth(struct eapol_sm *sm) 368189251Ssam{ 369189251Ssam} 370189251Ssamstatic inline void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, 371189251Ssam int in_eapol_sm) 372189251Ssam{ 373189251Ssam} 374189251Ssamstatic inline void eapol_sm_invalidate_cached_session(struct eapol_sm *sm) 375189251Ssam{ 376189251Ssam} 377252726Srpaulostatic inline const char * eapol_sm_get_method_name(struct eapol_sm *sm) 378252726Srpaulo{ 379252726Srpaulo return NULL; 380252726Srpaulo} 381252726Srpaulostatic inline void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, 382252726Srpaulo struct ext_password_data *ext) 383252726Srpaulo{ 384252726Srpaulo} 385252726Srpaulostatic inline int eapol_sm_failed(struct eapol_sm *sm) 386252726Srpaulo{ 387252726Srpaulo return 0; 388252726Srpaulo} 389189251Ssam#endif /* IEEE8021X_EAPOL */ 390189251Ssam 391189251Ssam#endif /* EAPOL_SUPP_SM_H */ 392