mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-02-10 15:24:09 +01:00
handshake: Add pmksa setter & stealer
The majority of this patch was authored by Denis Kenzior, but I have appended setting the PMK inside handshake_state_set_pmksa as well as checking if the pmkid exists in handshake_state_steal_pmkid. Authored-by: Denis Kenzior <denkenz@gmail.com> Authored-by: James Prestwood <prestwoj@gmail.com>
This commit is contained in:
parent
235f6e5f14
commit
c36358cc7c
@ -458,6 +458,7 @@ unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/util.h src/util.c \
|
||||
src/simauth.h src/simauth.c \
|
||||
@ -517,6 +518,7 @@ unit_test_eapol_SOURCES = unit/test-eapol.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/eap-tls.c src/eap-ttls.c \
|
||||
src/eap-md5.c src/util.c \
|
||||
@ -547,6 +549,7 @@ unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/util.h src/util.c \
|
||||
src/erp.h src/erp.c \
|
||||
@ -565,6 +568,7 @@ unit_test_sae_SOURCES = unit/test-sae.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/util.h src/util.c \
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "src/handshake.h"
|
||||
#include "src/erp.h"
|
||||
#include "src/band.h"
|
||||
#include "src/pmksa.h"
|
||||
|
||||
static inline unsigned int n_ecc_groups(void)
|
||||
{
|
||||
@ -138,6 +139,9 @@ void handshake_state_unref(struct handshake_state *s)
|
||||
l_free(s->fils_ip_resp_ie);
|
||||
l_free(s->vendor_ies);
|
||||
|
||||
if (s->have_pmksa)
|
||||
l_free(s->pmksa);
|
||||
|
||||
if (s->erp_cache)
|
||||
erp_cache_put(s->erp_cache);
|
||||
|
||||
@ -701,6 +705,11 @@ void handshake_state_install_ptk(struct handshake_state *s)
|
||||
{
|
||||
s->ptk_complete = true;
|
||||
|
||||
if (!s->have_pmksa && IE_AKM_IS_SAE(s->akm_suite)) {
|
||||
l_debug("Adding PMKSA expiration");
|
||||
s->expiration = l_time_now() + pmksa_lifetime();
|
||||
}
|
||||
|
||||
if (install_tk) {
|
||||
uint32_t cipher = ie_rsn_cipher_suite_to_cipher(
|
||||
s->pairwise_cipher);
|
||||
@ -1203,3 +1212,71 @@ done:
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool handshake_state_set_pmksa(struct handshake_state *s,
|
||||
struct pmksa *pmksa)
|
||||
{
|
||||
/* checks for both expiration || pmksa being set */
|
||||
if (s->expiration)
|
||||
return false;
|
||||
|
||||
s->pmksa = pmksa;
|
||||
s->have_pmksa = true;
|
||||
|
||||
handshake_state_set_pmkid(s, pmksa->pmkid);
|
||||
handshake_state_set_pmk(s, pmksa->pmk, pmksa->pmk_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct pmksa *handshake_state_steal_pmksa(struct handshake_state *s)
|
||||
{
|
||||
struct pmksa *pmksa;
|
||||
uint64_t now = l_time_now();
|
||||
|
||||
if (s->have_pmksa) {
|
||||
pmksa = l_steal_ptr(s->pmksa);
|
||||
s->have_pmksa = false;
|
||||
|
||||
if (l_time_after(now, pmksa->expiration)) {
|
||||
l_free(pmksa);
|
||||
pmksa = NULL;
|
||||
}
|
||||
|
||||
return pmksa;
|
||||
}
|
||||
|
||||
if (s->expiration && l_time_after(now, s->expiration)) {
|
||||
s->expiration = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!s->have_pmkid)
|
||||
return NULL;
|
||||
|
||||
pmksa = l_new(struct pmksa, 1);
|
||||
pmksa->expiration = s->expiration;
|
||||
memcpy(pmksa->spa, s->spa, sizeof(s->spa));
|
||||
memcpy(pmksa->aa, s->aa, sizeof(s->aa));
|
||||
memcpy(pmksa->ssid, s->ssid, s->ssid_len);
|
||||
pmksa->ssid_len = s->ssid_len;
|
||||
pmksa->akm = s->akm_suite;
|
||||
memcpy(pmksa->pmkid, s->pmkid, sizeof(s->pmkid));
|
||||
pmksa->pmk_len = s->pmk_len;
|
||||
memcpy(pmksa->pmk, s->pmk, s->pmk_len);
|
||||
|
||||
return pmksa;
|
||||
}
|
||||
|
||||
void handshake_state_cache_pmksa(struct handshake_state *s)
|
||||
{
|
||||
struct pmksa *pmksa = handshake_state_steal_pmksa(s);
|
||||
|
||||
l_debug("%p", pmksa);
|
||||
|
||||
if (!pmksa)
|
||||
return;
|
||||
|
||||
if (L_WARN_ON(pmksa_cache_put(pmksa) < 0))
|
||||
l_free(pmksa);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
struct handshake_state;
|
||||
enum crypto_cipher;
|
||||
struct eapol_frame;
|
||||
struct pmksa;
|
||||
|
||||
enum handshake_kde {
|
||||
/* 802.11-2020 Table 12-9 in section 12.7.2 */
|
||||
@ -141,6 +142,11 @@ struct handshake_state {
|
||||
bool supplicant_ocvc : 1;
|
||||
bool ext_key_id_capable : 1;
|
||||
bool force_default_ecc_group : 1;
|
||||
bool have_pmksa : 1;
|
||||
union {
|
||||
struct pmksa *pmksa;
|
||||
uint64_t expiration;
|
||||
};
|
||||
uint8_t ssid[SSID_MAX_SIZE];
|
||||
size_t ssid_len;
|
||||
char *passphrase;
|
||||
@ -302,6 +308,9 @@ void handshake_state_set_chandef(struct handshake_state *s,
|
||||
int handshake_state_verify_oci(struct handshake_state *s, const uint8_t *oci,
|
||||
size_t oci_len);
|
||||
|
||||
bool handshake_state_set_pmksa(struct handshake_state *s, struct pmksa *pmksa);
|
||||
void handshake_state_cache_pmksa(struct handshake_state *s);
|
||||
|
||||
bool handshake_util_ap_ie_matches(const struct ie_rsn_info *msg_info,
|
||||
const uint8_t *scan_ie, bool is_wpa);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user