Commit ccfdec90 authored by Felix Walter's avatar Felix Walter Committed by David S. Miller

macsec: Add support for GCM-AES-256 cipher suite

This adds support for the GCM-AES-256 cipher suite as specified in
IEEE 802.1AEbn-2011. The prepared cipher suite selection mechanism is used,
with GCM-AES-128 being the default cipher suite as defined in the standard.
Signed-off-by: default avatarFelix Walter <felix.walter@cloudandheat.com>
Cc: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e8b18af8
...@@ -393,7 +393,12 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb) ...@@ -393,7 +393,12 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb)
#define MACSEC_PORT_SCB (0x0000) #define MACSEC_PORT_SCB (0x0000)
#define MACSEC_UNDEF_SCI ((__force sci_t)0xffffffffffffffffULL) #define MACSEC_UNDEF_SCI ((__force sci_t)0xffffffffffffffffULL)
#define DEFAULT_SAK_LEN 16 #define MACSEC_GCM_AES_128_SAK_LEN 16
#define MACSEC_GCM_AES_256_SAK_LEN 32
#define MAX_SAK_LEN MACSEC_GCM_AES_256_SAK_LEN
#define DEFAULT_SAK_LEN MACSEC_GCM_AES_128_SAK_LEN
#define DEFAULT_SEND_SCI true #define DEFAULT_SEND_SCI true
#define DEFAULT_ENCRYPT false #define DEFAULT_ENCRYPT false
#define DEFAULT_ENCODING_SA 0 #define DEFAULT_ENCODING_SA 0
...@@ -1600,7 +1605,7 @@ static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = { ...@@ -1600,7 +1605,7 @@ static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = {
[MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY, [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY,
.len = MACSEC_KEYID_LEN, }, .len = MACSEC_KEYID_LEN, },
[MACSEC_SA_ATTR_KEY] = { .type = NLA_BINARY, [MACSEC_SA_ATTR_KEY] = { .type = NLA_BINARY,
.len = MACSEC_MAX_KEY_LEN, }, .len = MAX_SAK_LEN, },
}; };
static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa) static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa)
...@@ -2362,15 +2367,26 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) ...@@ -2362,15 +2367,26 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb)
{ {
struct macsec_tx_sc *tx_sc = &secy->tx_sc; struct macsec_tx_sc *tx_sc = &secy->tx_sc;
struct nlattr *secy_nest = nla_nest_start(skb, MACSEC_ATTR_SECY); struct nlattr *secy_nest = nla_nest_start(skb, MACSEC_ATTR_SECY);
u64 csid;
if (!secy_nest) if (!secy_nest)
return 1; return 1;
switch (secy->key_len) {
case MACSEC_GCM_AES_128_SAK_LEN:
csid = MACSEC_CIPHER_ID_GCM_AES_128;
break;
case MACSEC_GCM_AES_256_SAK_LEN:
csid = MACSEC_CIPHER_ID_GCM_AES_256;
break;
default:
goto cancel;
}
if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci, if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci,
MACSEC_SECY_ATTR_PAD) || MACSEC_SECY_ATTR_PAD) ||
nla_put_u64_64bit(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, nla_put_u64_64bit(skb, MACSEC_SECY_ATTR_CIPHER_SUITE,
MACSEC_DEFAULT_CIPHER_ID, csid, MACSEC_SECY_ATTR_PAD) ||
MACSEC_SECY_ATTR_PAD) ||
nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) ||
nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) ||
nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) ||
...@@ -3015,8 +3031,8 @@ static void macsec_setup(struct net_device *dev) ...@@ -3015,8 +3031,8 @@ static void macsec_setup(struct net_device *dev)
eth_zero_addr(dev->broadcast); eth_zero_addr(dev->broadcast);
} }
static void macsec_changelink_common(struct net_device *dev, static int macsec_changelink_common(struct net_device *dev,
struct nlattr *data[]) struct nlattr *data[])
{ {
struct macsec_secy *secy; struct macsec_secy *secy;
struct macsec_tx_sc *tx_sc; struct macsec_tx_sc *tx_sc;
...@@ -3056,6 +3072,22 @@ static void macsec_changelink_common(struct net_device *dev, ...@@ -3056,6 +3072,22 @@ static void macsec_changelink_common(struct net_device *dev,
if (data[IFLA_MACSEC_VALIDATION]) if (data[IFLA_MACSEC_VALIDATION])
secy->validate_frames = nla_get_u8(data[IFLA_MACSEC_VALIDATION]); secy->validate_frames = nla_get_u8(data[IFLA_MACSEC_VALIDATION]);
if (data[IFLA_MACSEC_CIPHER_SUITE]) {
switch (nla_get_u64(data[IFLA_MACSEC_CIPHER_SUITE])) {
case MACSEC_CIPHER_ID_GCM_AES_128:
case MACSEC_DEFAULT_CIPHER_ALT:
secy->key_len = MACSEC_GCM_AES_128_SAK_LEN;
break;
case MACSEC_CIPHER_ID_GCM_AES_256:
secy->key_len = MACSEC_GCM_AES_256_SAK_LEN;
break;
default:
return -EINVAL;
}
}
return 0;
} }
static int macsec_changelink(struct net_device *dev, struct nlattr *tb[], static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
...@@ -3071,9 +3103,7 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[], ...@@ -3071,9 +3103,7 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
data[IFLA_MACSEC_PORT]) data[IFLA_MACSEC_PORT])
return -EINVAL; return -EINVAL;
macsec_changelink_common(dev, data); return macsec_changelink_common(dev, data);
return 0;
} }
static void macsec_del_dev(struct macsec_dev *macsec) static void macsec_del_dev(struct macsec_dev *macsec)
...@@ -3270,8 +3300,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev, ...@@ -3270,8 +3300,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
if (err) if (err)
goto unlink; goto unlink;
if (data) if (data) {
macsec_changelink_common(dev, data); err = macsec_changelink_common(dev, data);
if (err)
goto del_dev;
}
err = register_macsec_dev(real_dev, dev); err = register_macsec_dev(real_dev, dev);
if (err < 0) if (err < 0)
...@@ -3320,7 +3353,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[], ...@@ -3320,7 +3353,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[],
} }
switch (csid) { switch (csid) {
case MACSEC_DEFAULT_CIPHER_ID: case MACSEC_CIPHER_ID_GCM_AES_128:
case MACSEC_CIPHER_ID_GCM_AES_256:
case MACSEC_DEFAULT_CIPHER_ALT: case MACSEC_DEFAULT_CIPHER_ALT:
if (icv_len < MACSEC_MIN_ICV_LEN || if (icv_len < MACSEC_MIN_ICV_LEN ||
icv_len > MACSEC_STD_ICV_LEN) icv_len > MACSEC_STD_ICV_LEN)
...@@ -3390,12 +3424,24 @@ static int macsec_fill_info(struct sk_buff *skb, ...@@ -3390,12 +3424,24 @@ static int macsec_fill_info(struct sk_buff *skb,
{ {
struct macsec_secy *secy = &macsec_priv(dev)->secy; struct macsec_secy *secy = &macsec_priv(dev)->secy;
struct macsec_tx_sc *tx_sc = &secy->tx_sc; struct macsec_tx_sc *tx_sc = &secy->tx_sc;
u64 csid;
switch (secy->key_len) {
case MACSEC_GCM_AES_128_SAK_LEN:
csid = MACSEC_CIPHER_ID_GCM_AES_128;
break;
case MACSEC_GCM_AES_256_SAK_LEN:
csid = MACSEC_CIPHER_ID_GCM_AES_256;
break;
default:
goto nla_put_failure;
}
if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci, if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci,
IFLA_MACSEC_PAD) || IFLA_MACSEC_PAD) ||
nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) ||
nla_put_u64_64bit(skb, IFLA_MACSEC_CIPHER_SUITE, nla_put_u64_64bit(skb, IFLA_MACSEC_CIPHER_SUITE,
MACSEC_DEFAULT_CIPHER_ID, IFLA_MACSEC_PAD) || csid, IFLA_MACSEC_PAD) ||
nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) ||
nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) ||
nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) ||
......
...@@ -18,12 +18,17 @@ ...@@ -18,12 +18,17 @@
#define MACSEC_GENL_NAME "macsec" #define MACSEC_GENL_NAME "macsec"
#define MACSEC_GENL_VERSION 1 #define MACSEC_GENL_VERSION 1
#define MACSEC_MAX_KEY_LEN 128 #define MACSEC_MAX_KEY_LEN 256
#define MACSEC_KEYID_LEN 16 #define MACSEC_KEYID_LEN 16
#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL /* cipher IDs as per IEEE802.1AEbn-2011 */
#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL #define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL
#define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL
#define MACSEC_DEFAULT_CIPHER_ID MACSEC_CIPHER_ID_GCM_AES_128
/* deprecated cipher ID for GCM-AES-128 */
#define MACSEC_DEFAULT_CIPHER_ALT 0x0080020001000001ULL
#define MACSEC_MIN_ICV_LEN 8 #define MACSEC_MIN_ICV_LEN 8
#define MACSEC_MAX_ICV_LEN 32 #define MACSEC_MAX_ICV_LEN 32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment