#include "common.h"
#include "l2_packet/l2_packet.h"
+#include "rsn_supp/wpa.h"
+#include "rsn_supp/wpa_ie.h"
+#include "ap/wpa_auth.h"
#include "wpa_supplicant_i.h"
-#include "wpa.h"
-#include "wpa_ie.h"
-#include "../hostapd/wpa.h"
+#include "driver_i.h"
#include "ibss_rsn.h"
}
-static void supp_set_state(void *ctx, wpa_states state)
+static void supp_set_state(void *ctx, enum wpa_states state)
{
struct ibss_rsn_peer *peer = ctx;
peer->supp_state = state;
}
-static int supp_set_key(void *ctx, wpa_alg alg,
+static int supp_set_key(void *ctx, enum wpa_alg alg,
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{
+ struct ibss_rsn_peer *peer = ctx;
+
wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
"set_tx=%d)",
__func__, alg, MAC2STR(addr), key_idx, set_tx);
wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
- wpa_hexdump(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
- return 0;
+ wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
+
+ if (key_idx == 0) {
+ /*
+ * In IBSS RSN, the pairwise key from the 4-way handshake
+ * initiated by the peer with highest MAC address is used.
+ */
+ if (os_memcmp(peer->ibss_rsn->wpa_s->own_addr, peer->addr,
+ ETH_ALEN) > 0) {
+ wpa_printf(MSG_DEBUG, "SUPP: Do not use this PTK");
+ return 0;
+ }
+ }
+
+ return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx,
+ set_tx, seq, seq_len, key, key_len);
}
return -1;
ctx->ctx = peer;
+ ctx->msg_ctx = peer->ibss_rsn->wpa_s;
ctx->set_state = supp_set_state;
ctx->ether_send = supp_ether_send;
ctx->get_beacon_ie = supp_get_beacon_ie;
}
+static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
+ const u8 *addr, int idx, u8 *key, size_t key_len)
+{
+ struct ibss_rsn *ibss_rsn = ctx;
+ u8 seq[6];
+
+ os_memset(seq, 0, sizeof(seq));
+
+ if (addr) {
+ wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
+ " key_idx=%d)",
+ __func__, alg, MAC2STR(addr), idx);
+ } else {
+ wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
+ __func__, alg, idx);
+ }
+ wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);
+
+ if (idx == 0) {
+ /*
+ * In IBSS RSN, the pairwise key from the 4-way handshake
+ * initiated by the peer with highest MAC address is used.
+ */
+ if (addr == NULL ||
+ os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) {
+ wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK");
+ return 0;
+ }
+ }
+
+ return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
+ 1, seq, 6, key, key_len);
+}
+
+
static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
const u8 *own_addr)
{
cb.logger = auth_logger;
cb.send_eapol = auth_send_eapol;
cb.get_psk = auth_get_psk;
+ cb.set_key = auth_set_key;
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
if (ibss_rsn->auth_group == NULL) {
return -1;
}
- wpa_auth_sm_event(peer->auth, WPA_ASSOC);
+ if (wpa_auth_sm_event(peer->auth, WPA_ASSOC))
+ return -1;
- wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth);
+ if (wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth))
+ return -1;
return 0;
}