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
eap_tls_state_txt(int state)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
eap_tls_state(struct eap_tls_data * data,int state)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
eap_tls_valid_session(struct eap_sm * sm,struct eap_tls_data * data)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
eap_tls_init(struct eap_sm * sm)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
eap_unauth_tls_init(struct eap_sm * sm)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
eap_wfa_unauth_tls_init(struct eap_sm * sm)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
eap_tls_reset(struct eap_sm * sm,void * priv)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
eap_tls_build_start(struct eap_sm * sm,struct eap_tls_data * data,u8 id)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
eap_tls_buildReq(struct eap_sm * sm,void * priv,u8 id)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
eap_tls_check(struct eap_sm * sm,void * priv,struct wpabuf * respData)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
eap_tls_process_msg(struct eap_sm * sm,void * priv,const struct wpabuf * respData)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
eap_tls_process(struct eap_sm * sm,void * priv,struct wpabuf * respData)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
eap_tls_isDone(struct eap_sm * sm,void * priv)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
eap_tls_getKey(struct eap_sm * sm,void * priv,size_t * len)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
eap_tls_get_emsk(struct eap_sm * sm,void * priv,size_t * len)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
eap_tls_isSuccess(struct eap_sm * sm,void * priv)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
eap_tls_get_session_id(struct eap_sm * sm,void * priv,size_t * len)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
eap_server_tls_register(void)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
eap_server_unauth_tls_register(void)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
eap_server_wfa_unauth_tls_register(void)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