]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mka: Add driver op to get macsec capabilities
authorSabrina Dubroca <sd@queasysnail.net>
Fri, 7 Oct 2016 10:08:12 +0000 (12:08 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 9 Oct 2016 08:30:48 +0000 (11:30 +0300)
This also implements the macsec_get_capability for the macsec_qca
driver to maintain the existing behavior.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
src/drivers/driver.h
src/drivers/driver_macsec_qca.c
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 a57aa536e2ca7aaec61dc5cb8b34dc1cc5950d61..ea4a41f9ffe003b05a9a33cdd2952d62595028e3 100644 (file)
@@ -3297,6 +3297,14 @@ struct wpa_driver_ops {
 
        int (*macsec_deinit)(void *priv);
 
+       /**
+        * macsec_get_capability - Inform MKA of this driver's capability
+        * @priv: Private driver interface data
+        * @cap: Driver's capability
+        * Returns: 0 on success, -1 on failure
+        */
+       int (*macsec_get_capability)(void *priv, enum macsec_cap *cap);
+
        /**
         * enable_protect_frames - Set protect frames status
         * @priv: Private driver interface data
index 385f7c58243f1cf31d667b6c3340260d89f26f17..041bcf5f9fee38367f2c20f8ca60694edfd3731c 100644 (file)
@@ -458,6 +458,16 @@ static int macsec_qca_macsec_deinit(void *priv)
 }
 
 
+static int macsec_qca_get_capability(void *priv, enum macsec_cap *cap)
+{
+       wpa_printf(MSG_DEBUG, "%s", __func__);
+
+       *cap = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
+
+       return 0;
+}
+
+
 static int macsec_qca_enable_protect_frames(void *priv, Boolean enabled)
 {
        struct macsec_qca_data *drv = priv;
@@ -889,6 +899,7 @@ const struct wpa_driver_ops wpa_driver_macsec_qca_ops = {
 
        .macsec_init = macsec_qca_macsec_init,
        .macsec_deinit = macsec_qca_macsec_deinit,
+       .macsec_get_capability = macsec_qca_get_capability,
        .enable_protect_frames = macsec_qca_enable_protect_frames,
        .set_replay_protect = macsec_qca_set_replay_protect,
        .set_current_cipher_suite = macsec_qca_set_current_cipher_suite,
index a8e7efc9b3bdaa4feccb26cc10529444b6f09895..52eeeff415e77de31d3c38a37bc9795879b3e08d 100644 (file)
@@ -3069,13 +3069,20 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
                kay->macsec_replay_window = 0;
                kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
        } else {
-               kay->macsec_capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
+               if (secy_get_capability(kay, &kay->macsec_capable) < 0) {
+                       os_free(kay);
+                       return NULL;
+               }
+
                kay->macsec_desired = TRUE;
                kay->macsec_protect = TRUE;
                kay->macsec_validate = Strict;
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
-               kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
+               if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF)
+                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
+               else
+                       kay->macsec_confidentiality = MACSEC_CAP_INTEGRITY;
        }
 
        wpa_printf(MSG_DEBUG, "KaY: state machine created");
@@ -3409,6 +3416,7 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
                                   unsigned int cs_index)
 {
        struct ieee802_1x_mka_participant *participant;
+       enum macsec_cap secy_cap;
 
        if (!kay)
                return -1;
@@ -3427,6 +3435,12 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
        kay->macsec_csindex = cs_index;
        kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable;
 
+       if (secy_get_capability(kay, &secy_cap) < 0)
+               return -3;
+
+       if (kay->macsec_capable > secy_cap)
+               kay->macsec_capable = secy_cap;
+
        participant = ieee802_1x_kay_get_principal_participant(kay);
        if (participant) {
                wpa_printf(MSG_INFO, "KaY: Cipher Suite changed");
index 144ee90540db21ed24bff844daade06a22e33077..bf6fbe592c351b9fd34815ec14fba7c6a12afd1e 100644 (file)
@@ -138,6 +138,7 @@ struct ieee802_1x_kay_ctx {
        /* abstract wpa driver interface */
        int (*macsec_init)(void *ctx, struct macsec_init_params *params);
        int (*macsec_deinit)(void *ctx);
+       int (*macsec_get_capability)(void *priv, enum macsec_cap *cap);
        int (*enable_protect_frames)(void *ctx, Boolean enabled);
        int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window);
        int (*set_current_cipher_suite)(void *ctx, u64 cs);
index b8fcf0551657f36d3b0cacc032b07b42aafc21af..32ee816f2ba94086ed953d850761299590009a1e 100644 (file)
@@ -113,6 +113,26 @@ int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean enabled)
 }
 
 
+int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap)
+{
+       struct ieee802_1x_kay_ctx *ops;
+
+       if (!kay) {
+               wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
+               return -1;
+       }
+
+       ops = kay->ctx;
+       if (!ops || !ops->macsec_get_capability) {
+               wpa_printf(MSG_ERROR,
+                          "KaY: secy macsec_get_capability operation not supported");
+               return -1;
+       }
+
+       return ops->macsec_get_capability(ops->ctx, cap);
+}
+
+
 int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
                               struct receive_sa *rxsa)
 {
index 120ca3c7e883fbb9cd34b589feec8f6a2d1b482a..bfd5737725e9064cbfa7aa06f3cbb0ad83dc2ac0 100644 (file)
@@ -28,6 +28,7 @@ int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay,
 int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean flag);
 
 /****** KaY -> SecY *******/
+int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap);
 int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
                               struct receive_sa *rxsa);
 int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay,
index d47395c16545b4b660e6dc0e29556506b2eadd09..5d5dcf0b0558a1134a8350b4af6c40bbe1b23551 100644 (file)
@@ -715,6 +715,14 @@ static inline int wpa_drv_macsec_deinit(struct wpa_supplicant *wpa_s)
        return wpa_s->driver->macsec_deinit(wpa_s->drv_priv);
 }
 
+static inline int wpa_drv_macsec_get_capability(struct wpa_supplicant *wpa_s,
+                                               enum macsec_cap *cap)
+{
+       if (!wpa_s->driver->macsec_get_capability)
+               return -1;
+       return wpa_s->driver->macsec_get_capability(wpa_s->drv_priv, cap);
+}
+
 static inline int wpa_drv_enable_protect_frames(struct wpa_supplicant *wpa_s,
                                                Boolean enabled)
 {
index 4163b6106cbcc4b4ca1cbcf12310d76daff443bd..29b7b562b99dd7ffc8ea3dda0a1aa32a85780ace 100644 (file)
@@ -38,6 +38,12 @@ static int wpas_macsec_deinit(void *priv)
 }
 
 
+static int wpas_macsec_get_capability(void *priv, enum macsec_cap *cap)
+{
+       return wpa_drv_macsec_get_capability(priv, cap);
+}
+
+
 static int wpas_enable_protect_frames(void *wpa_s, Boolean enabled)
 {
        return wpa_drv_enable_protect_frames(wpa_s, enabled);
@@ -191,6 +197,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
 
        kay_ctx->macsec_init = wpas_macsec_init;
        kay_ctx->macsec_deinit = wpas_macsec_deinit;
+       kay_ctx->macsec_get_capability = wpas_macsec_get_capability;
        kay_ctx->enable_protect_frames = wpas_enable_protect_frames;
        kay_ctx->set_replay_protect = wpas_set_replay_protect;
        kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite;