#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>
#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"
}
+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;
}
-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;
}
}
-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);
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;
}
}
-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)
{
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);
}
-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);
}
-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;
}
}
-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);
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);
}
-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);
}
-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;
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;
}
.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,