18dbcf02cSchristos /* 28dbcf02cSchristos * hostapd / EAP Authenticator state machine internal structures (RFC 4137) 38dbcf02cSchristos * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 48dbcf02cSchristos * 5e604d861Schristos * This software may be distributed under the terms of the BSD license. 6e604d861Schristos * See README for more details. 78dbcf02cSchristos */ 88dbcf02cSchristos 98dbcf02cSchristos #ifndef EAP_I_H 108dbcf02cSchristos #define EAP_I_H 118dbcf02cSchristos 128dbcf02cSchristos #include "wpabuf.h" 138dbcf02cSchristos #include "eap_server/eap.h" 148dbcf02cSchristos #include "eap_common/eap_common.h" 158dbcf02cSchristos 168dbcf02cSchristos /* RFC 4137 - EAP Standalone Authenticator */ 178dbcf02cSchristos 188dbcf02cSchristos /** 198dbcf02cSchristos * struct eap_method - EAP method interface 208dbcf02cSchristos * This structure defines the EAP method interface. Each method will need to 218dbcf02cSchristos * register its own EAP type, EAP name, and set of function pointers for method 228dbcf02cSchristos * specific operations. This interface is based on section 5.4 of RFC 4137. 238dbcf02cSchristos */ 248dbcf02cSchristos struct eap_method { 258dbcf02cSchristos int vendor; 26*bb618362Schristos enum eap_type method; 278dbcf02cSchristos const char *name; 288dbcf02cSchristos 298dbcf02cSchristos void * (*init)(struct eap_sm *sm); 308dbcf02cSchristos void * (*initPickUp)(struct eap_sm *sm); 318dbcf02cSchristos void (*reset)(struct eap_sm *sm, void *priv); 328dbcf02cSchristos 338dbcf02cSchristos struct wpabuf * (*buildReq)(struct eap_sm *sm, void *priv, u8 id); 348dbcf02cSchristos int (*getTimeout)(struct eap_sm *sm, void *priv); 35*bb618362Schristos bool (*check)(struct eap_sm *sm, void *priv, struct wpabuf *respData); 368dbcf02cSchristos void (*process)(struct eap_sm *sm, void *priv, 378dbcf02cSchristos struct wpabuf *respData); 38*bb618362Schristos bool (*isDone)(struct eap_sm *sm, void *priv); 398dbcf02cSchristos u8 * (*getKey)(struct eap_sm *sm, void *priv, size_t *len); 408dbcf02cSchristos /* isSuccess is not specified in draft-ietf-eap-statemachine-05.txt, 418dbcf02cSchristos * but it is useful in implementing Policy.getDecision() */ 42*bb618362Schristos bool (*isSuccess)(struct eap_sm *sm, void *priv); 438dbcf02cSchristos 448dbcf02cSchristos /** 458dbcf02cSchristos * free - Free EAP method data 468dbcf02cSchristos * @method: Pointer to the method data registered with 478dbcf02cSchristos * eap_server_method_register(). 488dbcf02cSchristos * 498dbcf02cSchristos * This function will be called when the EAP method is being 508dbcf02cSchristos * unregistered. If the EAP method allocated resources during 518dbcf02cSchristos * registration (e.g., allocated struct eap_method), they should be 528dbcf02cSchristos * freed in this function. No other method functions will be called 538dbcf02cSchristos * after this call. If this function is not defined (i.e., function 548dbcf02cSchristos * pointer is %NULL), a default handler is used to release the method 558dbcf02cSchristos * data with free(method). This is suitable for most cases. 568dbcf02cSchristos */ 578dbcf02cSchristos void (*free)(struct eap_method *method); 588dbcf02cSchristos 598dbcf02cSchristos #define EAP_SERVER_METHOD_INTERFACE_VERSION 1 608dbcf02cSchristos /** 618dbcf02cSchristos * version - Version of the EAP server method interface 628dbcf02cSchristos * 638dbcf02cSchristos * The EAP server method implementation should set this variable to 648dbcf02cSchristos * EAP_SERVER_METHOD_INTERFACE_VERSION. This is used to verify that the 658dbcf02cSchristos * EAP method is using supported API version when using dynamically 668dbcf02cSchristos * loadable EAP methods. 678dbcf02cSchristos */ 688dbcf02cSchristos int version; 698dbcf02cSchristos 708dbcf02cSchristos /** 718dbcf02cSchristos * next - Pointer to the next EAP method 728dbcf02cSchristos * 738dbcf02cSchristos * This variable is used internally in the EAP method registration code 748dbcf02cSchristos * to create a linked list of registered EAP methods. 758dbcf02cSchristos */ 768dbcf02cSchristos struct eap_method *next; 778dbcf02cSchristos 788dbcf02cSchristos /** 798dbcf02cSchristos * get_emsk - Get EAP method specific keying extended material (EMSK) 808dbcf02cSchristos * @sm: Pointer to EAP state machine allocated with eap_sm_init() 818dbcf02cSchristos * @priv: Pointer to private EAP method data from eap_method::init() 828dbcf02cSchristos * @len: Pointer to a variable to store EMSK length 838dbcf02cSchristos * Returns: EMSK or %NULL if not available 848dbcf02cSchristos * 858dbcf02cSchristos * This function can be used to get the extended keying material from 868dbcf02cSchristos * the EAP method. The key may already be stored in the method-specific 878dbcf02cSchristos * private data or this function may derive the key. 888dbcf02cSchristos */ 898dbcf02cSchristos u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len); 90bb610346Schristos 91bb610346Schristos /** 92bb610346Schristos * getSessionId - Get EAP method specific Session-Id 93bb610346Schristos * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 94bb610346Schristos * @priv: Pointer to private EAP method data from eap_method::init() 95bb610346Schristos * @len: Pointer to a variable to store Session-Id length 96bb610346Schristos * Returns: Session-Id or %NULL if not available 97bb610346Schristos * 98bb610346Schristos * This function can be used to get the Session-Id from the EAP method. 99bb610346Schristos * The Session-Id may already be stored in the method-specific private 100bb610346Schristos * data or this function may derive the Session-Id. 101bb610346Schristos */ 102bb610346Schristos u8 * (*getSessionId)(struct eap_sm *sm, void *priv, size_t *len); 1038dbcf02cSchristos }; 1048dbcf02cSchristos 1058dbcf02cSchristos /** 1068dbcf02cSchristos * struct eap_sm - EAP server state machine data 1078dbcf02cSchristos */ 1088dbcf02cSchristos struct eap_sm { 1098dbcf02cSchristos enum { 1108dbcf02cSchristos EAP_DISABLED, EAP_INITIALIZE, EAP_IDLE, EAP_RECEIVED, 1118dbcf02cSchristos EAP_INTEGRITY_CHECK, EAP_METHOD_RESPONSE, EAP_METHOD_REQUEST, 1128dbcf02cSchristos EAP_PROPOSE_METHOD, EAP_SELECT_ACTION, EAP_SEND_REQUEST, 1138dbcf02cSchristos EAP_DISCARD, EAP_NAK, EAP_RETRANSMIT, EAP_SUCCESS, EAP_FAILURE, 1148dbcf02cSchristos EAP_TIMEOUT_FAILURE, EAP_PICK_UP_METHOD, 1158dbcf02cSchristos EAP_INITIALIZE_PASSTHROUGH, EAP_IDLE2, EAP_RETRANSMIT2, 1168dbcf02cSchristos EAP_RECEIVED2, EAP_DISCARD2, EAP_SEND_REQUEST2, 1178dbcf02cSchristos EAP_AAA_REQUEST, EAP_AAA_RESPONSE, EAP_AAA_IDLE, 118bb610346Schristos EAP_TIMEOUT_FAILURE2, EAP_FAILURE2, EAP_SUCCESS2, 119bb610346Schristos EAP_INITIATE_REAUTH_START, EAP_INITIATE_RECEIVED 1208dbcf02cSchristos } EAP_state; 1218dbcf02cSchristos 1228dbcf02cSchristos /* Constants */ 1238dbcf02cSchristos int MaxRetrans; 1248dbcf02cSchristos 1258dbcf02cSchristos struct eap_eapol_interface eap_if; 1268dbcf02cSchristos 1278dbcf02cSchristos /* Full authenticator state machine local variables */ 1288dbcf02cSchristos 129111b9fd8Schristos /* Long-term (maintained between packets) */ 130*bb618362Schristos enum eap_type currentMethod; 1318dbcf02cSchristos int currentId; 1328dbcf02cSchristos enum { 1338dbcf02cSchristos METHOD_PROPOSED, METHOD_CONTINUE, METHOD_END 1348dbcf02cSchristos } methodState; 1358dbcf02cSchristos int retransCount; 1368dbcf02cSchristos struct wpabuf *lastReqData; 1378dbcf02cSchristos int methodTimeout; 1388dbcf02cSchristos 1398dbcf02cSchristos /* Short-term (not maintained between packets) */ 140*bb618362Schristos bool rxResp; 141*bb618362Schristos bool rxInitiate; 1428dbcf02cSchristos int respId; 143*bb618362Schristos enum eap_type respMethod; 1448dbcf02cSchristos int respVendor; 1458dbcf02cSchristos u32 respVendorMethod; 146*bb618362Schristos bool ignore; 1478dbcf02cSchristos enum { 1488dbcf02cSchristos DECISION_SUCCESS, DECISION_FAILURE, DECISION_CONTINUE, 149bb610346Schristos DECISION_PASSTHROUGH, DECISION_INITIATE_REAUTH_START 1508dbcf02cSchristos } decision; 1518dbcf02cSchristos 1528dbcf02cSchristos /* Miscellaneous variables */ 1538dbcf02cSchristos const struct eap_method *m; /* selected EAP method */ 1548dbcf02cSchristos /* not defined in RFC 4137 */ 155*bb618362Schristos bool changed; 156*bb618362Schristos void *eapol_ctx; 15736ebd06eSchristos const struct eapol_callbacks *eapol_cb; 1588dbcf02cSchristos void *eap_method_priv; 1598dbcf02cSchristos u8 *identity; 1608dbcf02cSchristos size_t identity_len; 1610a73ee0aSchristos char *serial_num; 1623d6c0713Schristos char imsi[20]; 163*bb618362Schristos char sim_aka_permanent[20]; 1648dbcf02cSchristos /* Whether Phase 2 method should validate identity match */ 1658dbcf02cSchristos int require_identity_match; 1668dbcf02cSchristos int lastId; /* Identifier used in the last EAP-Packet */ 1678dbcf02cSchristos struct eap_user *user; 1688dbcf02cSchristos int user_eap_method_index; 1698dbcf02cSchristos int init_phase2; 170*bb618362Schristos const struct eap_config *cfg; 171*bb618362Schristos struct eap_config cfg_buf; 172*bb618362Schristos bool update_user; 1738dbcf02cSchristos 174*bb618362Schristos unsigned int num_rounds; 175*bb618362Schristos unsigned int num_rounds_short; 1768dbcf02cSchristos enum { 1778dbcf02cSchristos METHOD_PENDING_NONE, METHOD_PENDING_WAIT, METHOD_PENDING_CONT 1788dbcf02cSchristos } method_pending; 1798dbcf02cSchristos 180*bb618362Schristos /* Optional challenges generated in Phase 1 (EAP-FAST) */ 1818dbcf02cSchristos u8 *auth_challenge; 1828dbcf02cSchristos u8 *peer_challenge; 1838dbcf02cSchristos 184*bb618362Schristos /* Whether to use the EAP-FAST-MSCHAPv2 instantiation of EAP-MSCHAPv2. 185*bb618362Schristos * That variant is otherwise identical, but it generates the MSK using 186*bb618362Schristos * MS-MPPE keys in reverse order. */ 187*bb618362Schristos bool eap_fast_mschapv2; 188*bb618362Schristos 1898dbcf02cSchristos struct wpabuf *assoc_wps_ie; 190111b9fd8Schristos struct wpabuf *assoc_p2p_ie; 1918dbcf02cSchristos 192*bb618362Schristos bool start_reauth; 1938dbcf02cSchristos 1948dbcf02cSchristos u8 peer_addr[ETH_ALEN]; 195111b9fd8Schristos 196*bb618362Schristos bool initiate_reauth_start_sent; 197*bb618362Schristos bool try_initiate_reauth; 198bb610346Schristos 1993c260e60Schristos #ifdef CONFIG_TESTING_OPTIONS 2003c260e60Schristos u32 tls_test_flags; 2013c260e60Schristos #endif /* CONFIG_TESTING_OPTIONS */ 2028dbcf02cSchristos }; 2038dbcf02cSchristos 2048dbcf02cSchristos int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len, 2058dbcf02cSchristos int phase2); 2063c260e60Schristos void eap_log_msg(struct eap_sm *sm, const char *fmt, ...) 2073c260e60Schristos PRINTF_FORMAT(2, 3); 2088dbcf02cSchristos void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len); 2098dbcf02cSchristos 2108dbcf02cSchristos #endif /* EAP_I_H */ 211