So that the core can notify drivers that need to perform some operations when an SA is deleted. Signed-off-by: Sabrina Dubroca <sd@xxxxxxxxxxxxxxx> --- src/drivers/driver.h | 16 +++++++++ src/pae/ieee802_1x_kay.c | 75 +++++++++++++++++++++++++++++++------------ src/pae/ieee802_1x_kay.h | 2 ++ src/pae/ieee802_1x_secy_ops.c | 42 ++++++++++++++++++++++++ src/pae/ieee802_1x_secy_ops.h | 3 ++ wpa_supplicant/driver_i.h | 16 +++++++++ wpa_supplicant/wpas_kay.c | 14 ++++++++ 7 files changed, 148 insertions(+), 20 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 03fc7253126d..bad4b4a19aaa 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3395,6 +3395,14 @@ struct wpa_driver_ops { int (*create_receive_sa)(void *priv, struct receive_sa *sa); /** + * delete_receive_sa - delete secure association for receive + * @priv: private driver interface data from init() + * @sa: secure association + * Returns: 0 on success, -1 on failure + */ + int (*delete_receive_sa)(void *priv, struct receive_sa *sa); + + /** * enable_receive_sa - enable the SA for receive * @priv: private driver interface data from init() * @sa: secure association @@ -3437,6 +3445,14 @@ struct wpa_driver_ops { int (*create_transmit_sa)(void *priv, struct transmit_sa *sa); /** + * delete_transmit_sa - delete secure association for transmit + * @priv: private driver interface data from init() + * @sa: secure association + * Returns: 0 on success, -1 on failure + */ + int (*delete_transmit_sa)(void *priv, struct transmit_sa *sa); + + /** * enable_transmit_sa - enable SA for transmit * @priv: private driver interface data from init() * @sa: secure association diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c index 38a829376d63..d09f26664413 100644 --- a/src/pae/ieee802_1x_kay.c +++ b/src/pae/ieee802_1x_kay.c @@ -491,6 +491,13 @@ ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci) } +static void ieee802_1x_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *sa) +{ + secy_disable_receive_sa(kay, sa); + secy_delete_receive_sa(kay, sa); + ieee802_1x_kay_deinit_receive_sa(sa); +} + /** * ieee802_1x_kay_deinit_receive_sc - **/ @@ -501,11 +508,9 @@ ieee802_1x_kay_deinit_receive_sc( struct receive_sa *psa, *pre_sa; wpa_printf(MSG_DEBUG, "KaY: Delete receive SC"); - dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, - list) { - secy_disable_receive_sa(participant->kay, psa); - ieee802_1x_kay_deinit_receive_sa(psa); - } + dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, list) + ieee802_1x_delete_receive_sa(participant->kay, psa); + dl_list_del(&psc->list); os_free(psc); } @@ -2270,6 +2275,14 @@ ieee802_1x_participant_send_mkpdu( static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa); + +static void ieee802_1x_delete_transmit_sa(struct ieee802_1x_kay *kay, struct transmit_sa *sa) +{ + secy_disable_transmit_sa(kay, sa); + secy_delete_transmit_sa(kay, sa); + ieee802_1x_kay_deinit_transmit_sa(sa); +} + /** * ieee802_1x_participant_timer - */ @@ -2344,8 +2357,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) dl_list_for_each_safe(txsa, pre_txsa, &participant->txsc->sa_list, struct transmit_sa, list) { - secy_disable_transmit_sa(kay, txsa); - ieee802_1x_kay_deinit_transmit_sa(txsa); + ieee802_1x_delete_transmit_sa(kay, txsa); } ieee802_1x_cp_connect_authenticated(kay->cp); @@ -2487,11 +2499,8 @@ ieee802_1x_kay_deinit_transmit_sc( struct transmit_sa *psa, *tmp; wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC"); - dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, - list) { - secy_disable_transmit_sa(participant->kay, psa); - ieee802_1x_kay_deinit_transmit_sa(psa); - } + dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, list) + ieee802_1x_delete_transmit_sa(participant->kay, psa); os_free(psc); } @@ -2569,6 +2578,30 @@ int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay, } +static struct transmit_sa *lookup_txsa_by_an(struct transmit_sc *txsc, u8 an) +{ + struct transmit_sa *txsa; + + dl_list_for_each(txsa, &txsc->sa_list, struct transmit_sa, list) { + if (txsa->an == an) + return txsa; + } + + return NULL; +} + +static struct receive_sa *lookup_rxsa_by_an(struct receive_sc *rxsc, u8 an) +{ + struct receive_sa *rxsa; + + dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) { + if (rxsa->an == an) + return rxsa; + } + + return NULL; +} + /** * ieee802_1x_kay_create_sas - */ @@ -2603,6 +2636,9 @@ int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, } dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { + while ((rxsa = lookup_rxsa_by_an(rxsc, latest_sak->an)) != NULL) + ieee802_1x_delete_receive_sa(kay, rxsa); + rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1, latest_sak); if (!rxsa) @@ -2611,6 +2647,9 @@ int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, secy_create_receive_sa(kay, rxsa); } + while ((txsa = lookup_txsa_by_an(principal->txsc, latest_sak->an)) != NULL) + ieee802_1x_delete_transmit_sa(kay, txsa); + txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an, 1, latest_sak); if (!txsa) @@ -2644,20 +2683,16 @@ int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, /* remove the transmit sa */ dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list, struct transmit_sa, list) { - if (is_ki_equal(&txsa->pkey->key_identifier, ki)) { - secy_disable_transmit_sa(kay, txsa); - ieee802_1x_kay_deinit_transmit_sa(txsa); - } + if (is_ki_equal(&txsa->pkey->key_identifier, ki)) + ieee802_1x_delete_transmit_sa(kay, txsa); } /* remove the receive sa */ dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list, struct receive_sa, list) { - if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { - secy_disable_receive_sa(kay, rxsa); - ieee802_1x_kay_deinit_receive_sa(rxsa); - } + if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) + ieee802_1x_delete_receive_sa(kay, rxsa); } } diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h index e2ba180ad95c..5233cb216ada 100644 --- a/src/pae/ieee802_1x_kay.h +++ b/src/pae/ieee802_1x_kay.h @@ -153,12 +153,14 @@ struct ieee802_1x_kay_ctx { enum confidentiality_offset co); int (*delete_receive_sc)(void *ctx, struct receive_sc *sc); int (*create_receive_sa)(void *ctx, struct receive_sa *sa); + int (*delete_receive_sa)(void *ctx, struct receive_sa *sa); int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc, enum confidentiality_offset co); int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc); int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa); + int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa); int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); }; diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c index b57c670f4d0b..3cfbb4accea7 100644 --- a/src/pae/ieee802_1x_secy_ops.c +++ b/src/pae/ieee802_1x_secy_ops.c @@ -256,6 +256,27 @@ int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) } +int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) +{ + struct ieee802_1x_kay_ctx *ops; + + if (!kay || !rxsa) { + wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); + return -1; + } + + ops = kay->ctx; + if (!ops || !ops->delete_receive_sa) { + wpa_printf(MSG_ERROR, + "KaY: secy delete_receive_sa operation not supported"); + return -1; + } + + return ops->delete_receive_sa(ops->ctx, rxsa); +} + + + int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) { struct ieee802_1x_kay_ctx *ops; @@ -363,6 +384,27 @@ int secy_create_transmit_sa(struct ieee802_1x_kay *kay, } +int secy_delete_transmit_sa(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa) +{ + struct ieee802_1x_kay_ctx *ops; + + if (!kay || !txsa) { + wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); + return -1; + } + + ops = kay->ctx; + if (!ops || !ops->delete_transmit_sa) { + wpa_printf(MSG_ERROR, + "KaY: secy delete_transmit_sa operation not supported"); + return -1; + } + + return ops->delete_transmit_sa(ops->ctx, txsa); +} + + int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, struct transmit_sa *txsa) { diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h index bfd5737725e9..25d9d178f2b2 100644 --- a/src/pae/ieee802_1x_secy_ops.h +++ b/src/pae/ieee802_1x_secy_ops.h @@ -39,6 +39,7 @@ int secy_get_available_receive_sc(struct ieee802_1x_kay *kay, u32 *channel); int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); +int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); @@ -50,6 +51,8 @@ int secy_delete_transmit_sc(struct ieee802_1x_kay *kay, struct transmit_sc *txsc); int secy_create_transmit_sa(struct ieee802_1x_kay *kay, struct transmit_sa *txsa); +int secy_delete_transmit_sa(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa); int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, struct transmit_sa *txsa); int secy_disable_transmit_sa(struct ieee802_1x_kay *kay, diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 9486589b68f0..5cbab8839435 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -806,6 +806,14 @@ static inline int wpa_drv_create_receive_sa(struct wpa_supplicant *wpa_s, return wpa_s->driver->create_receive_sa(wpa_s->drv_priv, sa); } +static inline int wpa_drv_delete_receive_sa(struct wpa_supplicant *wpa_s, + struct receive_sa *sa) +{ + if (!wpa_s->driver->delete_receive_sa) + return -1; + return wpa_s->driver->delete_receive_sa(wpa_s->drv_priv, sa); +} + static inline int wpa_drv_enable_receive_sa(struct wpa_supplicant *wpa_s, struct receive_sa *sa) { @@ -848,6 +856,14 @@ static inline int wpa_drv_create_transmit_sa(struct wpa_supplicant *wpa_s, return wpa_s->driver->create_transmit_sa(wpa_s->drv_priv, sa); } +static inline int wpa_drv_delete_transmit_sa(struct wpa_supplicant *wpa_s, + struct transmit_sa *sa) +{ + if (!wpa_s->driver->delete_transmit_sa) + return -1; + return wpa_s->driver->delete_transmit_sa(wpa_s->drv_priv, sa); +} + static inline int wpa_drv_enable_transmit_sa(struct wpa_supplicant *wpa_s, struct transmit_sa *sa) { diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c index 64364f729fc0..e03233003f51 100644 --- a/wpa_supplicant/wpas_kay.c +++ b/wpa_supplicant/wpas_kay.c @@ -120,6 +120,12 @@ static int wpas_create_receive_sa(void *wpa_s, struct receive_sa *sa) } +static int wpas_delete_receive_sa(void *wpa_s, struct receive_sa *sa) +{ + return wpa_drv_delete_receive_sa(wpa_s, sa); +} + + static int wpas_enable_receive_sa(void *wpa_s, struct receive_sa *sa) { return wpa_drv_enable_receive_sa(wpa_s, sa); @@ -152,6 +158,12 @@ static int wpas_create_transmit_sa(void *wpa_s, struct transmit_sa *sa) } +static int wpas_delete_transmit_sa(void *wpa_s, struct transmit_sa *sa) +{ + return wpa_drv_delete_transmit_sa(wpa_s, sa); +} + + static int wpas_enable_transmit_sa(void *wpa_s, struct transmit_sa *sa) { return wpa_drv_enable_transmit_sa(wpa_s, sa); @@ -196,11 +208,13 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) kay_ctx->create_receive_sc = wpas_create_receive_sc; kay_ctx->delete_receive_sc = wpas_delete_receive_sc; kay_ctx->create_receive_sa = wpas_create_receive_sa; + kay_ctx->delete_receive_sa = wpas_delete_receive_sa; kay_ctx->enable_receive_sa = wpas_enable_receive_sa; kay_ctx->disable_receive_sa = wpas_disable_receive_sa; kay_ctx->create_transmit_sc = wpas_create_transmit_sc; kay_ctx->delete_transmit_sc = wpas_delete_transmit_sc; kay_ctx->create_transmit_sa = wpas_create_transmit_sa; + kay_ctx->delete_transmit_sa = wpas_delete_transmit_sa; kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa; kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; -- 2.10.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap