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/eapol.h src/eapol.c \
|
||||||
src/eapolutil.h src/eapolutil.c \
|
src/eapolutil.h src/eapolutil.c \
|
||||||
src/handshake.h src/handshake.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.h src/eap.c src/eap-private.h \
|
||||||
src/util.h src/util.c \
|
src/util.h src/util.c \
|
||||||
src/simauth.h src/simauth.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/eapol.h src/eapol.c \
|
||||||
src/eapolutil.h src/eapolutil.c \
|
src/eapolutil.h src/eapolutil.c \
|
||||||
src/handshake.h src/handshake.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.h src/eap.c src/eap-private.h \
|
||||||
src/eap-tls.c src/eap-ttls.c \
|
src/eap-tls.c src/eap-ttls.c \
|
||||||
src/eap-md5.c src/util.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/eapol.h src/eapol.c \
|
||||||
src/eapolutil.h src/eapolutil.c \
|
src/eapolutil.h src/eapolutil.c \
|
||||||
src/handshake.h src/handshake.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.h src/eap.c src/eap-private.h \
|
||||||
src/util.h src/util.c \
|
src/util.h src/util.c \
|
||||||
src/erp.h src/erp.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/crypto.h src/crypto.c \
|
||||||
src/ie.h src/ie.c \
|
src/ie.h src/ie.c \
|
||||||
src/handshake.h src/handshake.c \
|
src/handshake.h src/handshake.c \
|
||||||
|
src/pmksa.h src/pmksa.c \
|
||||||
src/erp.h src/erp.c \
|
src/erp.h src/erp.c \
|
||||||
src/band.h src/band.c \
|
src/band.h src/band.c \
|
||||||
src/util.h src/util.c \
|
src/util.h src/util.c \
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "src/handshake.h"
|
#include "src/handshake.h"
|
||||||
#include "src/erp.h"
|
#include "src/erp.h"
|
||||||
#include "src/band.h"
|
#include "src/band.h"
|
||||||
|
#include "src/pmksa.h"
|
||||||
|
|
||||||
static inline unsigned int n_ecc_groups(void)
|
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->fils_ip_resp_ie);
|
||||||
l_free(s->vendor_ies);
|
l_free(s->vendor_ies);
|
||||||
|
|
||||||
|
if (s->have_pmksa)
|
||||||
|
l_free(s->pmksa);
|
||||||
|
|
||||||
if (s->erp_cache)
|
if (s->erp_cache)
|
||||||
erp_cache_put(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;
|
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) {
|
if (install_tk) {
|
||||||
uint32_t cipher = ie_rsn_cipher_suite_to_cipher(
|
uint32_t cipher = ie_rsn_cipher_suite_to_cipher(
|
||||||
s->pairwise_cipher);
|
s->pairwise_cipher);
|
||||||
@ -1203,3 +1212,71 @@ done:
|
|||||||
|
|
||||||
return r;
|
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;
|
struct handshake_state;
|
||||||
enum crypto_cipher;
|
enum crypto_cipher;
|
||||||
struct eapol_frame;
|
struct eapol_frame;
|
||||||
|
struct pmksa;
|
||||||
|
|
||||||
enum handshake_kde {
|
enum handshake_kde {
|
||||||
/* 802.11-2020 Table 12-9 in section 12.7.2 */
|
/* 802.11-2020 Table 12-9 in section 12.7.2 */
|
||||||
@ -141,6 +142,11 @@ struct handshake_state {
|
|||||||
bool supplicant_ocvc : 1;
|
bool supplicant_ocvc : 1;
|
||||||
bool ext_key_id_capable : 1;
|
bool ext_key_id_capable : 1;
|
||||||
bool force_default_ecc_group : 1;
|
bool force_default_ecc_group : 1;
|
||||||
|
bool have_pmksa : 1;
|
||||||
|
union {
|
||||||
|
struct pmksa *pmksa;
|
||||||
|
uint64_t expiration;
|
||||||
|
};
|
||||||
uint8_t ssid[SSID_MAX_SIZE];
|
uint8_t ssid[SSID_MAX_SIZE];
|
||||||
size_t ssid_len;
|
size_t ssid_len;
|
||||||
char *passphrase;
|
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,
|
int handshake_state_verify_oci(struct handshake_state *s, const uint8_t *oci,
|
||||||
size_t oci_len);
|
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,
|
bool handshake_util_ap_ie_matches(const struct ie_rsn_info *msg_info,
|
||||||
const uint8_t *scan_ie, bool is_wpa);
|
const uint8_t *scan_ie, bool is_wpa);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user