1 /* 2 * EAP peer state machines internal structures (RFC 4137) 3 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #ifndef EAP_I_H 10 #define EAP_I_H 11 12 #include "utils/wpabuf.h" 13 #include "eap.h" 14 #include "eap_common.h" 15 #include "eap_config.h" 16 #include "esp_wpa2.h" 17 18 /* RFC 4137 - EAP Peer state machine */ 19 20 typedef enum { 21 DECISION_FAIL, DECISION_COND_SUCC, DECISION_UNCOND_SUCC 22 } EapDecision; 23 24 typedef enum { 25 METHOD_NONE, METHOD_INIT, METHOD_CONT, METHOD_MAY_CONT, METHOD_DONE 26 } EapMethodState; 27 28 /** 29 * struct eap_method_ret - EAP return values from struct eap_method::process() 30 * 31 * These structure contains OUT variables for the interface between peer state 32 * machine and methods (RFC 4137, Sect. 4.2). eapRespData will be returned as 33 * the return value of struct eap_method::process() so it is not included in 34 * this structure. 35 */ 36 struct eap_method_ret { 37 /** 38 * ignore - Whether method decided to drop the current packed (OUT) 39 */ 40 Boolean ignore; 41 42 /** 43 * methodState - Method-specific state (IN/OUT) 44 */ 45 EapMethodState methodState; 46 47 /** 48 * decision - Authentication decision (OUT) 49 */ 50 EapDecision decision; 51 52 /** 53 * allowNotifications - Whether method allows notifications (OUT) 54 */ 55 Boolean allowNotifications; 56 }; 57 58 struct eap_sm; 59 60 /** 61 * struct eap_method - EAP method interface 62 * This structure defines the EAP method interface. Each method will need to 63 * register its own EAP type, EAP name, and set of function pointers for method 64 * specific operations. This interface is based on section 4.4 of RFC 4137. 65 */ 66 struct eap_method { 67 /** 68 * vendor - EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF) 69 */ 70 int vendor; 71 72 /** 73 * method - EAP type number (EAP_TYPE_*) 74 */ 75 EapType method; 76 77 /** 78 * name - Name of the method (e.g., "TLS") 79 */ 80 const char *name; 81 82 /** 83 * init - Initialize an EAP method 84 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 85 * Returns: Pointer to allocated private data, or %NULL on failure 86 * 87 * This function is used to initialize the EAP method explicitly 88 * instead of using METHOD_INIT state as specific in RFC 4137. The 89 * method is expected to initialize it method-specific state and return 90 * a pointer that will be used as the priv argument to other calls. 91 */ 92 void * (*init)(struct eap_sm *sm); 93 94 /** 95 * deinit - Deinitialize an EAP method 96 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 97 * @priv: Pointer to private EAP method data from eap_method::init() 98 * 99 * Deinitialize the EAP method and free any allocated private data. 100 */ 101 void (*deinit)(struct eap_sm *sm, void *priv); 102 103 /** 104 * process - Process an EAP request 105 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 106 * @priv: Pointer to private EAP method data from eap_method::init() 107 * @ret: Return values from EAP request validation and processing 108 * @reqData: EAP request to be processed (eapReqData) 109 * Returns: Pointer to allocated EAP response packet (eapRespData) 110 * 111 * This function is a combination of m.check(), m.process(), and 112 * m.buildResp() procedures defined in section 4.4 of RFC 4137 In other 113 * words, this function validates the incoming request, processes it, 114 * and build a response packet. m.check() and m.process() return values 115 * are returned through struct eap_method_ret *ret variable. Caller is 116 * responsible for freeing the returned EAP response packet. 117 */ 118 struct wpabuf * (*process)(struct eap_sm *sm, void *priv, 119 struct eap_method_ret *ret, 120 const struct wpabuf *reqData); 121 bool (*isKeyAvailable)(struct eap_sm *sm, void *priv); 122 u8 * (*getKey)(struct eap_sm *sm, void *priv, size_t *len); 123 124 /** 125 * get_status - Get EAP method status 126 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 127 * @priv: Pointer to private EAP method data from eap_method::init() 128 * @buf: Buffer for status information 129 * @buflen: Maximum buffer length 130 * @verbose: Whether to include verbose status information 131 * Returns: Number of bytes written to buf 132 * 133 * Query EAP method for status information. This function fills in a 134 * text area with current status information from the EAP method. If 135 * the buffer (buf) is not large enough, status information will be 136 * truncated to fit the buffer. 137 */ 138 int (*get_status)(struct eap_sm *sm, void *priv, char *buf, 139 size_t buflen, int verbose); 140 141 /** 142 * has_reauth_data - Whether method is ready for fast reauthentication 143 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 144 * @priv: Pointer to private EAP method data from eap_method::init() 145 * Returns: %TRUE or %FALSE based on whether fast reauthentication is 146 * possible 147 * 148 * This function is an optional handler that only EAP methods 149 * supporting fast re-authentication need to implement. 150 */ 151 bool (*has_reauth_data)(struct eap_sm *sm, void *priv); 152 153 /** 154 * deinit_for_reauth - Release data that is not needed for fast re-auth 155 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 156 * @priv: Pointer to private EAP method data from eap_method::init() 157 * 158 * This function is an optional handler that only EAP methods 159 * supporting fast re-authentication need to implement. This is called 160 * when authentication has been completed and EAP state machine is 161 * requesting that enough state information is maintained for fast 162 * re-authentication 163 */ 164 void (*deinit_for_reauth)(struct eap_sm *sm, void *priv); 165 166 /** 167 * init_for_reauth - Prepare for start of fast re-authentication 168 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 169 * @priv: Pointer to private EAP method data from eap_method::init() 170 * 171 * This function is an optional handler that only EAP methods 172 * supporting fast re-authentication need to implement. This is called 173 * when EAP authentication is started and EAP state machine is 174 * requesting fast re-authentication to be used. 175 */ 176 void * (*init_for_reauth)(struct eap_sm *sm, void *priv); 177 178 /** 179 * get_identity - Get method specific identity for re-authentication 180 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 181 * @priv: Pointer to private EAP method data from eap_method::init() 182 * @len: Length of the returned identity 183 * Returns: Pointer to the method specific identity or %NULL if default 184 * identity is to be used 185 * 186 * This function is an optional handler that only EAP methods 187 * that use method specific identity need to implement. 188 */ 189 const u8 * (*get_identity)(struct eap_sm *sm, void *priv, size_t *len); 190 191 /** 192 * free - Free EAP method data 193 * @method: Pointer to the method data registered with 194 * eap_peer_method_register(). 195 * 196 * This function will be called when the EAP method is being 197 * unregistered. If the EAP method allocated resources during 198 * registration (e.g., allocated struct eap_method), they should be 199 * freed in this function. No other method functions will be called 200 * after this call. If this function is not defined (i.e., function 201 * pointer is %NULL), a default handler is used to release the method 202 * data with free(method). This is suitable for most cases. 203 */ 204 void (*free)(struct eap_method *method); 205 206 #define EAP_PEER_METHOD_INTERFACE_VERSION 1 207 /** 208 * version - Version of the EAP peer method interface 209 * 210 * The EAP peer method implementation should set this variable to 211 * EAP_PEER_METHOD_INTERFACE_VERSION. This is used to verify that the 212 * EAP method is using supported API version when using dynamically 213 * loadable EAP methods. 214 */ 215 int version; 216 217 /** 218 * next - Pointer to the next EAP method 219 * 220 * This variable is used internally in the EAP method registration code 221 * to create a linked list of registered EAP methods. 222 */ 223 struct eap_method *next; 224 225 #ifdef CONFIG_DYNAMIC_EAP_METHODS 226 /** 227 * dl_handle - Handle for the dynamic library 228 * 229 * This variable is used internally in the EAP method registration code 230 * to store a handle for the dynamic library. If the method is linked 231 * in statically, this is %NULL. 232 */ 233 void *dl_handle; 234 #endif /* CONFIG_DYNAMIC_EAP_METHODS */ 235 236 /** 237 * get_emsk - Get EAP method specific keying extended material (EMSK) 238 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 239 * @priv: Pointer to private EAP method data from eap_method::init() 240 * @len: Pointer to a variable to store EMSK length 241 * Returns: EMSK or %NULL if not available 242 * 243 * This function can be used to get the extended keying material from 244 * the EAP method. The key may already be stored in the method-specific 245 * private data or this function may derive the key. 246 */ 247 u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len); 248 249 /** 250 * getSessionId - Get EAP method specific Session-Id 251 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 252 * @priv: Pointer to private EAP method data from eap_method::init() 253 * @len: Pointer to a variable to store Session-Id length 254 * Returns: Session-Id or %NULL if not available 255 * 256 * This function can be used to get the Session-Id from the EAP method. 257 * The Session-Id may already be stored in the method-specific private 258 * data or this function may derive the Session-Id. 259 */ 260 u8 * (*getSessionId)(struct eap_sm *sm, void *priv, size_t *len); 261 }; 262 263 #define CLIENT_CERT_NAME "CLC" 264 #define CA_CERT_NAME "CAC" 265 #define PRIVATE_KEY_NAME "PVK" 266 #define PAC_FILE_NAME "PAC" 267 #define BLOB_NAME_LEN 3 268 #define BLOB_NUM 4 269 270 enum SIG_WPA2 { 271 SIG_WPA2_START = 0, 272 SIG_WPA2_RX, 273 SIG_WPA2_TASK_DEL, 274 SIG_WPA2_MAX, 275 }; 276 277 /** 278 * struct eap_sm - EAP state machine data 279 */ 280 struct eap_sm { 281 /* not defined in RFC 4137 */ 282 Boolean changed; 283 void *eapol_ctx; 284 const struct eapol_callbacks *eapol_cb; 285 void *eap_method_priv; 286 int init_phase2; 287 288 void *msg_ctx; 289 void *ssl_ctx; 290 291 unsigned int workaround; 292 ///////////////////////////////////////////////// 293 struct pbuf *outbuf; 294 struct wpa_config_blob blob[BLOB_NUM]; 295 struct eap_peer_config config; 296 u8 current_identifier; 297 u8 ownaddr[ETH_ALEN]; 298 #ifdef USE_WPA2_TASK 299 u8 wpa2_sig_cnt[SIG_WPA2_MAX]; 300 #endif 301 u8 finish_state; 302 303 /* Optional challenges generated in Phase 1 (EAP-FAST) */ 304 u8 *peer_challenge, *auth_challenge; 305 306 unsigned int expected_failure:1; 307 unsigned int ext_cert_check:1; 308 unsigned int waiting_ext_cert_check:1; 309 bool peap_done; 310 311 u8 *eapKeyData; 312 size_t eapKeyDataLen; 313 struct wpabuf *lastRespData; 314 const struct eap_method *m; 315 }; 316 317 typedef enum { 318 WPA2_STATE_ENABLED = 0, 319 WPA2_STATE_DISABLED, 320 } wpa2_state_t; 321 322 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len); 323 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len); 324 const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash); 325 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len); 326 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len); 327 void eap_clear_config_otp(struct eap_sm *sm); 328 const char * eap_get_config_phase1(struct eap_sm *sm); 329 const char * eap_get_config_phase2(struct eap_sm *sm); 330 int eap_get_config_fragment_size(struct eap_sm *sm); 331 struct eap_peer_config * eap_get_config(struct eap_sm *sm); 332 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob); 333 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, const char *name); 334 int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method); 335 bool wifi_sta_get_enterprise_disable_time_check(void); 336 337 struct wpabuf * eap_sm_build_identity_resp(struct eap_sm *sm, u8 id, int encrypted); 338 339 #endif /* EAP_I_H */ 340