nvethernet: Enable key program through TZ

Enabling macsec key's programming using TZ

Bug 3246511

Change-Id: I07d921018a611e4c8dd57aaa27d20a845c9af658
Signed-off-by: Mahesh Patil <maheshp@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2478492
Reviewed-by: Bhadram Varka <vbhadram@nvidia.com>
Tested-by: Bhadram Varka <vbhadram@nvidia.com>
This commit is contained in:
Mahesh Patil
2021-02-01 11:44:45 -08:00
committed by Revanth Kumar Uppala
parent ca2466ab09
commit 023efe53b2
3 changed files with 154 additions and 20 deletions

View File

@@ -196,7 +196,8 @@ int macsec_close(struct macsec_priv_data *macsec_pdata)
return ret;
}
int macsec_open(struct macsec_priv_data *macsec_pdata)
int macsec_open(struct macsec_priv_data *macsec_pdata,
void *const genl_info)
{
struct ether_priv_data *pdata = macsec_pdata->ether_pdata;
struct device *dev = pdata->dev;
@@ -238,7 +239,7 @@ int macsec_open(struct macsec_priv_data *macsec_pdata)
#endif
/* 3. invoke OSI HW initialization, initialize standard BYP entries */
ret = osi_macsec_init(pdata->osi_core);
ret = osi_macsec_init(pdata->osi_core, genl_info);
if (ret < 0) {
dev_err(dev, "osi_macsec_init failed, %d\n", ret);
goto err_osi_init;
@@ -520,7 +521,7 @@ static int macsec_dis_rx_sa(struct sk_buff *skb, struct genl_info *info)
#ifndef TEST
ret = osi_macsec_config(pdata->osi_core, &rx_sa, OSI_DISABLE,
CTLR_SEL_RX);
CTLR_SEL_RX, info);
if (ret < 0) {
pr_err("%s: failed to disable Rx SA", __func__);
}
@@ -574,7 +575,7 @@ static int macsec_en_rx_sa(struct sk_buff *skb, struct genl_info *info)
#ifndef TEST
ret = osi_macsec_config(pdata->osi_core, &rx_sa, OSI_ENABLE,
CTLR_SEL_RX);
CTLR_SEL_RX, info);
if (ret < 0) {
pr_err("%s: failed to enable Rx SA", __func__);
}
@@ -628,7 +629,7 @@ static int macsec_dis_tx_sa(struct sk_buff *skb, struct genl_info *info)
#ifndef TEST
ret = osi_macsec_config(pdata->osi_core, &tx_sa, OSI_DISABLE,
CTLR_SEL_TX);
CTLR_SEL_TX, info);
if (ret < 0) {
pr_err("%s: failed to disable Tx SA", __func__);
}
@@ -682,7 +683,7 @@ static int macsec_en_tx_sa(struct sk_buff *skb, struct genl_info *info)
#ifndef TEST
ret = osi_macsec_config(pdata->osi_core, &tx_sa, OSI_ENABLE,
CTLR_SEL_TX);
CTLR_SEL_TX, info);
if (ret < 0) {
pr_err("%s: failed to enable Tx SA", __func__);
}
@@ -740,7 +741,7 @@ static int macsec_init(struct sk_buff *skb, struct genl_info *info)
goto exit;
}
ret = macsec_open(macsec_pdata);
ret = macsec_open(macsec_pdata, info);
//TODO - check why needs -EOPNOTSUPP, why not pass ret val
if (ret < 0) {
ret = -EOPNOTSUPP;
@@ -919,6 +920,7 @@ int macsec_probe(struct ether_priv_data *pdata)
}
macsec_pdata->ether_pdata = pdata;
pdata->macsec_pdata = macsec_pdata;
osi_core->osd_ops.macsec_tz_kt_config = macsec_tz_kt_config;
/* 3. Get OSI MACsec ops */
if (osi_init_macsec_ops(osi_core) != 0) {
@@ -955,3 +957,87 @@ exit:
PRINT_EXIT();
return ret;
}
int macsec_tz_kt_config(void *priv, unsigned char cmd,
void *const config, void *const genl_info)
{
struct genl_info *info = (struct genl_info *)genl_info;
struct osi_macsec_kt_config *kt_config = NULL;
struct sk_buff *msg;
struct nlattr *nest;
void *msg_head;
int ret = 0;
if (genl_info == OSI_NULL) {
pr_err("Can not config key through TZ, genl_info NULL\n");
/* return success, as KT LUT can be programmed manually
* through sysfs
*/
return ret;
}
/* remap osi tz cmd to netlink cmd */
if (cmd == MACSEC_CMD_TZ_CONFIG) {
cmd = NV_MACSEC_CMD_TZ_CONFIG;
} else if (cmd == MACSEC_CMD_TZ_KT_RESET) {
cmd = NV_MACSEC_CMD_TZ_KT_RESET;
} else {
pr_err("%s: Wrong TZ cmd %d\n", __func__, cmd);
ret = -1;
goto fail;
}
msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (msg == NULL) {
pr_err("Unable to alloc genl reply\n");
ret = -ENOMEM;
goto fail;
}
msg_head = genlmsg_put_reply(msg, info, &nv_macsec_fam, 0, cmd);
if (msg_head == NULL) {
pr_err("unable to get replyhead\n");
ret = -EINVAL;
goto failure;
}
if (cmd == NV_MACSEC_CMD_TZ_CONFIG && config != NULL) {
kt_config = (struct osi_macsec_kt_config *)config;
/* pr_err("%s: ctrl: %hu rw: %hu idx: %hu flags: %#x\n"
* __func__,
* kt_config->table_config.ctlr_sel,
* kt_config->table_config.rw,
* kt_config->table_config.index,
* kt_config->flags);
*/
nest = nla_nest_start(msg, NV_MACSEC_ATTR_TZ_CONFIG);
if (!nest) {
ret = EINVAL;
goto failure;
}
nla_put_u8(msg, NV_MACSEC_TZ_ATTR_CTRL,
kt_config->table_config.ctlr_sel);
nla_put_u8(msg, NV_MACSEC_TZ_ATTR_RW,
kt_config->table_config.rw);
nla_put_u8(msg, NV_MACSEC_TZ_ATTR_INDEX,
kt_config->table_config.index);
nla_put(msg, NV_MACSEC_TZ_ATTR_KEY, KEY_LEN_256,
kt_config->entry.sak);
nla_put(msg, NV_MACSEC_TZ_ATTR_HKEY, KEY_LEN_128,
kt_config->entry.h);
nla_put_u32(msg, NV_MACSEC_TZ_ATTR_FLAG, kt_config->flags);
nla_nest_end(msg, nest);
}
genlmsg_end(msg, msg_head);
ret = genlmsg_reply(msg, info);
if (ret != 0) {
pr_err("Unable to send reply\n");
}
return ret;
failure:
nlmsg_free(msg);
fail:
return ret;
}

View File

@@ -35,10 +35,11 @@
*/
#define MACSEC_IRQ_NAME_SZ 32
//TODO - include name of driver interface as well
/* TODO - include name of driver interface as well */
#define NV_MACSEC_GENL_NAME "nv_macsec"
#define NV_MACSEC_GENL_VERSION 1
/* keep the same enum definition in nv macsec supplicant driver */
enum nv_macsec_sa_attrs {
NV_MACSEC_SA_ATTR_UNSPEC,
NV_MACSEC_SA_ATTR_SCI,
@@ -50,6 +51,19 @@ enum nv_macsec_sa_attrs {
NV_MACSEC_SA_ATTR_MAX = __NV_MACSEC_SA_ATTR_END - 1,
};
enum nv_macsec_tz_attrs {
NV_MACSEC_TZ_ATTR_UNSPEC,
NV_MACSEC_TZ_ATTR_CTRL,
NV_MACSEC_TZ_ATTR_RW,
NV_MACSEC_TZ_ATTR_INDEX,
NV_MACSEC_TZ_ATTR_KEY,
NV_MACSEC_TZ_ATTR_HKEY,
NV_MACSEC_TZ_ATTR_FLAG,
__NV_MACSEC_TZ_ATTR_END,
NUM_NV_MACSEC_TZ_ATTR = __NV_MACSEC_TZ_ATTR_END,
NV_MACSEC_TZ_ATTR_MAX = __NV_MACSEC_TZ_ATTR_END - 1,
};
enum nv_macsec_attrs {
NV_MACSEC_ATTR_UNSPEC,
NV_MACSEC_ATTR_IFNAME,
@@ -60,6 +74,7 @@ enum nv_macsec_attrs {
NV_MACSEC_ATTR_CIPHER_SUITE,
NV_MACSEC_ATTR_CTRL_PORT_EN,
NV_MACSEC_ATTR_SA_CONFIG, /* Nested SA config */
NV_MACSEC_ATTR_TZ_CONFIG, /* Nested TZ config */
__NV_MACSEC_ATTR_END,
NUM_NV_MACSEC_ATTR = __NV_MACSEC_ATTR_END,
NV_MACSEC_ATTR_MAX = __NV_MACSEC_ATTR_END - 1,
@@ -74,12 +89,24 @@ static const struct nla_policy nv_macsec_sa_genl_policy[NUM_NV_MACSEC_SA_ATTR] =
.len = KEY_LEN_128,},
};
static const struct nla_policy nv_macsec_tz_genl_policy[NUM_NV_MACSEC_TZ_ATTR] = {
[NV_MACSEC_TZ_ATTR_CTRL] = { .type = NLA_U8 }, /* controller Tx or Rx */
[NV_MACSEC_TZ_ATTR_RW] = { .type = NLA_U8 },
[NV_MACSEC_TZ_ATTR_INDEX] = { .type = NLA_U8 },
[NV_MACSEC_TZ_ATTR_KEY] = { .type = NLA_BINARY,
.len = KEY_LEN_256 },
[NV_MACSEC_TZ_ATTR_HKEY] = { .type = NLA_BINARY,
.len = KEY_LEN_128 },
[NV_MACSEC_TZ_ATTR_FLAG] = { .type = NLA_U32 },
};
static const struct nla_policy nv_macsec_genl_policy[NUM_NV_MACSEC_ATTR] = {
[NV_MACSEC_ATTR_IFNAME] = { .type = NLA_STRING },
[NV_MACSEC_ATTR_TXSC_PORT] = { .type = NLA_U16 },
[NV_MACSEC_ATTR_REPLAY_PROT_EN] = { .type = NLA_U32 },
[NV_MACSEC_ATTR_REPLAY_WINDOW] = { .type = NLA_U32 },
[NV_MACSEC_ATTR_SA_CONFIG] = { .type = NLA_NESTED },
[NV_MACSEC_ATTR_TZ_CONFIG] = { .type = NLA_NESTED },
};
enum nv_macsec_nl_commands {
@@ -93,6 +120,8 @@ enum nv_macsec_nl_commands {
NV_MACSEC_CMD_DIS_TX_SA,
NV_MACSEC_CMD_EN_RX_SA,
NV_MACSEC_CMD_DIS_RX_SA,
NV_MACSEC_CMD_TZ_CONFIG,
NV_MACSEC_CMD_TZ_KT_RESET,
NV_MACSEC_CMD_DEINIT,
};
@@ -128,8 +157,26 @@ struct macsec_priv_data {
int macsec_probe(struct ether_priv_data *pdata);
void macsec_remove(struct ether_priv_data *pdata);
int macsec_open(struct macsec_priv_data *macsec_pdata);
int macsec_open(struct macsec_priv_data *macsec_pdata,
void *const genl_info);
int macsec_close(struct macsec_priv_data *macsec_pdata);
/**
* @brief macsec_tz_kt_config - Program macsec key table entry.
*
* @param[in] priv: OSD private data structure.
* @param[in] cmd: macsec TZ config cmd
* @param[in] kt_config: Pointer to osi_macsec_kt_config structure
* @param[in] genl_info: Pointer to netlink msg structure
*
* @retval 0 on success
* @retval negative value on failure.
*/
int macsec_tz_kt_config(void *priv,
unsigned char cmd,
void *const kt_config,
void *const genl_info);
#ifdef TEST
int macsec_genl_register(void);
void macsec_genl_unregister(void);

View File

@@ -143,7 +143,8 @@ static ssize_t macsec_enable_show(struct device *dev,
"None");
}
extern int macsec_open(struct macsec_priv_data *macsec_pdata);
extern int macsec_open(struct macsec_priv_data *macsec_pdata,
void *const genl_info);
extern int macsec_close(struct macsec_priv_data *macsec_pdata);
/**
@@ -177,10 +178,10 @@ static ssize_t macsec_enable_store(struct device *dev,
if (strncmp(buf, "0", 1) == OSI_NONE) {
ret = macsec_close(macsec_pdata);
} else if (strncmp(buf, "txrx", 4) == OSI_NONE) {
ret = macsec_open(macsec_pdata);
ret = macsec_open(macsec_pdata, OSI_NULL);
} else if (strncmp(buf, "tx", 2) == OSI_NONE) {
if (macsec_pdata->enabled == OSI_NONE) {
ret = macsec_open(macsec_pdata);
ret = macsec_open(macsec_pdata, OSI_NONE);
}
enable |= (OSI_MACSEC_TX_EN);
ret = osi_macsec_en(osi_core, enable);
@@ -191,7 +192,7 @@ static ssize_t macsec_enable_store(struct device *dev,
macsec_pdata->enabled = OSI_MACSEC_TX_EN;
} else if (strncmp(buf, "rx", 2) == OSI_NONE) {
if (macsec_pdata->enabled == OSI_NONE) {
ret = macsec_open(macsec_pdata);
ret = macsec_open(macsec_pdata, OSI_NONE);
}
enable |= (OSI_MACSEC_RX_EN);
ret = osi_macsec_en(osi_core, enable);
@@ -1121,6 +1122,7 @@ static DEVICE_ATTR(macsec_sci_lut, (S_IRUGO | S_IWUSR),
macsec_sci_lut_show,
macsec_sci_lut_store);
#ifdef MACSEC_KEY_PROGRAM
static void dump_kt(char **buf_p, unsigned short ctlr_sel,
struct osi_core_priv_data *osi_core)
{
@@ -1133,7 +1135,7 @@ static void dump_kt(char **buf_p, unsigned short ctlr_sel,
kt_config.table_config.ctlr_sel = ctlr_sel;
kt_config.table_config.rw = LUT_READ;
kt_config.table_config.index = i;
if (osi_macsec_kt_config(osi_core, &kt_config) < 0) {
if (osi_macsec_kt_config(osi_core, &kt_config, OSI_NULL) < 0) {
pr_err("%s: Failed to read KT\n", __func__);
*buf_p = buf;
return;
@@ -1234,11 +1236,9 @@ static ssize_t macsec_kt_store(struct device *dev,
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
struct ether_priv_data *pdata = netdev_priv(ndev);
struct osi_core_priv_data *osi_core = pdata->osi_core;
#if 1 /* HKEY GENERATION */
struct crypto_cipher *tfm;
unsigned char hkey[KEY_LEN_128];
unsigned char zeros[KEY_LEN_128] = {0};
#endif
struct osi_macsec_kt_config kt_config = {0};
int temp[KEY_LEN_256] = {0};
unsigned char sak[KEY_LEN_256] = {0};
@@ -1286,8 +1286,7 @@ static ssize_t macsec_kt_store(struct device *dev,
kt_config.table_config.rw = LUT_WRITE;
kt_config.table_config.index = index;
#if 1 /* HKEY GENERATION */
//TODO - move to OSD and use ether_linux.h/macsec.c for this
/* HKEY GENERATION */
tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
if (crypto_cipher_setkey(tfm, sak, KEY_LEN_128)) {
pr_err("%s: Failed to set cipher key for H generation",
@@ -1296,7 +1295,6 @@ static ssize_t macsec_kt_store(struct device *dev,
}
crypto_cipher_encrypt_one(tfm, hkey, zeros);
crypto_free_cipher(tfm);
#endif /* HKEY GENERATION */
for (i = 0; i < KEY_LEN_128; i++) {
sak[i] = (unsigned char)temp[i];
@@ -1325,7 +1323,7 @@ static ssize_t macsec_kt_store(struct device *dev,
kt_config.flags |= LUT_FLAGS_ENTRY_VALID;
}
ret = osi_macsec_kt_config(osi_core, &kt_config);
ret = osi_macsec_kt_config(osi_core, &kt_config, OSI_NULL);
if (ret < 0) {
pr_err("%s: Failed to set SAK", __func__);
goto exit;
@@ -1358,6 +1356,7 @@ static DEVICE_ATTR(macsec_tx_kt, (S_IRUGO | S_IWUSR),
static DEVICE_ATTR(macsec_rx_kt, (S_IRUGO | S_IWUSR),
macsec_rx_kt_show,
NULL);
#endif /* MACSEC_KEY_PROGRAM */
static void dump_sc_state_lut(char **buf_p, unsigned short ctlr_sel,
struct osi_core_priv_data *osi_core)
@@ -2068,9 +2067,11 @@ static struct attribute *ether_sysfs_attrs[] = {
&dev_attr_macsec_irq_stats.attr,
&dev_attr_macsec_byp_lut.attr,
&dev_attr_macsec_sci_lut.attr,
#ifdef MACSEC_KEY_PROGRAM
&dev_attr_macsec_kt.attr,
&dev_attr_macsec_tx_kt.attr,
&dev_attr_macsec_rx_kt.attr,
#endif /* MACSEC_KEY_PROGRAM */
&dev_attr_macsec_sc_state_lut.attr,
&dev_attr_macsec_sa_state_lut.attr,
&dev_attr_macsec_sc_param_lut.attr,