3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-25 17:59:25 +01:00

fils: support OCI in reassociation

This commit is contained in:
James Prestwood 2021-09-28 14:27:36 -07:00 committed by Denis Kenzior
parent c4c14f3ac0
commit d68c9e69fa
3 changed files with 36 additions and 2 deletions

View File

@ -37,6 +37,7 @@
#include "src/missing.h" #include "src/missing.h"
#include "src/erp.h" #include "src/erp.h"
#include "src/auth-proto.h" #include "src/auth-proto.h"
#include "src/band.h"
#define FILS_NONCE_LEN 16 #define FILS_NONCE_LEN 16
#define FILS_SESSION_LEN 8 #define FILS_SESSION_LEN 8
@ -49,6 +50,7 @@ struct fils_sm {
fils_tx_authenticate_func_t auth; fils_tx_authenticate_func_t auth;
fils_tx_associate_func_t assoc; fils_tx_associate_func_t assoc;
fils_get_oci_func_t get_oci;
uint8_t nonce[FILS_NONCE_LEN]; uint8_t nonce[FILS_NONCE_LEN];
uint8_t anonce[FILS_NONCE_LEN]; uint8_t anonce[FILS_NONCE_LEN];
@ -148,12 +150,13 @@ static int fils_derive_key_data(struct fils_sm *fils)
uint8_t data[44]; uint8_t data[44];
uint8_t *ptr = data; uint8_t *ptr = data;
size_t hash_len; size_t hash_len;
struct iovec iov[4]; struct iovec iov[5];
size_t iov_elems = 0; size_t iov_elems = 0;
size_t fils_ft_len = 0; size_t fils_ft_len = 0;
bool sha384; bool sha384;
size_t ie_len; size_t ie_len;
uint8_t *rsne = NULL; uint8_t *rsne = NULL;
uint8_t oci[6];
rmsk = erp_get_rmsk(fils->erp, &rmsk_len); rmsk = erp_get_rmsk(fils->erp, &rmsk_len);
@ -302,6 +305,23 @@ static int fils_derive_key_data(struct fils_sm *fils)
iov_elems += 1; iov_elems += 1;
} }
/*
* IEEE 802.11 Section 12.11.2.6.2
* "If dot11RSNAOperatingChannelValidationActivated is true and AP
* indicates OCVC capability, the STA shall include OCI element in the
* request"
*/
if (fils->hs->supplicant_ocvc && fils->hs->chandef) {
oci[0] = IE_TYPE_EXTENSION;
oci[1] = 4;
oci[2] = IE_TYPE_OCI & 0xff;
oci_from_chandef(fils->hs->chandef, oci + 3);
iov[iov_elems].iov_base = oci;
iov[iov_elems].iov_len = 6;
iov_elems++;
}
memcpy(data, fils->nonce, sizeof(fils->nonce)); memcpy(data, fils->nonce, sizeof(fils->nonce));
memcpy(data + sizeof(fils->nonce), fils->anonce, sizeof(fils->anonce)); memcpy(data + sizeof(fils->nonce), fils->anonce, sizeof(fils->anonce));
@ -436,12 +456,20 @@ static int fils_rx_authenticate(struct auth_proto *driver, const uint8_t *frame,
if (erp_rx_packet(fils->erp, wrapped, wrapped_len) < 0) if (erp_rx_packet(fils->erp, wrapped, wrapped_len) < 0)
goto invalid_ies; goto invalid_ies;
return fils_derive_key_data(fils); return fils->get_oci(fils->user_data);
invalid_ies: invalid_ies:
return MMPDU_STATUS_CODE_INVALID_ELEMENT; return MMPDU_STATUS_CODE_INVALID_ELEMENT;
} }
static int fils_rx_oci(struct auth_proto *driver)
{
struct fils_sm *fils = l_container_of(driver, struct fils_sm, ap);
return fils_derive_key_data(fils);
}
static int fils_rx_associate(struct auth_proto *driver, const uint8_t *frame, static int fils_rx_associate(struct auth_proto *driver, const uint8_t *frame,
size_t len) size_t len)
{ {
@ -564,6 +592,7 @@ invalid_ies:
struct auth_proto *fils_sm_new(struct handshake_state *hs, struct auth_proto *fils_sm_new(struct handshake_state *hs,
fils_tx_authenticate_func_t auth, fils_tx_authenticate_func_t auth,
fils_tx_associate_func_t assoc, fils_tx_associate_func_t assoc,
fils_get_oci_func_t get_oci,
void *user_data) void *user_data)
{ {
struct fils_sm *fils; struct fils_sm *fils;
@ -572,11 +601,13 @@ struct auth_proto *fils_sm_new(struct handshake_state *hs,
fils->auth = auth; fils->auth = auth;
fils->assoc = assoc; fils->assoc = assoc;
fils->get_oci = get_oci;
fils->user_data = user_data; fils->user_data = user_data;
fils->hs = hs; fils->hs = hs;
fils->ap.start = fils_start; fils->ap.start = fils_start;
fils->ap.free = fils_free; fils->ap.free = fils_free;
fils->ap.rx_oci = fils_rx_oci;
fils->ap.rx_authenticate = fils_rx_authenticate; fils->ap.rx_authenticate = fils_rx_authenticate;
fils->ap.rx_associate = fils_rx_associate; fils->ap.rx_associate = fils_rx_associate;

View File

@ -30,8 +30,10 @@ typedef void (*fils_tx_associate_func_t)(struct iovec *iov, size_t iov_len,
const uint8_t *kek, size_t kek_len, const uint8_t *kek, size_t kek_len,
const uint8_t *nonces, size_t nonces_len, const uint8_t *nonces, size_t nonces_len,
void *user_data); void *user_data);
typedef int (*fils_get_oci_func_t)(void *user_data);
struct auth_proto *fils_sm_new(struct handshake_state *hs, struct auth_proto *fils_sm_new(struct handshake_state *hs,
fils_tx_authenticate_func_t auth, fils_tx_authenticate_func_t auth,
fils_tx_associate_func_t assoc, fils_tx_associate_func_t assoc,
fils_get_oci_func_t get_oci,
void *user_data); void *user_data);

View File

@ -3689,6 +3689,7 @@ static void netdev_connect_common(struct netdev *netdev,
case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384: case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384:
netdev->ap = fils_sm_new(hs, netdev_fils_tx_authenticate, netdev->ap = fils_sm_new(hs, netdev_fils_tx_authenticate,
netdev_fils_tx_associate, netdev_fils_tx_associate,
netdev_get_oci,
netdev); netdev);
break; break;
default: default: