]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/drivers/driver_macsec_qca.c
mka: Add driver op to get macsec capabilities
[thirdparty/hostap.git] / src / drivers / driver_macsec_qca.c
index 3eae2f89d20e80ddfd9da1ef5a08634988e9c54e..041bcf5f9fee38367f2c20f8ca60694edfd3731c 100644 (file)
@@ -11,6 +11,7 @@
 #include "includes.h"
 #include <sys/ioctl.h>
 #include <net/if.h>
+#include <inttypes.h>
 #ifdef __linux__
 #include <netpacket/packet.h>
 #include <net/if_arp.h>
@@ -28,6 +29,7 @@
 #include "utils/eloop.h"
 #include "common/defs.h"
 #include "common/ieee802_1x_defs.h"
+#include "pae/ieee802_1x_kay.h"
 #include "driver.h"
 
 #include "nss_macsec_secy.h"
@@ -456,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;
@@ -485,15 +497,12 @@ static int macsec_qca_set_replay_protect(void *priv, Boolean enabled,
 }
 
 
-static int macsec_qca_set_current_cipher_suite(void *priv, const u8 *cs,
-                                              size_t cs_len)
+static int macsec_qca_set_current_cipher_suite(void *priv, u64 cs)
 {
-       u8 default_cs_id[] = CS_ID_GCM_AES_128;
-
-       if (cs_len != CS_ID_LEN ||
-           os_memcmp(cs, default_cs_id, cs_len) != 0) {
-               wpa_hexdump(MSG_ERROR, "macsec: NOT supported CipherSuite",
-                           cs, cs_len);
+       if (cs != CS_ID_GCM_AES_128) {
+               wpa_printf(MSG_ERROR,
+                          "%s: NOT supported CipherSuite: %016" PRIx64,
+                          __func__, cs);
                return -1;
        }
 
@@ -517,16 +526,16 @@ static int macsec_qca_enable_controlled_port(void *priv, Boolean enabled)
 }
 
 
-static int macsec_qca_get_receive_lowest_pn(void *priv, u32 channel, u8 an,
-                                           u32 *lowest_pn)
+static int macsec_qca_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
        u32 next_pn = 0;
        bool enabled = FALSE;
        u32 win;
+       u32 channel = sa->sc->channel;
 
-       ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, an,
+       ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, sa->an,
                                                 &next_pn);
        ret += nss_macsec_secy_rx_sc_replay_protect_get(drv->secy_id, channel,
                                                        &enabled);
@@ -534,40 +543,42 @@ static int macsec_qca_get_receive_lowest_pn(void *priv, u32 channel, u8 an,
                                                            channel, &win);
 
        if (enabled)
-               *lowest_pn = (next_pn > win) ? (next_pn - win) : 1;
+               sa->lowest_pn = (next_pn > win) ? (next_pn - win) : 1;
        else
-               *lowest_pn = next_pn;
+               sa->lowest_pn = next_pn;
 
-       wpa_printf(MSG_DEBUG, "%s: lpn=0x%x", __func__, *lowest_pn);
+       wpa_printf(MSG_DEBUG, "%s: lpn=0x%x", __func__, sa->lowest_pn);
 
        return ret;
 }
 
 
-static int macsec_qca_get_transmit_next_pn(void *priv, u32 channel, u8 an,
-                                          u32 *next_pn)
+static int macsec_qca_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
+       u32 channel = sa->sc->channel;
 
-       ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, an,
-                                                next_pn);
+       ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, sa->an,
+                                                &sa->next_pn);
 
-       wpa_printf(MSG_DEBUG, "%s: npn=0x%x", __func__, *next_pn);
+       wpa_printf(MSG_DEBUG, "%s: npn=0x%x", __func__, sa->next_pn);
 
        return ret;
 }
 
 
-int macsec_qca_set_transmit_next_pn(void *priv, u32 channel, u8 an, u32 next_pn)
+int macsec_qca_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
+       u32 channel = sa->sc->channel;
 
-       ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, an,
-                                                next_pn);
 
