1e28a4053SRui Paulo /* 2*a90b9d01SCy Schubert * hostapd / EAP-TLS (RFC 5216, RFC 9190) 3e28a4053SRui Paulo * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 7e28a4053SRui Paulo */ 8e28a4053SRui Paulo 9e28a4053SRui Paulo #include "includes.h" 10e28a4053SRui Paulo 11e28a4053SRui Paulo #include "common.h" 12e28a4053SRui Paulo #include "eap_i.h" 13e28a4053SRui Paulo #include "eap_tls_common.h" 14e28a4053SRui Paulo #include "crypto/tls.h" 15e28a4053SRui Paulo 16e28a4053SRui Paulo 17e28a4053SRui Paulo static void eap_tls_reset(struct eap_sm *sm, void *priv); 18e28a4053SRui Paulo 19e28a4053SRui Paulo 20e28a4053SRui Paulo struct eap_tls_data { 21e28a4053SRui Paulo struct eap_ssl_data ssl; 22e28a4053SRui Paulo enum { START, CONTINUE, SUCCESS, FAILURE } state; 23e28a4053SRui Paulo int established; 24f05cddf9SRui Paulo u8 eap_type; 254bc52338SCy Schubert int phase2; 26e28a4053SRui Paulo }; 27e28a4053SRui Paulo 28e28a4053SRui Paulo 29e28a4053SRui Paulo static const char * eap_tls_state_txt(int state) 30e28a4053SRui Paulo { 31e28a4053SRui Paulo switch (state) { 32e28a4053SRui Paulo case START: 33e28a4053SRui Paulo return "START"; 34e28a4053SRui Paulo case CONTINUE: 35e28a4053SRui Paulo return "CONTINUE"; 36e28a4053SRui Paulo case SUCCESS: 37e28a4053SRui Paulo return "SUCCESS"; 38e28a4053SRui Paulo case FAILURE: 39e28a4053SRui Paulo return "FAILURE"; 40e28a4053SRui Paulo default: 41e28a4053SRui Paulo return "Unknown?!"; 42e28a4053SRui Paulo } 43e28a4053SRui Paulo } 44e28a4053SRui Paulo 45e28a4053SRui Paulo 46e28a4053SRui Paulo static void eap_tls_state(struct eap_tls_data *data, int state) 47e28a4053SRui Paulo { 48e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP-TLS: %s -> %s", 49e28a4053SRui Paulo eap_tls_state_txt(data->state), 50e28a4053SRui Paulo eap_tls_state_txt(state)); 51e28a4053SRui Paulo data->state = state; 52325151a3SRui Paulo if (state == FAILURE) 53325151a3SRui Paulo tls_connection_remove_session(data->ssl.conn); 54325151a3SRui Paulo } 55325151a3SRui Paulo 56325151a3SRui Paulo 57325151a3SRui Paulo static void eap_tls_valid_session(struct eap_sm *sm, struct eap_tls_data *data) 58325151a3SRui Paulo { 59325151a3SRui Paulo struct wpabuf *buf; 60325151a3SRui Paulo 61c1d255d3SCy Schubert if (!sm->cfg->tls_session_lifetime) 62325151a3SRui Paulo return; 63325151a3SRui Paulo 64325151a3SRui Paulo buf = wpabuf_alloc(1); 65325151a3SRui Paulo if (!buf) 66325151a3SRui Paulo return; 67325151a3SRui Paulo wpabuf_put_u8(buf, data->eap_type); 68325151a3SRui Paulo tls_connection_set_success_data(data->ssl.conn, buf); 69e28a4053SRui Paulo } 70e28a4053SRui Paulo 71e28a4053SRui Paulo 72e28a4053SRui Paulo static void * eap_tls_init(struct eap_sm *sm) 73e28a4053SRui Paulo { 74e28a4053SRui Paulo struct eap_tls_data *data; 75e28a4053SRui Paulo 76e28a4053SRui Paulo data = os_zalloc(sizeof(*data)); 77e28a4053SRui Paulo if (data == NULL) 78e28a4053SRui Paulo return NULL; 79e28a4053SRui Paulo data->state = START; 80e28a4053SRui Paulo 81325151a3SRui Paulo if (eap_server_tls_ssl_init(sm, &data->ssl, 1, EAP_TYPE_TLS)) { 82e28a4053SRui Paulo wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 83e28a4053SRui Paulo eap_tls_reset(sm, data); 84e28a4053SRui Paulo return NULL; 85e28a4053SRui Paulo } 86e28a4053SRui Paulo 87f05cddf9SRui Paulo data->eap_type = EAP_TYPE_TLS; 88f05cddf9SRui Paulo 894bc52338SCy Schubert data->phase2 = sm->init_phase2; 904bc52338SCy Schubert 91e28a4053SRui Paulo return data; 92e28a4053SRui Paulo } 93e28a4053SRui Paulo 94e28a4053SRui Paulo 95f05cddf9SRui Paulo #ifdef EAP_SERVER_UNAUTH_TLS 96f05cddf9SRui Paulo static void * eap_unauth_tls_init(struct eap_sm *sm) 97f05cddf9SRui Paulo { 98f05cddf9SRui Paulo struct eap_tls_data *data; 99f05cddf9SRui Paulo 100f05cddf9SRui Paulo data = os_zalloc(sizeof(*data)); 101f05cddf9SRui Paulo if (data == NULL) 102f05cddf9SRui Paulo return NULL; 103f05cddf9SRui Paulo data->state = START; 104f05cddf9SRui Paulo 105325151a3SRui Paulo if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_UNAUTH_TLS_TYPE)) { 106f05cddf9SRui Paulo wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 107f05cddf9SRui Paulo eap_tls_reset(sm, data); 108f05cddf9SRui Paulo return NULL; 109f05cddf9SRui Paulo } 110f05cddf9SRui Paulo 111f05cddf9SRui Paulo data->eap_type = EAP_UNAUTH_TLS_TYPE; 112f05cddf9SRui Paulo return data; 113f05cddf9SRui Paulo } 114f05cddf9SRui Paulo #endif /* EAP_SERVER_UNAUTH_TLS */ 115f05cddf9SRui Paulo 116f05cddf9SRui Paulo 1175b9c547cSRui Paulo #ifdef CONFIG_HS20 1185b9c547cSRui Paulo static void * eap_wfa_unauth_tls_init(struct eap_sm *sm) 1195b9c547cSRui Paulo { 1205b9c547cSRui Paulo struct eap_tls_data *data; 1215b9c547cSRui Paulo 1225b9c547cSRui Paulo data = os_zalloc(sizeof(*data)); 1235b9c547cSRui Paulo if (data == NULL) 1245b9c547cSRui Paulo return NULL; 1255b9c547cSRui Paulo data->state = START; 1265b9c547cSRui Paulo 127325151a3SRui Paulo if (eap_server_tls_ssl_init(sm, &data->ssl, 0, 128325151a3SRui Paulo EAP_WFA_UNAUTH_TLS_TYPE)) { 1295b9c547cSRui Paulo wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 1305b9c547cSRui Paulo eap_tls_reset(sm, data); 1315b9c547cSRui Paulo return NULL; 1325b9c547cSRui Paulo } 1335b9c547cSRui Paulo 1345b9c547cSRui Paulo data->eap_type = EAP_WFA_UNAUTH_TLS_TYPE; 1355b9c547cSRui Paulo return data; 1365b9c547cSRui Paulo } 1375b9c547cSRui Paulo #endif /* CONFIG_HS20 */ 1385b9c547cSRui Paulo 1395b9c547cSRui Paulo 140e28a4053SRui Paulo static void eap_tls_reset(struct eap_sm *sm, void *priv) 141e28a4053SRui Paulo { 142e28a4053SRui Paulo struct eap_tls_data *data = priv; 143e28a4053SRui Paulo if (data == NULL) 144e28a4053SRui Paulo return; 145e28a4053SRui Paulo eap_server_tls_ssl_deinit(sm, &data->ssl); 146e28a4053SRui Paulo os_free(data); 147e28a4053SRui Paulo } 148e28a4053SRui Paulo 149e28a4053SRui Paulo 150e28a4053SRui Paulo static struct wpabuf * eap_tls_build_start(struct eap_sm *sm, 151e28a4053SRui Paulo struct eap_tls_data *data, u8 id) 152e28a4053SRui Paulo { 153e28a4053SRui Paulo struct wpabuf *req; 154e28a4053SRui Paulo 155f05cddf9SRui Paulo req = eap_tls_msg_alloc(data->eap_type, 1, EAP_CODE_REQUEST, id); 156e28a4053SRui Paulo if (req == NULL) { 157e28a4053SRui Paulo wpa_printf(MSG_ERROR, "EAP-TLS: Failed to allocate memory for " 158e28a4053SRui Paulo "request"); 159e28a4053SRui Paulo eap_tls_state(data, FAILURE); 160e28a4053SRui Paulo return NULL; 161e28a4053SRui Paulo } 162e28a4053SRui Paulo 163e28a4053SRui Paulo wpabuf_put_u8(req, EAP_TLS_FLAGS_START); 164e28a4053SRui Paulo 165e28a4053SRui Paulo eap_tls_state(data, CONTINUE); 166e28a4053SRui Paulo 167e28a4053SRui Paulo return req; 168e28a4053SRui Paulo } 169e28a4053SRui Paulo 170e28a4053SRui Paulo 171e28a4053SRui Paulo static struct wpabuf * eap_tls_buildReq(struct eap_sm *sm, void *priv, u8 id) 172e28a4053SRui Paulo { 173e28a4053SRui Paulo struct eap_tls_data *data = priv; 174e28a4053SRui Paulo struct wpabuf *res; 175e28a4053SRui Paulo 176e28a4053SRui Paulo if (data->ssl.state == FRAG_ACK) { 177f05cddf9SRui Paulo return eap_server_tls_build_ack(id, data->eap_type, 0); 178e28a4053SRui Paulo } 179e28a4053SRui Paulo 180e28a4053SRui Paulo if (data->ssl.state == WAIT_FRAG_ACK) { 181f05cddf9SRui Paulo res = eap_server_tls_build_msg(&data->ssl, data->eap_type, 0, 182e28a4053SRui Paulo id); 183e28a4053SRui Paulo goto check_established; 184e28a4053SRui Paulo } 185e28a4053SRui Paulo 186e28a4053SRui Paulo switch (data->state) { 187e28a4053SRui Paulo case START: 188e28a4053SRui Paulo return eap_tls_build_start(sm, data, id); 189e28a4053SRui Paulo case CONTINUE: 190c1d255d3SCy Schubert if (tls_connection_established(sm->cfg->ssl_ctx, 191c1d255d3SCy Schubert data->ssl.conn)) 192e28a4053SRui Paulo data->established = 1; 193e28a4053SRui Paulo break; 194e28a4053SRui Paulo default: 195e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP-TLS: %s - unexpected state %d", 196e28a4053SRui Paulo __func__, data->state); 197e28a4053SRui Paulo return NULL; 198e28a4053SRui Paulo } 199e28a4053SRui Paulo 200f05cddf9SRui Paulo res = eap_server_tls_build_msg(&data->ssl, data->eap_type, 0, id); 201e28a4053SRui Paulo 202e28a4053SRui Paulo check_established: 203e28a4053SRui Paulo if (data->established && data->ssl.state != WAIT_FRAG_ACK) { 204e28a4053SRui Paulo /* TLS handshake has been completed and there are no more 205e28a4053SRui Paulo * fragments waiting to be sent out. */ 206e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP-TLS: Done"); 207e28a4053SRui Paulo eap_tls_state(data, SUCCESS); 208325151a3SRui Paulo eap_tls_valid_session(sm, data); 2094bc52338SCy Schubert if (sm->serial_num) { 2104bc52338SCy Schubert char user[128]; 2114bc52338SCy Schubert int user_len; 2124bc52338SCy Schubert 2134bc52338SCy Schubert user_len = os_snprintf(user, sizeof(user), "cert-%s", 2144bc52338SCy Schubert sm->serial_num); 2154bc52338SCy Schubert if (eap_user_get(sm, (const u8 *) user, user_len, 2164bc52338SCy Schubert data->phase2) < 0) 2174bc52338SCy Schubert wpa_printf(MSG_DEBUG, 2184bc52338SCy Schubert "EAP-TLS: No user entry found based on the serial number of the client certificate "); 2194bc52338SCy Schubert else 2204bc52338SCy Schubert wpa_printf(MSG_DEBUG, 2214bc52338SCy Schubert "EAP-TLS: Updated user entry based on the serial number of the client certificate "); 2224bc52338SCy Schubert } 223e28a4053SRui Paulo } 224e28a4053SRui Paulo 225e28a4053SRui Paulo return res; 226e28a4053SRui Paulo } 227e28a4053SRui Paulo 228e28a4053SRui Paulo 229c1d255d3SCy Schubert static bool eap_tls_check(struct eap_sm *sm, void *priv, 230e28a4053SRui Paulo struct wpabuf *respData) 231e28a4053SRui Paulo { 232f05cddf9SRui Paulo struct eap_tls_data *data = priv; 233e28a4053SRui Paulo const u8 *pos; 234e28a4053SRui Paulo size_t len; 235e28a4053SRui Paulo 236f05cddf9SRui Paulo if (data->eap_type == EAP_UNAUTH_TLS_TYPE) 237f05cddf9SRui Paulo pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 238f05cddf9SRui Paulo EAP_VENDOR_TYPE_UNAUTH_TLS, respData, 239f05cddf9SRui Paulo &len); 2405b9c547cSRui Paulo else if (data->eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 2415b9c547cSRui Paulo pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 2425b9c547cSRui Paulo EAP_VENDOR_WFA_UNAUTH_TLS, respData, 2435b9c547cSRui Paulo &len); 244f05cddf9SRui Paulo else 245f05cddf9SRui Paulo pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_type, 246f05cddf9SRui Paulo respData, &len); 247e28a4053SRui Paulo if (pos == NULL || len < 1) { 248e28a4053SRui Paulo wpa_printf(MSG_INFO, "EAP-TLS: Invalid frame"); 249c1d255d3SCy Schubert return true; 250e28a4053SRui Paulo } 251e28a4053SRui Paulo 252c1d255d3SCy Schubert return false; 253e28a4053SRui Paulo } 254e28a4053SRui Paulo 255e28a4053SRui Paulo 256e28a4053SRui Paulo static void eap_tls_process_msg(struct eap_sm *sm, void *priv, 257e28a4053SRui Paulo const struct wpabuf *respData) 258e28a4053SRui Paulo { 259e28a4053SRui Paulo struct eap_tls_data *data = priv; 260e28a4053SRui Paulo if (data->state == SUCCESS && wpabuf_len(data->ssl.tls_in) == 0) { 261e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP-TLS: Client acknowledged final TLS " 262e28a4053SRui Paulo "handshake message"); 263e28a4053SRui Paulo return; 264e28a4053SRui Paulo } 265206b73d0SCy Schubert if (eap_server_tls_phase1(sm, &data->ssl) < 0) { 266e28a4053SRui Paulo eap_tls_state(data, FAILURE); 267206b73d0SCy Schubert return; 268206b73d0SCy Schubert } 269e28a4053SRui Paulo } 270e28a4053SRui Paulo 271e28a4053SRui Paulo 272e28a4053SRui Paulo static void eap_tls_process(struct eap_sm *sm, void *priv, 273e28a4053SRui Paulo struct wpabuf *respData) 274e28a4053SRui Paulo { 275e28a4053SRui Paulo struct eap_tls_data *data = priv; 276325151a3SRui Paulo const struct wpabuf *buf; 277325151a3SRui Paulo const u8 *pos; 278325151a3SRui Paulo 279e28a4053SRui Paulo if (eap_server_tls_process(sm, &data->ssl, respData, data, 280f05cddf9SRui Paulo data->eap_type, NULL, eap_tls_process_msg) < 281325151a3SRui Paulo 0) { 282e28a4053SRui Paulo eap_tls_state(data, FAILURE); 283325151a3SRui Paulo return; 284325151a3SRui Paulo } 285325151a3SRui Paulo 286c1d255d3SCy Schubert if (!tls_connection_established(sm->cfg->ssl_ctx, data->ssl.conn) || 287c1d255d3SCy Schubert !tls_connection_resumed(sm->cfg->ssl_ctx, data->ssl.conn)) 288325151a3SRui Paulo return; 289325151a3SRui Paulo 290325151a3SRui Paulo buf = tls_connection_get_success_data(data->ssl.conn); 291325151a3SRui Paulo if (!buf || wpabuf_len(buf) < 1) { 292325151a3SRui Paulo wpa_printf(MSG_DEBUG, 293325151a3SRui Paulo "EAP-TLS: No success data in resumed session - reject attempt"); 294325151a3SRui Paulo eap_tls_state(data, FAILURE); 295325151a3SRui Paulo return; 296325151a3SRui Paulo } 297325151a3SRui Paulo 298325151a3SRui Paulo pos = wpabuf_head(buf); 299325151a3SRui Paulo if (*pos != data->eap_type) { 300325151a3SRui Paulo wpa_printf(MSG_DEBUG, 301325151a3SRui Paulo "EAP-TLS: Resumed session for another EAP type (%u) - reject attempt", 302325151a3SRui Paulo *pos); 303325151a3SRui Paulo eap_tls_state(data, FAILURE); 304325151a3SRui Paulo return; 305325151a3SRui Paulo } 306325151a3SRui Paulo 307325151a3SRui Paulo wpa_printf(MSG_DEBUG, 308325151a3SRui Paulo "EAP-TLS: Resuming previous session"); 309*a90b9d01SCy Schubert 310*a90b9d01SCy Schubert if (data->ssl.tls_v13 && data->ssl.tls_out) { 311*a90b9d01SCy Schubert wpa_hexdump_buf(MSG_DEBUG, 312*a90b9d01SCy Schubert "EAP-TLS: Additional data to be sent for TLS 1.3", 313*a90b9d01SCy Schubert data->ssl.tls_out); 314*a90b9d01SCy Schubert return; 315*a90b9d01SCy Schubert } 316*a90b9d01SCy Schubert 317325151a3SRui Paulo eap_tls_state(data, SUCCESS); 318325151a3SRui Paulo tls_connection_set_success_data_resumed(data->ssl.conn); 3194bc52338SCy Schubert /* TODO: Cache serial number with session and update EAP user 3204bc52338SCy Schubert * information based on the cached serial number */ 321e28a4053SRui Paulo } 322e28a4053SRui Paulo 323e28a4053SRui Paulo 324c1d255d3SCy Schubert static bool eap_tls_isDone(struct eap_sm *sm, void *priv) 325e28a4053SRui Paulo { 326e28a4053SRui Paulo struct eap_tls_data *data = priv; 327e28a4053SRui Paulo return data->state == SUCCESS || data->state == FAILURE; 328e28a4053SRui Paulo } 329e28a4053SRui Paulo 330e28a4053SRui Paulo 331e28a4053SRui Paulo static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len) 332e28a4053SRui Paulo { 333e28a4053SRui Paulo struct eap_tls_data *data = priv; 334e28a4053SRui Paulo u8 *eapKeyData; 33585732ac8SCy Schubert const char *label; 336206b73d0SCy Schubert const u8 eap_tls13_context[] = { EAP_TYPE_TLS }; 337206b73d0SCy Schubert const u8 *context = NULL; 338206b73d0SCy Schubert size_t context_len = 0; 339e28a4053SRui Paulo 340e28a4053SRui Paulo if (data->state != SUCCESS) 341e28a4053SRui Paulo return NULL; 342e28a4053SRui Paulo 343206b73d0SCy Schubert if (data->ssl.tls_v13) { 34485732ac8SCy Schubert label = "EXPORTER_EAP_TLS_Key_Material"; 345206b73d0SCy Schubert context = eap_tls13_context; 346206b73d0SCy Schubert context_len = 1; 347206b73d0SCy Schubert } else { 34885732ac8SCy Schubert label = "client EAP encryption"; 349206b73d0SCy Schubert } 35085732ac8SCy Schubert eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label, 351206b73d0SCy Schubert context, context_len, 35285732ac8SCy Schubert EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 353e28a4053SRui Paulo if (eapKeyData) { 354e28a4053SRui Paulo *len = EAP_TLS_KEY_LEN; 355e28a4053SRui Paulo wpa_hexdump(MSG_DEBUG, "EAP-TLS: Derived key", 356e28a4053SRui Paulo eapKeyData, EAP_TLS_KEY_LEN); 35785732ac8SCy Schubert os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN); 358e28a4053SRui Paulo } else { 359e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP-TLS: Failed to derive key"); 360e28a4053SRui Paulo } 361e28a4053SRui Paulo 362e28a4053SRui Paulo return eapKeyData; 363e28a4053SRui Paulo } 364e28a4053SRui Paulo 365e28a4053SRui Paulo 366e28a4053SRui Paulo static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 367e28a4053SRui Paulo { 368e28a4053SRui Paulo struct eap_tls_data *data = priv; 369e28a4053SRui Paulo u8 *eapKeyData, *emsk; 37085732ac8SCy Schubert const char *label; 371206b73d0SCy Schubert const u8 eap_tls13_context[] = { EAP_TYPE_TLS }; 372206b73d0SCy Schubert const u8 *context = NULL; 373206b73d0SCy Schubert size_t context_len = 0; 374e28a4053SRui Paulo 375e28a4053SRui Paulo if (data->state != SUCCESS) 376e28a4053SRui Paulo return NULL; 377e28a4053SRui Paulo 378206b73d0SCy Schubert if (data->ssl.tls_v13) { 37985732ac8SCy Schubert label = "EXPORTER_EAP_TLS_Key_Material"; 380206b73d0SCy Schubert context = eap_tls13_context; 381206b73d0SCy Schubert context_len = 1; 382206b73d0SCy Schubert } else { 38385732ac8SCy Schubert label = "client EAP encryption"; 384206b73d0SCy Schubert } 38585732ac8SCy Schubert eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label, 386206b73d0SCy Schubert context, context_len, 387e28a4053SRui Paulo EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 388e28a4053SRui Paulo if (eapKeyData) { 389e28a4053SRui Paulo emsk = os_malloc(EAP_EMSK_LEN); 390e28a4053SRui Paulo if (emsk) 391e28a4053SRui Paulo os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN, 392e28a4053SRui Paulo EAP_EMSK_LEN); 3935b9c547cSRui Paulo bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 394e28a4053SRui Paulo } else 395e28a4053SRui Paulo emsk = NULL; 396e28a4053SRui Paulo 397e28a4053SRui Paulo if (emsk) { 398e28a4053SRui Paulo *len = EAP_EMSK_LEN; 399e28a4053SRui Paulo wpa_hexdump(MSG_DEBUG, "EAP-TLS: Derived EMSK", 400e28a4053SRui Paulo emsk, EAP_EMSK_LEN); 401e28a4053SRui Paulo } else { 402e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP-TLS: Failed to derive EMSK"); 403e28a4053SRui Paulo } 404e28a4053SRui Paulo 405e28a4053SRui Paulo return emsk; 406e28a4053SRui Paulo } 407e28a4053SRui Paulo 408e28a4053SRui Paulo 409c1d255d3SCy Schubert static bool eap_tls_isSuccess(struct eap_sm *sm, void *priv) 410e28a4053SRui Paulo { 411e28a4053SRui Paulo struct eap_tls_data *data = priv; 412e28a4053SRui Paulo return data->state == SUCCESS; 413e28a4053SRui Paulo } 414e28a4053SRui Paulo 415e28a4053SRui Paulo 4165b9c547cSRui Paulo static u8 * eap_tls_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 4175b9c547cSRui Paulo { 4185b9c547cSRui Paulo struct eap_tls_data *data = priv; 4195b9c547cSRui Paulo 4205b9c547cSRui Paulo if (data->state != SUCCESS) 4215b9c547cSRui Paulo return NULL; 4225b9c547cSRui Paulo 4235b9c547cSRui Paulo return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TLS, 4245b9c547cSRui Paulo len); 4255b9c547cSRui Paulo } 4265b9c547cSRui Paulo 4275b9c547cSRui Paulo 428e28a4053SRui Paulo int eap_server_tls_register(void) 429e28a4053SRui Paulo { 430e28a4053SRui Paulo struct eap_method *eap; 431e28a4053SRui Paulo 432e28a4053SRui Paulo eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 433e28a4053SRui Paulo EAP_VENDOR_IETF, EAP_TYPE_TLS, "TLS"); 434e28a4053SRui Paulo if (eap == NULL) 435e28a4053SRui Paulo return -1; 436e28a4053SRui Paulo 437e28a4053SRui Paulo eap->init = eap_tls_init; 438e28a4053SRui Paulo eap->reset = eap_tls_reset; 439e28a4053SRui Paulo eap->buildReq = eap_tls_buildReq; 440e28a4053SRui Paulo eap->check = eap_tls_check; 441e28a4053SRui Paulo eap->process = eap_tls_process; 442e28a4053SRui Paulo eap->isDone = eap_tls_isDone; 443e28a4053SRui Paulo eap->getKey = eap_tls_getKey; 444e28a4053SRui Paulo eap->isSuccess = eap_tls_isSuccess; 445e28a4053SRui Paulo eap->get_emsk = eap_tls_get_emsk; 4465b9c547cSRui Paulo eap->getSessionId = eap_tls_get_session_id; 447e28a4053SRui Paulo 448780fb4a2SCy Schubert return eap_server_method_register(eap); 449e28a4053SRui Paulo } 450f05cddf9SRui Paulo 451f05cddf9SRui Paulo 452f05cddf9SRui Paulo #ifdef EAP_SERVER_UNAUTH_TLS 453f05cddf9SRui Paulo int eap_server_unauth_tls_register(void) 454f05cddf9SRui Paulo { 455f05cddf9SRui Paulo struct eap_method *eap; 456f05cddf9SRui Paulo 457f05cddf9SRui Paulo eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 458f05cddf9SRui Paulo EAP_VENDOR_UNAUTH_TLS, 459f05cddf9SRui Paulo EAP_VENDOR_TYPE_UNAUTH_TLS, 460f05cddf9SRui Paulo "UNAUTH-TLS"); 461f05cddf9SRui Paulo if (eap == NULL) 462f05cddf9SRui Paulo return -1; 463f05cddf9SRui Paulo 464f05cddf9SRui Paulo eap->init = eap_unauth_tls_init; 465f05cddf9SRui Paulo eap->reset = eap_tls_reset; 466f05cddf9SRui Paulo eap->buildReq = eap_tls_buildReq; 467f05cddf9SRui Paulo eap->check = eap_tls_check; 468f05cddf9SRui Paulo eap->process = eap_tls_process; 469f05cddf9SRui Paulo eap->isDone = eap_tls_isDone; 470f05cddf9SRui Paulo eap->getKey = eap_tls_getKey; 471f05cddf9SRui Paulo eap->isSuccess = eap_tls_isSuccess; 472f05cddf9SRui Paulo eap->get_emsk = eap_tls_get_emsk; 473f05cddf9SRui Paulo 474780fb4a2SCy Schubert return eap_server_method_register(eap); 475f05cddf9SRui Paulo } 476f05cddf9SRui Paulo #endif /* EAP_SERVER_UNAUTH_TLS */ 4775b9c547cSRui Paulo 4785b9c547cSRui Paulo 4795b9c547cSRui Paulo #ifdef CONFIG_HS20 4805b9c547cSRui Paulo int eap_server_wfa_unauth_tls_register(void) 4815b9c547cSRui Paulo { 4825b9c547cSRui Paulo struct eap_method *eap; 4835b9c547cSRui Paulo 4845b9c547cSRui Paulo eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 4855b9c547cSRui Paulo EAP_VENDOR_WFA_NEW, 4865b9c547cSRui Paulo EAP_VENDOR_WFA_UNAUTH_TLS, 4875b9c547cSRui Paulo "WFA-UNAUTH-TLS"); 4885b9c547cSRui Paulo if (eap == NULL) 4895b9c547cSRui Paulo return -1; 4905b9c547cSRui Paulo 4915b9c547cSRui Paulo eap->init = eap_wfa_unauth_tls_init; 4925b9c547cSRui Paulo eap->reset = eap_tls_reset; 4935b9c547cSRui Paulo eap->buildReq = eap_tls_buildReq; 4945b9c547cSRui Paulo eap->check = eap_tls_check; 4955b9c547cSRui Paulo eap->process = eap_tls_process; 4965b9c547cSRui Paulo eap->isDone = eap_tls_isDone; 4975b9c547cSRui Paulo eap->getKey = eap_tls_getKey; 4985b9c547cSRui Paulo eap->isSuccess = eap_tls_isSuccess; 4995b9c547cSRui Paulo eap->get_emsk = eap_tls_get_emsk; 5005b9c547cSRui Paulo 501780fb4a2SCy Schubert return eap_server_method_register(eap); 5025b9c547cSRui Paulo } 5035b9c547cSRui Paulo #endif /* CONFIG_HS20 */ 504