Blame SOURCES/macsec-0007-mka-Add-driver-op-to-get-macsec-capabilities.patch

6c9f0c
From a25e4efc9e428d968e83398bd8c9c94698ba5851 Mon Sep 17 00:00:00 2001
6c9f0c
Message-Id: <a25e4efc9e428d968e83398bd8c9c94698ba5851.1488376601.git.dcaratti@redhat.com>
6c9f0c
From: Sabrina Dubroca <sd@queasysnail.net>
6c9f0c
Date: Fri, 7 Oct 2016 12:08:12 +0200
6c9f0c
Subject: [PATCH] mka: Add driver op to get macsec capabilities
6c9f0c
6c9f0c
This also implements the macsec_get_capability for the macsec_qca
6c9f0c
driver to maintain the existing behavior.
6c9f0c
6c9f0c
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
6c9f0c
---
6c9f0c
 src/drivers/driver.h            |  8 ++++++++
6c9f0c
 src/drivers/driver_macsec_qca.c | 11 +++++++++++
6c9f0c
 src/pae/ieee802_1x_kay.c        | 18 ++++++++++++++++--
6c9f0c
 src/pae/ieee802_1x_kay.h        |  1 +
6c9f0c
 src/pae/ieee802_1x_secy_ops.c   | 20 ++++++++++++++++++++
6c9f0c
 src/pae/ieee802_1x_secy_ops.h   |  1 +
6c9f0c
 wpa_supplicant/driver_i.h       |  8 ++++++++
6c9f0c
 wpa_supplicant/wpas_kay.c       |  7 +++++++
6c9f0c
 8 files changed, 72 insertions(+), 2 deletions(-)
6c9f0c
6c9f0c
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
6c9f0c
index a57aa53..ea4a41f 100644
6c9f0c
--- a/src/drivers/driver.h
6c9f0c
+++ b/src/drivers/driver.h
6c9f0c
@@ -3298,6 +3298,14 @@ struct wpa_driver_ops {
6c9f0c
 	int (*macsec_deinit)(void *priv);
6c9f0c
 
6c9f0c
 	/**
6c9f0c
+	 * macsec_get_capability - Inform MKA of this driver's capability
6c9f0c
+	 * @priv: Private driver interface data
6c9f0c
+	 * @cap: Driver's capability
6c9f0c
+	 * Returns: 0 on success, -1 on failure
6c9f0c
+	 */
6c9f0c
+	int (*macsec_get_capability)(void *priv, enum macsec_cap *cap);
6c9f0c
+
6c9f0c
+	/**
6c9f0c
 	 * enable_protect_frames - Set protect frames status
6c9f0c
 	 * @priv: Private driver interface data
6c9f0c
 	 * @enabled: TRUE = protect frames enabled
6c9f0c
diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c
6c9f0c
index 385f7c5..041bcf5 100644
6c9f0c
--- a/src/drivers/driver_macsec_qca.c
6c9f0c
+++ b/src/drivers/driver_macsec_qca.c
6c9f0c
@@ -458,6 +458,16 @@ static int macsec_qca_macsec_deinit(void *priv)
6c9f0c
 }
6c9f0c
 
6c9f0c
 
6c9f0c
+static int macsec_qca_get_capability(void *priv, enum macsec_cap *cap)
6c9f0c
+{
6c9f0c
+	wpa_printf(MSG_DEBUG, "%s", __func__);
6c9f0c
+
6c9f0c
+	*cap = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
6c9f0c
+
6c9f0c
+	return 0;
6c9f0c
+}
6c9f0c
+
6c9f0c
+
6c9f0c
 static int macsec_qca_enable_protect_frames(void *priv, Boolean enabled)
6c9f0c
 {
6c9f0c
 	struct macsec_qca_data *drv = priv;
6c9f0c
@@ -889,6 +899,7 @@ const struct wpa_driver_ops wpa_driver_macsec_qca_ops = {
6c9f0c
 
6c9f0c
 	.macsec_init = macsec_qca_macsec_init,
6c9f0c
 	.macsec_deinit = macsec_qca_macsec_deinit,
6c9f0c
+	.macsec_get_capability = macsec_qca_get_capability,
6c9f0c
 	.enable_protect_frames = macsec_qca_enable_protect_frames,
6c9f0c
 	.set_replay_protect = macsec_qca_set_replay_protect,
6c9f0c
 	.set_current_cipher_suite = macsec_qca_set_current_cipher_suite,
6c9f0c
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
6c9f0c
index a8e7efc..52eeeff 100644
6c9f0c
--- a/src/pae/ieee802_1x_kay.c
6c9f0c
+++ b/src/pae/ieee802_1x_kay.c
6c9f0c
@@ -3069,13 +3069,20 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
6c9f0c
 		kay->macsec_replay_window = 0;
6c9f0c
 		kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
6c9f0c
 	} else {
6c9f0c
-		kay->macsec_capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
6c9f0c
+		if (secy_get_capability(kay, &kay->macsec_capable) < 0) {
6c9f0c
+			os_free(kay);
6c9f0c
+			return NULL;
6c9f0c
+		}
6c9f0c
+
6c9f0c
 		kay->macsec_desired = TRUE;
6c9f0c
 		kay->macsec_protect = TRUE;
6c9f0c
 		kay->macsec_validate = Strict;
6c9f0c
 		kay->macsec_replay_protect = FALSE;
6c9f0c
 		kay->macsec_replay_window = 0;
6c9f0c
-		kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
6c9f0c
+		if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF)
6c9f0c
+			kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
6c9f0c
+		else
6c9f0c
+			kay->macsec_confidentiality = MACSEC_CAP_INTEGRITY;
6c9f0c
 	}
6c9f0c
 
6c9f0c
 	wpa_printf(MSG_DEBUG, "KaY: state machine created");
6c9f0c
@@ -3409,6 +3416,7 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
6c9f0c
 				   unsigned int cs_index)
6c9f0c
 {
6c9f0c
 	struct ieee802_1x_mka_participant *participant;
6c9f0c
+	enum macsec_cap secy_cap;
6c9f0c
 
6c9f0c
 	if (!kay)
6c9f0c
 		return -1;
6c9f0c
@@ -3427,6 +3435,12 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
6c9f0c
 	kay->macsec_csindex = cs_index;
6c9f0c
 	kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable;
6c9f0c
 
6c9f0c
+	if (secy_get_capability(kay, &secy_cap) < 0)
6c9f0c
+		return -3;
6c9f0c
+
6c9f0c
+	if (kay->macsec_capable > secy_cap)
6c9f0c
+		kay->macsec_capable = secy_cap;
6c9f0c
+
6c9f0c
 	participant = ieee802_1x_kay_get_principal_participant(kay);
6c9f0c
 	if (participant) {
6c9f0c
 		wpa_printf(MSG_INFO, "KaY: Cipher Suite changed");
6c9f0c
diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
6c9f0c
index 144ee90..bf6fbe5 100644
6c9f0c
--- a/src/pae/ieee802_1x_kay.h
6c9f0c
+++ b/src/pae/ieee802_1x_kay.h
6c9f0c
@@ -138,6 +138,7 @@ struct ieee802_1x_kay_ctx {
6c9f0c
 	/* abstract wpa driver interface */
6c9f0c
 	int (*macsec_init)(void *ctx, struct macsec_init_params *params);
6c9f0c
 	int (*macsec_deinit)(void *ctx);
6c9f0c
+	int (*macsec_get_capability)(void *priv, enum macsec_cap *cap);
6c9f0c
 	int (*enable_protect_frames)(void *ctx, Boolean enabled);
6c9f0c
 	int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window);
6c9f0c
 	int (*set_current_cipher_suite)(void *ctx, u64 cs);
6c9f0c
diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c
6c9f0c
index b8fcf05..32ee816 100644
6c9f0c
--- a/src/pae/ieee802_1x_secy_ops.c
6c9f0c
+++ b/src/pae/ieee802_1x_secy_ops.c
6c9f0c
@@ -113,6 +113,26 @@ int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean enabled)
6c9f0c
 }
6c9f0c
 
6c9f0c
 
6c9f0c
+int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap)
6c9f0c
+{
6c9f0c
+	struct ieee802_1x_kay_ctx *ops;
6c9f0c
+
6c9f0c
+	if (!kay) {
6c9f0c
+		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
6c9f0c
+		return -1;
6c9f0c
+	}
6c9f0c
+
6c9f0c
+	ops = kay->ctx;
6c9f0c
+	if (!ops || !ops->macsec_get_capability) {
6c9f0c
+		wpa_printf(MSG_ERROR,
6c9f0c
+			   "KaY: secy macsec_get_capability operation not supported");
6c9f0c
+		return -1;
6c9f0c
+	}
6c9f0c
+
6c9f0c
+	return ops->macsec_get_capability(ops->ctx, cap);
6c9f0c
+}
6c9f0c
+
6c9f0c
+
6c9f0c
 int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
6c9f0c
 			       struct receive_sa *rxsa)
6c9f0c
 {
6c9f0c
diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h
6c9f0c
index 120ca3c..bfd5737 100644
6c9f0c
--- a/src/pae/ieee802_1x_secy_ops.h
6c9f0c
+++ b/src/pae/ieee802_1x_secy_ops.h
6c9f0c
@@ -28,6 +28,7 @@ int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay,
6c9f0c
 int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean flag);
6c9f0c
 
6c9f0c
 /****** KaY -> SecY *******/
6c9f0c
+int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap);
6c9f0c
 int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
6c9f0c
 			       struct receive_sa *rxsa);
6c9f0c
 int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay,
6c9f0c
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
6c9f0c
index d47395c..5d5dcf0 100644
6c9f0c
--- a/wpa_supplicant/driver_i.h
6c9f0c
+++ b/wpa_supplicant/driver_i.h
6c9f0c
@@ -715,6 +715,14 @@ static inline int wpa_drv_macsec_deinit(struct wpa_supplicant *wpa_s)
6c9f0c
 	return wpa_s->driver->macsec_deinit(wpa_s->drv_priv);
6c9f0c
 }
6c9f0c
 
6c9f0c
+static inline int wpa_drv_macsec_get_capability(struct wpa_supplicant *wpa_s,
6c9f0c
+						enum macsec_cap *cap)
6c9f0c
+{
6c9f0c
+	if (!wpa_s->driver->macsec_get_capability)
6c9f0c
+		return -1;
6c9f0c
+	return wpa_s->driver->macsec_get_capability(wpa_s->drv_priv, cap);
6c9f0c
+}
6c9f0c
+
6c9f0c
 static inline int wpa_drv_enable_protect_frames(struct wpa_supplicant *wpa_s,
6c9f0c
 						Boolean enabled)
6c9f0c
 {
6c9f0c
diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c
6c9f0c
index 4163b61..29b7b56 100644
6c9f0c
--- a/wpa_supplicant/wpas_kay.c
6c9f0c
+++ b/wpa_supplicant/wpas_kay.c
6c9f0c
@@ -38,6 +38,12 @@ static int wpas_macsec_deinit(void *priv)
6c9f0c
 }
6c9f0c
 
6c9f0c
 
6c9f0c
+static int wpas_macsec_get_capability(void *priv, enum macsec_cap *cap)
6c9f0c
+{
6c9f0c
+	return wpa_drv_macsec_get_capability(priv, cap);
6c9f0c
+}
6c9f0c
+
6c9f0c
+
6c9f0c
 static int wpas_enable_protect_frames(void *wpa_s, Boolean enabled)
6c9f0c
 {
6c9f0c
 	return wpa_drv_enable_protect_frames(wpa_s, enabled);
6c9f0c
@@ -191,6 +197,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
6c9f0c
 
6c9f0c
 	kay_ctx->macsec_init = wpas_macsec_init;
6c9f0c
 	kay_ctx->macsec_deinit = wpas_macsec_deinit;
6c9f0c
+	kay_ctx->macsec_get_capability = wpas_macsec_get_capability;
6c9f0c
 	kay_ctx->enable_protect_frames = wpas_enable_protect_frames;
6c9f0c
 	kay_ctx->set_replay_protect = wpas_set_replay_protect;
6c9f0c
 	kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite;
6c9f0c
-- 
6c9f0c
2.7.4
6c9f0c