* hostapd / EAP-PSK (RFC 4764) server
* Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*
* Note: EAP-PSK is an EAP authentication method and as such, completely
* different from WPA-PSK. This file is not needed for WPA-PSK functionality.
#include "common.h"
#include "crypto/aes_wrap.h"
+#include "crypto/random.h"
#include "eap_common/eap_psk_common.h"
#include "eap_server/eap_i.h"
enum { PSK_1, PSK_3, SUCCESS, FAILURE } state;
u8 rand_s[EAP_PSK_RAND_LEN];
u8 rand_p[EAP_PSK_RAND_LEN];
- u8 *id_p, *id_s;
- size_t id_p_len, id_s_len;
+ u8 *id_p;
+ size_t id_p_len;
u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN];
u8 msk[EAP_MSK_LEN];
u8 emsk[EAP_EMSK_LEN];
if (data == NULL)
return NULL;
data->state = PSK_1;
- data->id_s = (u8 *) "hostapd";
- data->id_s_len = 7;
return data;
}
{
struct eap_psk_data *data = priv;
os_free(data->id_p);
- os_free(data);
+ bin_clear_free(data, sizeof(*data));
}
wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)");
- if (os_get_random(data->rand_s, EAP_PSK_RAND_LEN)) {
+ if (random_get_bytes(data->rand_s, EAP_PSK_RAND_LEN)) {
wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
data->state = FAILURE;
return NULL;
data->rand_s, EAP_PSK_RAND_LEN);
req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
- sizeof(*psk) + data->id_s_len,
+ sizeof(*psk) + sm->server_id_len,
EAP_CODE_REQUEST, id);
if (req == NULL) {
wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
psk = wpabuf_put(req, sizeof(*psk));
psk->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */
os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
- wpabuf_put_data(req, data->id_s, data->id_s_len);
+ wpabuf_put_data(req, sm->server_id, sm->server_id_len);
return req;
}
os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
/* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
- buflen = data->id_s_len + EAP_PSK_RAND_LEN;
+ buflen = sm->server_id_len + EAP_PSK_RAND_LEN;
buf = os_malloc(buflen);
if (buf == NULL)
goto fail;
- os_memcpy(buf, data->id_s, data->id_s_len);
- os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
- if (omac1_aes_128(data->ak, buf, buflen, psk->mac_s))
+ os_memcpy(buf, sm->server_id, sm->server_id_len);
+ os_memcpy(buf + sm->server_id_len, data->rand_p, EAP_PSK_RAND_LEN);
+ if (omac1_aes_128(data->ak, buf, buflen, psk->mac_s)) {
+ os_free(buf);
goto fail;
+ }
os_free(buf);
if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk,
os_memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN);
/* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
- buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
+ buflen = data->id_p_len + sm->server_id_len + 2 * EAP_PSK_RAND_LEN;
buf = os_malloc(buflen);
if (buf == NULL) {
data->state = FAILURE;
}
os_memcpy(buf, data->id_p, data->id_p_len);
pos = buf + data->id_p_len;
- os_memcpy(pos, data->id_s, data->id_s_len);
- pos += data->id_s_len;
+ os_memcpy(pos, sm->server_id, sm->server_id_len);
+ pos += sm->server_id_len;
os_memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN);
pos += EAP_PSK_RAND_LEN;
os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
}
os_free(buf);
wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN);
- if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
+ if (os_memcmp_const(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P");
wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P",
mac, EAP_PSK_MAC_LEN);
}
+static u8 * eap_psk_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
+{
+ struct eap_psk_data *data = priv;
+ u8 *id;
+
+ if (data->state != SUCCESS)
+ return NULL;
+
+ *len = 1 + 2 * EAP_PSK_RAND_LEN;
+ id = os_malloc(*len);
+ if (id == NULL)
+ return NULL;
+
+ id[0] = EAP_TYPE_PSK;
+ os_memcpy(id + 1, data->rand_p, EAP_PSK_RAND_LEN);
+ os_memcpy(id + 1 + EAP_PSK_RAND_LEN, data->rand_s, EAP_PSK_RAND_LEN);
+ wpa_hexdump(MSG_DEBUG, "EAP-PSK: Derived Session-Id", id, *len);
+
+ return id;
+}
+
+
int eap_server_psk_register(void)
{
struct eap_method *eap;
eap->getKey = eap_psk_getKey;
eap->isSuccess = eap_psk_isSuccess;
eap->get_emsk = eap_psk_get_emsk;
+ eap->getSessionId = eap_psk_get_session_id;
ret = eap_server_method_register(eap);
if (ret)