3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-22 21:22:37 +01:00

handshake: Add OCV utilities

Add a utility for setting the OCI obtained from the hardware (prior to
handshake starting) as well as a utility to validate the OCI obtained
from the peer.
This commit is contained in:
Denis Kenzior 2021-09-20 14:29:05 -05:00
parent 764376b677
commit 8ada894f70
2 changed files with 62 additions and 0 deletions

View File

@ -42,6 +42,7 @@
#include "src/util.h" #include "src/util.h"
#include "src/handshake.h" #include "src/handshake.h"
#include "src/erp.h" #include "src/erp.h"
#include "src/band.h"
static inline unsigned int n_ecc_groups() static inline unsigned int n_ecc_groups()
{ {
@ -112,6 +113,8 @@ void handshake_state_free(struct handshake_state *s)
if (s->erp_cache) if (s->erp_cache)
erp_cache_put(s->erp_cache); erp_cache_put(s->erp_cache);
l_free(s->chandef);
if (s->passphrase) { if (s->passphrase) {
explicit_bzero(s->passphrase, strlen(s->passphrase)); explicit_bzero(s->passphrase, strlen(s->passphrase));
l_free(s->passphrase); l_free(s->passphrase);
@ -188,6 +191,8 @@ valid_ie:
l_free(s->authenticator_ie); l_free(s->authenticator_ie);
s->authenticator_ie = l_memdup(ie, ie[1] + 2u); s->authenticator_ie = l_memdup(ie, ie[1] + 2u);
s->authenticator_ocvc = info.ocvc;
return true; return true;
} }
@ -228,6 +233,7 @@ valid_ie:
s->group_cipher = info.group_cipher; s->group_cipher = info.group_cipher;
s->group_management_cipher = info.group_management_cipher; s->group_management_cipher = info.group_management_cipher;
s->akm_suite = info.akm_suites; s->akm_suite = info.akm_suites;
s->supplicant_ocvc = info.ocvc;
/* /*
* Don't set MFP for OSEN otherwise EAPoL will attempt to negotiate a * Don't set MFP for OSEN otherwise EAPoL will attempt to negotiate a
@ -1014,3 +1020,51 @@ bool handshake_state_add_ecc_sae_pt(struct handshake_state *s,
s->ecc_sae_pts[i] = l_ecc_point_clone(pt); s->ecc_sae_pts[i] = l_ecc_point_clone(pt);
return true; return true;
} }
void handshake_state_set_chandef(struct handshake_state *s,
struct band_chandef *chandef)
{
s->chandef = chandef;
}
int handshake_state_verify_oci(struct handshake_state *s, const uint8_t *oci,
size_t oci_len)
{
int r = -ENOENT;
bool ocvc;
l_debug("oci_len: %zu", oci ? oci_len : 0);
if (!oci)
goto done;
r = -EBADMSG;
if (oci_len != 3)
goto done;
l_debug("operating_class: %hu", oci[0]);
l_debug("primary_channel_number: %hu", oci[1]);
l_debug("frequency segment 1 channel number: %hu", oci[2]);
r = -EINVAL;
if (!s->chandef) {
l_debug("Own chandef unavailable");
goto done;
}
r = oci_verify(oci, s->chandef);
if (r < 0)
l_debug("OCI verification failed: %s", strerror(-r));
done:
if (!r)
return r;
/* Only enforce validation if we're configured to do so */
ocvc = s->authenticator ? s->authenticator_ocvc : s->supplicant_ocvc;
if (!ocvc)
r = 0;
return r;
}

View File

@ -126,6 +126,8 @@ struct handshake_state {
bool wait_for_gtk : 1; bool wait_for_gtk : 1;
bool no_rekey : 1; bool no_rekey : 1;
bool support_fils : 1; bool support_fils : 1;
bool authenticator_ocvc : 1;
bool supplicant_ocvc : 1;
uint8_t ssid[32]; uint8_t ssid[32];
size_t ssid_len; size_t ssid_len;
char *passphrase; char *passphrase;
@ -143,6 +145,7 @@ struct handshake_state {
uint32_t go_ip_addr; uint32_t go_ip_addr;
uint8_t *fils_ip_req_ie; uint8_t *fils_ip_req_ie;
uint8_t *fils_ip_resp_ie; uint8_t *fils_ip_resp_ie;
struct band_chandef *chandef;
void *user_data; void *user_data;
void (*free)(struct handshake_state *s); void (*free)(struct handshake_state *s);
@ -242,6 +245,11 @@ bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped,
void handshake_state_set_gtk(struct handshake_state *s, const uint8_t *key, void handshake_state_set_gtk(struct handshake_state *s, const uint8_t *key,
unsigned int key_index, const uint8_t *rsc); unsigned int key_index, const uint8_t *rsc);
void handshake_state_set_chandef(struct handshake_state *s,
struct band_chandef *chandef);
int handshake_state_verify_oci(struct handshake_state *s, const uint8_t *oci,
size_t oci_len);
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);