mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 21:22:37 +01:00
erp: remove 'complete' callback
Since ERP is only used for FILS and not behaving in the 'normal' ERP fashion (dealing with actual EAP data, timeouts etc.) we can structure ERP as a more synchronous protocol, removing the need for a complete callback. Now, erp_rx_packet returns a status, so FILS can decide how to handle any failures. The complete callback was also removed in favor of a getter for the RMSK (erp_get_rmsk). This allows FILS to syncronously handle ERP, and potentially fail directly in fils_rx_authenticate.
This commit is contained in:
parent
d02c038a0d
commit
8c11fdabcc
26
src/erp.c
26
src/erp.c
@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <ell/ell.h>
|
||||
|
||||
@ -50,11 +51,11 @@ struct erp_cache_entry {
|
||||
|
||||
struct erp_state {
|
||||
erp_tx_packet_func_t tx_packet;
|
||||
erp_complete_func_t complete;
|
||||
void *user_data;
|
||||
|
||||
struct erp_cache_entry *cache;
|
||||
|
||||
uint8_t rmsk[64];
|
||||
uint8_t r_rk[64];
|
||||
uint8_t r_ik[64];
|
||||
char keyname_nai[254];
|
||||
@ -330,7 +331,7 @@ static bool erp_derive_reauth_keys(const uint8_t *emsk, size_t emsk_len,
|
||||
|
||||
struct erp_state *erp_new(struct erp_cache_entry *cache,
|
||||
erp_tx_packet_func_t tx_packet,
|
||||
erp_complete_func_t complete, void *user_data)
|
||||
void *user_data)
|
||||
{
|
||||
struct erp_state *erp;
|
||||
|
||||
@ -340,7 +341,6 @@ struct erp_state *erp_new(struct erp_cache_entry *cache,
|
||||
erp = l_new(struct erp_state, 1);
|
||||
|
||||
erp->tx_packet = tx_packet;
|
||||
erp->complete = complete;
|
||||
erp->user_data = user_data;
|
||||
erp->cache = cache;
|
||||
|
||||
@ -398,12 +398,11 @@ bool erp_start(struct erp_state *erp)
|
||||
return true;
|
||||
}
|
||||
|
||||
void erp_rx_packet(struct erp_state *erp, const uint8_t *pkt, size_t len)
|
||||
int erp_rx_packet(struct erp_state *erp, const uint8_t *pkt, size_t len)
|
||||
{
|
||||
struct erp_tlv_iter iter;
|
||||
enum eap_erp_cryptosuite cs;
|
||||
uint8_t hash[16];
|
||||
uint8_t rmsk[64];
|
||||
char info[256];
|
||||
char *ptr = info;
|
||||
const uint8_t *nai = NULL;
|
||||
@ -425,7 +424,7 @@ void erp_rx_packet(struct erp_state *erp, const uint8_t *pkt, size_t len)
|
||||
type = pkt[4];
|
||||
|
||||
if (type != ERP_TYPE_REAUTH)
|
||||
return;
|
||||
goto eap_failed;
|
||||
|
||||
r = util_is_bit_set(pkt[5], 0);
|
||||
if (r)
|
||||
@ -505,15 +504,18 @@ void erp_rx_packet(struct erp_state *erp, const uint8_t *pkt, size_t len)
|
||||
ptr += 2;
|
||||
|
||||
hkdf_expand(L_CHECKSUM_SHA256, erp->r_rk, erp->cache->emsk_len,
|
||||
info, ptr - info, rmsk, erp->cache->emsk_len);
|
||||
info, ptr - info, erp->rmsk, erp->cache->emsk_len);
|
||||
|
||||
erp->complete(ERP_RESULT_SUCCESS, rmsk, erp->cache->emsk_len,
|
||||
erp->user_data);
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
eap_failed:
|
||||
erp->complete(ERP_RESULT_FAIL, NULL, 0, erp->user_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void erp_get_rmsk(struct erp_state *erp, void **rmsk, size_t *rmsk_len)
|
||||
{
|
||||
*rmsk = erp->rmsk;
|
||||
*rmsk_len = erp->cache->emsk_len;
|
||||
}
|
||||
|
||||
void erp_init(void)
|
||||
|
@ -30,16 +30,16 @@ enum erp_result {
|
||||
|
||||
typedef void (*erp_tx_packet_func_t)(const uint8_t *erp_data, size_t len,
|
||||
void *user_data);
|
||||
typedef void (*erp_complete_func_t)(enum erp_result result, const void *rmsk,
|
||||
size_t rmsk_len, void *user_data);
|
||||
|
||||
struct erp_state *erp_new(struct erp_cache_entry *cache,
|
||||
erp_tx_packet_func_t tx_packet,
|
||||
erp_complete_func_t complete, void *user_data);
|
||||
void *user_data);
|
||||
void erp_free(struct erp_state *erp);
|
||||
|
||||
bool erp_start(struct erp_state *erp);
|
||||
void erp_rx_packet(struct erp_state *erp, const uint8_t *erp_data, size_t len);
|
||||
int erp_rx_packet(struct erp_state *erp, const uint8_t *erp_data, size_t len);
|
||||
|
||||
void erp_get_rmsk(struct erp_state *erp, void **rmsk, size_t *rmsk_len);
|
||||
|
||||
void erp_cache_add(const char *id, const void *session_id, size_t session_len,
|
||||
const void *emsk, size_t emsk_len,
|
||||
|
25
src/fils.c
25
src/fils.c
@ -119,10 +119,9 @@ static void fils_erp_tx_func(const uint8_t *eap_data, size_t len,
|
||||
fils->auth(data, ptr - data + tlv_len, fils->user_data);
|
||||
}
|
||||
|
||||
static void fils_erp_complete(enum erp_result result, const void *rmsk,
|
||||
size_t rmsk_len, void *user_data)
|
||||
static int fils_derive_key_data(struct fils_sm *fils, const void *rmsk,
|
||||
size_t rmsk_len)
|
||||
{
|
||||
struct fils_sm *fils = user_data;
|
||||
struct ie_tlv_builder builder;
|
||||
uint8_t key[FILS_NONCE_LEN * 2];
|
||||
uint8_t key_data[64 + 48 + 16]; /* largest ICK, KEK, TK */
|
||||
@ -134,11 +133,6 @@ static void fils_erp_complete(enum erp_result result, const void *rmsk,
|
||||
bool sha384;
|
||||
unsigned int ie_len;
|
||||
|
||||
if (result != ERP_RESULT_SUCCESS) {
|
||||
fils_failed(fils, MMPDU_STATUS_CODE_UNSPECIFIED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* IEEE 802.11ai - Section 12.12.2.5.3
|
||||
*/
|
||||
@ -241,6 +235,8 @@ static void fils_erp_complete(enum erp_result result, const void *rmsk,
|
||||
FILS_NONCE_LEN * 2, fils->user_data);
|
||||
|
||||
fils->in_auth = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fils_sm *fils_sm_new(struct handshake_state *hs,
|
||||
@ -259,8 +255,7 @@ struct fils_sm *fils_sm_new(struct handshake_state *hs,
|
||||
fils->hs = hs;
|
||||
fils->in_auth = true;
|
||||
|
||||
fils->erp = erp_new(hs->erp_cache, fils_erp_tx_func,
|
||||
fils_erp_complete, fils);
|
||||
fils->erp = erp_new(hs->erp_cache, fils_erp_tx_func, fils);
|
||||
|
||||
return fils;
|
||||
}
|
||||
@ -294,6 +289,8 @@ void fils_rx_authenticate(struct fils_sm *fils, const uint8_t *frame,
|
||||
const uint8_t *session = NULL;
|
||||
const uint8_t *wrapped = NULL;
|
||||
size_t wrapped_len = 0;
|
||||
void *rmsk;
|
||||
size_t rmsk_len;
|
||||
|
||||
if (!hdr) {
|
||||
l_debug("Auth frame header did not validate");
|
||||
@ -353,9 +350,13 @@ void fils_rx_authenticate(struct fils_sm *fils, const uint8_t *frame,
|
||||
|
||||
memcpy(fils->anonce, anonce, FILS_NONCE_LEN);
|
||||
|
||||
erp_rx_packet(fils->erp, wrapped, wrapped_len);
|
||||
if (erp_rx_packet(fils->erp, wrapped, wrapped_len) < 0)
|
||||
goto auth_failed;
|
||||
|
||||
erp_get_rmsk(fils->erp, &rmsk, &rmsk_len);
|
||||
|
||||
fils_derive_key_data(fils, rmsk, rmsk_len);
|
||||
|
||||
/* EAP should now call the key materials callback, giving us the rMSK */
|
||||
return;
|
||||
|
||||
auth_failed:
|
||||
|
Loading…
Reference in New Issue
Block a user