* hostapd / EAP-PAX (RFC 4746) 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.
*/
#include "includes.h"
#include "common.h"
+#include "crypto/random.h"
#include "eap_server/eap_i.h"
#include "eap_common/eap_pax_common.h"
u8 mk[EAP_PAX_MK_LEN];
u8 ck[EAP_PAX_CK_LEN];
u8 ick[EAP_PAX_ICK_LEN];
+ u8 mid[EAP_PAX_MID_LEN];
int keys_set;
char *cid;
size_t cid_len;
{
struct eap_pax_data *data = priv;
os_free(data->cid);
- os_free(data);
+ bin_clear_free(data, sizeof(*data));
}
wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (sending)");
- if (os_get_random(data->rand.r.x, EAP_PAX_RAND_LEN)) {
+ if (random_get_bytes(data->rand.r.x, EAP_PAX_RAND_LEN)) {
wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data");
data->state = FAILURE;
return NULL;
(u8 *) data->cid, data->cid_len, NULL, 0, pos);
wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: MAC_CK(B, CID)",
pos, EAP_PAX_MAC_LEN);
- pos += EAP_PAX_MAC_LEN;
/* Optional ADE could be added here, if needed */
wpabuf_mhead(respData),
wpabuf_len(respData) - EAP_PAX_ICV_LEN,
NULL, 0, NULL, 0, icvbuf);
- if (os_memcmp(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) {
+ if (os_memcmp_const(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) {
wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV");
wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV",
icvbuf, EAP_PAX_ICV_LEN);
struct eap_pax_hdr *resp;
u8 mac[EAP_PAX_MAC_LEN], icvbuf[EAP_PAX_ICV_LEN];
const u8 *pos;
- size_t len, left;
+ size_t len, left, cid_len;
int i;
if (data->state != PAX_STD_1)
wpa_printf(MSG_INFO, "EAP-PAX: Too short PAX_STD-2 (CID)");
return;
}
- data->cid_len = WPA_GET_BE16(pos);
+ cid_len = WPA_GET_BE16(pos);
+ if (cid_len > 1500) {
+ wpa_printf(MSG_INFO, "EAP-PAX: Too long CID");
+ return;
+ }
+ data->cid_len = cid_len;
os_free(data->cid);
data->cid = os_malloc(data->cid_len);
if (data->cid == NULL) {
if (eap_pax_initial_key_derivation(data->mac_id, data->ak,
data->rand.e, data->mk, data->ck,
- data->ick) < 0) {
+ data->ick, data->mid) < 0) {
wpa_printf(MSG_INFO, "EAP-PAX: Failed to complete initial "
"key derivation");
data->state = FAILURE;
data->rand.r.x, EAP_PAX_RAND_LEN,
data->rand.r.y, EAP_PAX_RAND_LEN,
(u8 *) data->cid, data->cid_len, mac);
- if (os_memcmp(mac, pos, EAP_PAX_MAC_LEN) != 0) {
+ if (os_memcmp_const(mac, pos, EAP_PAX_MAC_LEN) != 0) {
wpa_printf(MSG_INFO, "EAP-PAX: Invalid MAC_CK(A, B, CID) in "
"PAX_STD-2");
wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected MAC_CK(A, B, CID)",
wpabuf_head(respData),
wpabuf_len(respData) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0,
icvbuf);
- if (os_memcmp(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) {
+ if (os_memcmp_const(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) {
wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV in PAX_STD-2");
wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV",
icvbuf, EAP_PAX_ICV_LEN);
}
+static u8 * eap_pax_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
+{
+ struct eap_pax_data *data = priv;
+ u8 *sid;
+
+ if (data->state != SUCCESS)
+ return NULL;
+
+ sid = os_malloc(1 + EAP_PAX_MID_LEN);
+ if (sid == NULL)
+ return NULL;
+
+ *len = 1 + EAP_PAX_MID_LEN;
+ sid[0] = EAP_TYPE_PAX;
+ os_memcpy(sid + 1, data->mid, EAP_PAX_MID_LEN);
+
+ return sid;
+}
+
+
int eap_server_pax_register(void)
{
struct eap_method *eap;
- int ret;
eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
EAP_VENDOR_IETF, EAP_TYPE_PAX, "PAX");
eap->getKey = eap_pax_getKey;
eap->isSuccess = eap_pax_isSuccess;
eap->get_emsk = eap_pax_get_emsk;
+ eap->getSessionId = eap_pax_get_session_id;
- ret = eap_server_method_register(eap);
- if (ret)
- eap_server_method_free(eap);
- return ret;
+ return eap_server_method_register(eap);
}