Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / src / eap_peer / eap_psk.c
index ccf871e..f012663 100644 (file)
@@ -2,14 +2,8 @@
  * EAP peer method: EAP-PSK (RFC 4764)
  * Copyright (c) 2004-2008, 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.
@@ -19,6 +13,7 @@
 
 #include "common.h"
 #include "crypto/aes_wrap.h"
+#include "crypto/random.h"
 #include "eap_common/eap_psk_common.h"
 #include "eap_i.h"
 
@@ -26,6 +21,7 @@
 struct eap_psk_data {
        enum { PSK_INIT, PSK_MAC_SENT, PSK_DONE } state;
        u8 rand_p[EAP_PSK_RAND_LEN];
+       u8 rand_s[EAP_PSK_RAND_LEN];
        u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN];
        u8 *id_s, *id_p;
        size_t id_s_len, id_p_len;
@@ -80,7 +76,7 @@ static void eap_psk_deinit(struct eap_sm *sm, void *priv)
        struct eap_psk_data *data = priv;
        os_free(data->id_s);
        os_free(data->id_p);
-       os_free(data);
+       bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -117,6 +113,7 @@ static struct wpabuf * eap_psk_process_1(struct eap_psk_data *data,
        }
        wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr1->rand_s,
                    EAP_PSK_RAND_LEN);
+       os_memcpy(data->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
        os_free(data->id_s);
        data->id_s_len = len - sizeof(*hdr1);
        data->id_s = os_malloc(data->id_s_len);
@@ -130,7 +127,7 @@ static struct wpabuf * eap_psk_process_1(struct eap_psk_data *data,
        wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_S",
                          data->id_s, data->id_s_len);
 
-       if (os_get_random(data->rand_p, EAP_PSK_RAND_LEN)) {
+       if (random_get_bytes(data->rand_p, EAP_PSK_RAND_LEN)) {
                wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
                ret->ignore = TRUE;
                return NULL;
@@ -240,7 +237,7 @@ static struct wpabuf * eap_psk_process_3(struct eap_psk_data *data,
                return NULL;
        }
        os_free(buf);
-       if (os_memcmp(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
+       if (os_memcmp_const(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
                wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third "
                           "message");
                ret->methodState = METHOD_DONE;
@@ -439,6 +436,28 @@ static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *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 != PSK_DONE)
+               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;
+}
+
+
 static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
 {
        struct eap_psk_data *data = priv;
@@ -473,6 +492,7 @@ int eap_peer_psk_register(void)
        eap->process = eap_psk_process;
        eap->isKeyAvailable = eap_psk_isKeyAvailable;
        eap->getKey = eap_psk_getKey;
+       eap->getSessionId = eap_psk_get_session_id;
        eap->get_emsk = eap_psk_get_emsk;
 
        ret = eap_peer_method_register(eap);