-       wpa_printf(MSG_INFO, "%s: npn=0x%x", __func__, next_pn);
+       ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an,
+                                                sa->next_pn);
+
+       wpa_printf(MSG_INFO, "%s: npn=0x%x", __func__, sa->next_pn);
 
        return ret;
 }
@@ -600,8 +611,7 @@ static int macsec_qca_get_available_receive_sc(void *priv, u32 *channel)
 }
 
 
-static int macsec_qca_create_receive_sc(void *priv, u32 channel,
-                                       const u8 *sci_addr, u16 sci_port,
+static int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc,
                                        unsigned int conf_offset,
                                        int validation)
 {
@@ -610,6 +620,9 @@ static int macsec_qca_create_receive_sc(void *priv, u32 channel,
        fal_rx_prc_lut_t entry;
        fal_rx_sc_validate_frame_e vf;
        enum validate_frames validate_frames = validation;
+       u32 channel = sc->channel;
+       const u8 *sci_addr = sc->sci.addr;
+       u16 sci_port = be_to_host16(sc->sci.port);
 
        wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
 
@@ -648,11 +661,12 @@ static int macsec_qca_create_receive_sc(void *priv, u32 channel,
 }
 
 
-static int macsec_qca_delete_receive_sc(void *priv, u32 channel)
+static int macsec_qca_delete_receive_sc(void *priv, struct receive_sc *sc)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
        fal_rx_prc_lut_t entry;
+       u32 channel = sc->channel;
 
        wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
 
@@ -666,49 +680,57 @@ static int macsec_qca_delete_receive_sc(void *priv, u32 channel)
 }
 
 
-static int macsec_qca_create_receive_sa(void *priv, u32 channel, u8 an,
-                                       u32 lowest_pn, const u8 *sak)
+static int macsec_qca_create_receive_sa(void *priv, struct receive_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
        fal_rx_sak_t rx_sak;
        int i = 0;
+       u32 channel = sa->sc->channel;
 
        wpa_printf(MSG_DEBUG, "%s, channel=%d, an=%d, lpn=0x%x",
-                  __func__, channel, an, lowest_pn);
+                  __func__, channel, sa->an, sa->lowest_pn);
 
        os_memset(&rx_sak, 0, sizeof(rx_sak));
        for (i = 0; i < 16; i++)
-               rx_sak.sak[i] = sak[15 - i];
+               rx_sak.sak[i] = sa->pkey->key[15 - i];
 
-       ret += nss_macsec_secy_rx_sa_create(drv->secy_id, channel, an);
-       ret += nss_macsec_secy_rx_sak_set(drv->secy_id, channel, an, &rx_sak);
+       ret += nss_macsec_secy_rx_sa_create(drv->secy_id, channel, sa->an);
+       ret += nss_macsec_secy_rx_sak_set(drv->secy_id, channel, sa->an,
+                                         &rx_sak);
 
        return ret;
 }
 
 
-static int macsec_qca_enable_receive_sa(void *priv, u32 channel, u8 an)
+static int macsec_qca_enable_receive_sa(void *priv, struct receive_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
+       u32 channel = sa->sc->channel;
+
 
-       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an);
+       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
+                  sa->an);
 
-       ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, an, TRUE);
+       ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an,
+                                           TRUE);
 
        return ret;
 }
 
 
-static int macsec_qca_disable_receive_sa(void *priv, u32 channel, u8 an)
+static int macsec_qca_disable_receive_sa(void *priv, struct receive_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
+       u32 channel = sa->sc->channel;
 
-       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an);
+       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
+                  sa->an);
 
-       ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, an, FALSE);
+       ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an,
+                                           FALSE);
 
        return ret;
 }
@@ -741,14 +763,14 @@ static int macsec_qca_get_available_transmit_sc(void *priv, u32 *channel)
 }
 
 
-static int macsec_qca_create_transmit_sc(void *priv, u32 channel,
-                                        const u8 *sci_addr, u16 sci_port,
+static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc,
                                         unsigned int conf_offset)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
        fal_tx_class_lut_t entry;
        u8 psci[ETH_ALEN + 2];
+       u32 channel = sc->channel;
 
        wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
 
