From 023efe53b2de93bbbdca6de734526d468fdec040 Mon Sep 17 00:00:00 2001 From: Mahesh Patil Date: Mon, 1 Feb 2021 11:44:45 -0800 Subject: [PATCH] nvethernet: Enable key program through TZ Enabling macsec key's programming using TZ Bug 3246511 Change-Id: I07d921018a611e4c8dd57aaa27d20a845c9af658 Signed-off-by: Mahesh Patil Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2478492 Reviewed-by: Bhadram Varka Tested-by: Bhadram Varka --- .../net/ethernet/nvidia/nvethernet/macsec.c | 100 ++++++++++++++++-- .../net/ethernet/nvidia/nvethernet/macsec.h | 51 ++++++++- .../net/ethernet/nvidia/nvethernet/sysfs.c | 23 ++-- 3 files changed, 154 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/nvidia/nvethernet/macsec.c b/drivers/net/ethernet/nvidia/nvethernet/macsec.c index 87863149..f5fab32a 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/macsec.c +++ b/drivers/net/ethernet/nvidia/nvethernet/macsec.c @@ -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; +} diff --git a/drivers/net/ethernet/nvidia/nvethernet/macsec.h b/drivers/net/ethernet/nvidia/nvethernet/macsec.h index 742e147e..bee94924 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/macsec.h +++ b/drivers/net/ethernet/nvidia/nvethernet/macsec.h @@ -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); diff --git a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c index 4ac13d73..af2ade41 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c +++ b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c @@ -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,