]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mka: Add support for removing SAs
authorSabrina Dubroca <sd@queasysnail.net>
Fri, 21 Oct 2016 12:45:28 +0000 (14:45 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 29 Oct 2016 08:35:38 +0000 (11:35 +0300)
So that the core can notify drivers that need to perform some operations
when an SA is deleted.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
src/drivers/driver.h
src/pae/ieee802_1x_kay.c
src/pae/ieee802_1x_kay.h
src/pae/ieee802_1x_secy_ops.c
src/pae/ieee802_1x_secy_ops.h
wpa_supplicant/driver_i.h
wpa_supplicant/wpas_kay.c

index 54ae6b7485a54ed666a1476ce2d9823e60df450b..9a6db909da5def64ae6ee6275b2bbd4fafab09e7 100644 (file)
@@ -3418,6 +3418,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()
@@ -3460,6 +3468,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()
index 38a829376d636db62074f44c8ffd59258bf0dfc4..e312d045949391ec462f1f25f999ee496b67b960 100644 (file)
@@ -491,6 +491,15 @@ 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 -
  **/
@@ -502,10 +511,9 @@ ieee802_1x_kay_deinit_receive_sc(
 
        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);
-       }
+                             list)
+               ieee802_1x_delete_receive_sa(participant->kay, psa);
+
        dl_list_del(&psc->list);
        os_free(psc);
 }
@@ -2270,6 +2278,16 @@ 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 +2362,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 +2504,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 +2583,32 @@ 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 +2643,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 +2654,10 @@ 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 +2691,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);
                }
        }
 
index e2ba180ad95c2749eeca60b4a55bfcca749d30d5..5233cb216adad1d46fd098cb21e3f8f7896282ce 100644 (file)
@@ -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);
 };
index b57c670f4d0b5d61b2dd9a158899a59a4ccbd3fd..b1a9d223fd31d5caff6651eb55021d670ff8e238 100644 (file)
@@ -256,6 +256,26 @@ 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 +383,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)
 {
index 59f0baadec6e96a5a8776968cb11cf6dcc1ebe2b..477120b1f4a0a77e58b938dd49d911cee01ce66b 100644 (file)
@@ -38,6 +38,7 @@ int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay,
 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);
@@ -48,6 +49,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,
index 244e3865dd603100987697c275d2a28e71603b44..c9bb20d90eb1bc43c9c6e7423f74db08640dc2f3 100644 (file)
@@ -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)
 {
index 64364f729fc06010274807aa6c63e9a485290caa..e03233003f5129426bc45d9216d29cb05660c88c 100644 (file)
@@ -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;