int WIFI_group_key_set(const unsigned char* pKeyValue, int keylength, int key_idx, const unsigned char* keyIV) { struct wpa_supplicant *wpa_s = g_wpa_s; int alg; u8 msk_len; wpa_hexdump(MSG_DEBUG, "WIFI_group_key_set: KEYSC", keyIV, 16); wpa_printf(MSG_DEBUG, "[%s: %d] keylength = %d key_index = %d\n", __FUNCTION__, __LINE__, keylength, key_idx); alg = WPA_ALG_SMS4; msk_len = 32; if (wpa_drv_set_key(wpa_s, alg, (u8 *) "\xff\xff\xff\xff\xff\xff", key_idx, 1, keyIV, 16, pKeyValue, keylength) < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to set MSK to " "the driver."); return -1; } return 0; }
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_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; } } if (is_broadcast_ether_addr(addr)) addr = peer->addr; return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); }
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 wpa_supplicant_set_key(void *_wpa_s, 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 wpa_supplicant *wpa_s = _wpa_s; if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) { /* Clear the MIC error counter when setting a new PTK. */ wpa_s->mic_errors_seen = 0; } #ifdef CONFIG_TESTING_GET_GTK if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) && alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) { os_memcpy(wpa_s->last_gtk, key, key_len); wpa_s->last_gtk_len = key_len; } #endif /* CONFIG_TESTING_GET_GTK */ #ifdef CONFIG_TESTING_OPTIONS if (addr && !is_broadcast_ether_addr(addr)) { wpa_s->last_tk_alg = alg; os_memcpy(wpa_s->last_tk_addr, addr, ETH_ALEN); wpa_s->last_tk_key_idx = key_idx; if (key) os_memcpy(wpa_s->last_tk, key, key_len); wpa_s->last_tk_len = key_len; } #endif /* CONFIG_TESTING_OPTIONS */ return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); }
static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, struct ibss_rsn_peer *peer, const u8* addr) { wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); if (peer && peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH)) { /* Clear the TK for this pair to allow recovery from the case * where the peer STA has restarted and lost its key while we * still have a pairwise key configured. */ wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer " MACSTR, MAC2STR(addr)); wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL, 0); } if (peer && peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) { if (peer->own_auth_tx.sec) { struct os_reltime now, diff; os_get_reltime(&now); os_reltime_sub(&now, &peer->own_auth_tx, &diff); if (diff.sec == 0 && diff.usec < 500000) { wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX", (int) diff.usec); goto skip_reinit; } } /* * A peer sent us an Authentication frame even though it already * started an EAPOL session. We should reinit state machines * here, but it's much more complicated than just deleting and * recreating the state machine */ wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station " MACSTR, MAC2STR(addr)); ibss_rsn_stop(ibss_rsn, addr); peer = NULL; } if (!peer) { peer = ibss_rsn_peer_init(ibss_rsn, addr); if (!peer) return; wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR, MAC2STR(addr)); } skip_reinit: /* reply with an Authentication frame now, before sending an EAPOL */ ibss_rsn_send_auth(ibss_rsn, addr, 2); /* no need to start another AUTH challenge in the other way.. */ ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US); }
static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr) { struct wpa_auth_config conf; struct wpa_auth_callbacks cb; u8 seq[6] = {}; wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); os_memset(&conf, 0, sizeof(conf)); conf.wpa = 2; conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE; conf.wpa_pairwise = WPA_CIPHER_CCMP; conf.rsn_pairwise = WPA_CIPHER_CCMP; conf.wpa_group = WPA_CIPHER_CCMP; conf.eapol_version = 0; conf.wpa_group_rekey = -1; os_memset(&cb, 0, sizeof(cb)); cb.ctx = rsn; cb.logger = auth_logger; cb.get_psk = auth_get_psk; cb.set_key = auth_set_key; cb.start_ampe = auth_start_ampe; rsn->auth = wpa_init(addr, &conf, &cb); if (rsn->auth == NULL) { wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); return -1; } /* TODO: support rekeying */ if (random_get_bytes(rsn->mgtk, 16) < 0) { wpa_deinit(rsn->auth); return -1; } /* group mgmt */ wpa_drv_set_key(rsn->wpa_s, WPA_ALG_IGTK, NULL, 4, 1, seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk)); /* group privacy / data frames */ wpa_drv_set_key(rsn->wpa_s, WPA_ALG_CCMP, NULL, 1, 1, seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk)); return 0; }
static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success, void *ctx) { struct wpa_supplicant *wpa_s = ctx; int res, pmk_len; u8 pmk[PMK_LEN]; wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully", success ? "" : "un"); if (wpas_wps_eapol_cb(wpa_s) > 0) return; if (!success) { /* * Make sure we do not get stuck here waiting for long EAPOL * timeout if the AP does not disconnect in case of * authentication failure. */ wpa_supplicant_req_auth_timeout(wpa_s, 2, 0); } if (!success || !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) return; if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) return; wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way " "handshake"); pmk_len = PMK_LEN; res = eapol_sm_get_key(eapol, pmk, PMK_LEN); if (res) { /* * EAP-LEAP is an exception from other EAP methods: it * uses only 16-byte PMK. */ res = eapol_sm_get_key(eapol, pmk, 16); pmk_len = 16; } if (res) { wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state " "machines"); return; } if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, pmk_len)) { wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver"); } wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); }
static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk, size_t pmk_len) { struct wpa_supplicant *wpa_s = ctx; if (wpa_s->conf->key_mgmt_offload) return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, pmk_len); else return 0; }
static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk, size_t pmk_len) { struct wpa_supplicant *wpa_s = ctx; if (wpa_s->conf->key_mgmt_offload && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, pmk_len); else return 0; }
static int wpa_supplicant_set_key(void *_wpa_s, 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 wpa_supplicant *wpa_s = _wpa_s; if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) { /* Clear the MIC error counter when setting a new PTK. */ wpa_s->mic_errors_seen = 0; } return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); }
/** * wpa_eapol_set_wep_key - set WEP key for the driver * @ctx: Pointer to wpa_supplicant data (wpa_s) * @unicast: 1 = individual unicast key, 0 = broadcast key * @keyidx: WEP key index (0..3) * @key: Pointer to key data * @keylen: Key length in bytes * Returns: 0 on success or < 0 on error. */ static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx, const u8 *key, size_t keylen) { struct wpa_supplicant *wpa_s = ctx; if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 : WPA_CIPHER_WEP104; if (unicast) wpa_s->pairwise_cipher = cipher; else wpa_s->group_cipher = cipher; } return wpa_drv_set_key(wpa_s, WPA_ALG_WEP, unicast ? wpa_s->bssid : NULL, keyidx, unicast, NULL, 0, key, keylen); }
void ibss_rsn_connected(struct ibss_rsn *ibss_rsn) { u8 seq[6]; wpa_printf(MSG_DEBUG, "RSN: IBSS connected notification"); if (ibss_rsn->init_gtk_idx) { wpa_printf(MSG_DEBUG, "RSN: Set initial IBSS TX GTK"); os_memset(seq, 0, sizeof(seq)); if (wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_CCMP, broadcast_ether_addr, ibss_rsn->init_gtk_idx, 1, seq, sizeof(seq), ibss_rsn->init_gtk, 16) < 0) wpa_printf(MSG_INFO, "RSN: Failed to set IBSS TX GTK"); ibss_rsn->init_gtk_idx = 0; os_memset(ibss_rsn->init_gtk, 0, sizeof(ibss_rsn->init_gtk)); } }
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 mesh_rsn *mesh_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); return wpa_drv_set_key(mesh_rsn->wpa_s, alg, addr, idx, 1, seq, 6, key, key_len); }
int WIFI_unicast_key_set(const char* pKeyValue, int keylength, int key_idx) { struct wpa_supplicant *wpa_s = g_wpa_s; int alg, keylen, rsclen; u8 *key_rsc; u8 null_rsc[16] = { 0, 0, 0, 0, 0, 0, 0, 0 }; printf("[%s: %d] keylength = %d key_index = %d\n", __FUNCTION__, __LINE__, keylength, key_idx); alg = WPA_ALG_SMS4; keylen = 32; rsclen = 16; key_rsc = null_rsc; if (wpa_drv_set_key(wpa_s, alg, wpa_s->bssid, key_idx, 1, key_rsc, rsclen, (u8 *) pKeyValue, keylen) < 0) { wpa_printf(MSG_WARNING, "WIFI_unicast_key_set: Failed to set PTK to the driver"); return -1; } return 0; }
static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, enum eapol_supp_result result, void *ctx) { struct wpa_supplicant *wpa_s = ctx; int res, pmk_len; u8 pmk[PMK_LEN]; wpa_printf(MSG_DEBUG, "EAPOL authentication completed - result=%s", result_str(result)); if (wpas_wps_eapol_cb(wpa_s) > 0) return; wpa_s->eap_expected_failure = result == EAPOL_SUPP_RESULT_EXPECTED_FAILURE; if (result != EAPOL_SUPP_RESULT_SUCCESS) { /* * Make sure we do not get stuck here waiting for long EAPOL * timeout if the AP does not disconnect in case of * authentication failure. */ wpa_supplicant_req_auth_timeout(wpa_s, 2, 0); } else { ieee802_1x_notify_create_actor(wpa_s, wpa_s->last_eapol_src); } if (result != EAPOL_SUPP_RESULT_SUCCESS || !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) return; if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) return; wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way " "handshake"); pmk_len = PMK_LEN; if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) { #ifdef CONFIG_IEEE80211R u8 buf[2 * PMK_LEN]; wpa_printf(MSG_DEBUG, "RSN: Use FT XXKey as PMK for " "driver-based 4-way hs and FT"); res = eapol_sm_get_key(eapol, buf, 2 * PMK_LEN); if (res == 0) { os_memcpy(pmk, buf + PMK_LEN, PMK_LEN); os_memset(buf, 0, sizeof(buf)); } #else /* CONFIG_IEEE80211R */ res = -1; #endif /* CONFIG_IEEE80211R */ } else { res = eapol_sm_get_key(eapol, pmk, PMK_LEN); if (res) { /* * EAP-LEAP is an exception from other EAP methods: it * uses only 16-byte PMK. */ res = eapol_sm_get_key(eapol, pmk, 16); pmk_len = 16; } } if (res) { wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state " "machines"); return; } wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way " "handshake", pmk, pmk_len); if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, pmk_len)) { wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver"); } wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); }