@@ -759,9 +781,9 @@ static int macsec_qca_create_transmit_sc(void *priv, u32 channel,
        entry.action = FAL_TX_CLASS_ACTION_FORWARD;
        entry.channel = channel;
 
-       os_memcpy(psci, sci_addr, ETH_ALEN);
-       psci[6] = (sci_port >> 8) & 0xf;
-       psci[7] = sci_port & 0xf;
+       os_memcpy(psci, sc->sci.addr, ETH_ALEN);
+       psci[6] = (sc->sci.port >> 8) & 0xf;
+       psci[7] = sc->sci.port & 0xf;
 
        ret += nss_macsec_secy_tx_class_lut_set(drv->secy_id, channel, &entry);
        ret += nss_macsec_secy_tx_sc_create(drv->secy_id, channel, psci, 8);
@@ -775,11 +797,12 @@ static int macsec_qca_create_transmit_sc(void *priv, u32 channel,
 }
 
 
-static int macsec_qca_delete_transmit_sc(void *priv, u32 channel)
+static int macsec_qca_delete_transmit_sc(void *priv, struct transmit_sc *sc)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
        fal_tx_class_lut_t entry;
+       u32 channel = sc->channel;
 
        wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
 
@@ -793,19 +816,18 @@ static int macsec_qca_delete_transmit_sc(void *priv, u32 channel)
 }
 
 
-static int macsec_qca_create_transmit_sa(void *priv, u32 channel, u8 an,
-                                        u32 next_pn, Boolean confidentiality,
-                                        const u8 *sak)
+static int macsec_qca_create_transmit_sa(void *priv, struct transmit_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
        u8 tci = 0;
        fal_tx_sak_t tx_sak;
        int i;
+       u32 channel = sa->sc->channel;
 
        wpa_printf(MSG_DEBUG,
                   "%s: channel=%d, an=%d, next_pn=0x%x, confidentiality=%d",
-                  __func__, channel, an, next_pn, confidentiality);
+                  __func__, channel, sa->an, sa->next_pn, sa->confidentiality);
 
        if (drv->always_include_sci)
                tci |= TCI_SC;
@@ -814,45 +836,53 @@ static int macsec_qca_create_transmit_sa(void *priv, u32 channel, u8 an,
        else if (drv->use_scb)
                tci |= TCI_SCB;
 
-       if (confidentiality)
+       if (sa->confidentiality)
                tci |= TCI_E | TCI_C;
 
        os_memset(&tx_sak, 0, sizeof(tx_sak));
        for (i = 0; i < 16; i++)
-               tx_sak.sak[i] = sak[15 - i];
+               tx_sak.sak[i] = sa->pkey->key[15 - i];
 
-       ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, an,
-                                                next_pn);
-       ret += nss_macsec_secy_tx_sak_set(drv->secy_id, channel, an, &tx_sak);
+       ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an,
+                                                sa->next_pn);
+       ret += nss_macsec_secy_tx_sak_set(drv->secy_id, channel, sa->an,
+                                         &tx_sak);
        ret += nss_macsec_secy_tx_sc_tci_7_2_set(drv->secy_id, channel,
                                                 (tci >> 2));
-       ret += nss_macsec_secy_tx_sc_an_set(drv->secy_id, channel, an);
+       ret += nss_macsec_secy_tx_sc_an_set(drv->secy_id, channel, sa->an);
 
        return ret;
 }
 
 
-static int macsec_qca_enable_transmit_sa(void *priv, u32 channel, u8 an)
+static int macsec_qca_enable_transmit_sa(void *priv, struct transmit_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
+       u32 channel = sa->sc->channel;
+
 
-       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an);
+       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
+                  sa->an);
 
-       ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, an, TRUE);
+       ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an,
+                                           TRUE);
 
        return ret;
 }
 
 
-static int macsec_qca_disable_transmit_sa(void *priv, u32 channel, u8 an)
+static int macsec_qca_disable_transmit_sa(void *priv, struct transmit_sa *sa)
 {
        struct macsec_qca_data *drv = priv;
        int ret = 0;
+       u32 channel = sa->sc->channel;
 
-       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an);
+       wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
+                  sa->an);
 
-       ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, an, FALSE);
+       ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an,
+                                           FALSE);
 
        return ret;
 }
@@ -869,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,