mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: Felix Walter <felix.walter@cloudandheat.com> Cc: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									e8b18af8c3
								
							
						
					
					
						commit
						ccfdec9089
					
				
					 2 changed files with 67 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -393,7 +393,12 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb)
 | 
			
		|||
#define MACSEC_PORT_SCB (0x0000)
 | 
			
		||||
#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_ENCRYPT false
 | 
			
		||||
#define DEFAULT_ENCODING_SA 0
 | 
			
		||||
| 
						 | 
				
			
			@ -1600,7 +1605,7 @@ static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = {
 | 
			
		|||
	[MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY,
 | 
			
		||||
				   .len = MACSEC_KEYID_LEN, },
 | 
			
		||||
	[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)
 | 
			
		||||
| 
						 | 
				
			
			@ -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 nlattr *secy_nest = nla_nest_start(skb, MACSEC_ATTR_SECY);
 | 
			
		||||
	u64 csid;
 | 
			
		||||
 | 
			
		||||
	if (!secy_nest)
 | 
			
		||||
		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,
 | 
			
		||||
			MACSEC_SECY_ATTR_PAD) ||
 | 
			
		||||
	    nla_put_u64_64bit(skb, MACSEC_SECY_ATTR_CIPHER_SUITE,
 | 
			
		||||
			      MACSEC_DEFAULT_CIPHER_ID,
 | 
			
		||||
			      MACSEC_SECY_ATTR_PAD) ||
 | 
			
		||||
			      csid, MACSEC_SECY_ATTR_PAD) ||
 | 
			
		||||
	    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_PROTECT, secy->protect_frames) ||
 | 
			
		||||
| 
						 | 
				
			
			@ -3015,8 +3031,8 @@ static void macsec_setup(struct net_device *dev)
 | 
			
		|||
	eth_zero_addr(dev->broadcast);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void macsec_changelink_common(struct net_device *dev,
 | 
			
		||||
				     struct nlattr *data[])
 | 
			
		||||
static int macsec_changelink_common(struct net_device *dev,
 | 
			
		||||
				    struct nlattr *data[])
 | 
			
		||||
{
 | 
			
		||||
	struct macsec_secy *secy;
 | 
			
		||||
	struct macsec_tx_sc *tx_sc;
 | 
			
		||||
| 
						 | 
				
			
			@ -3056,6 +3072,22 @@ static void macsec_changelink_common(struct net_device *dev,
 | 
			
		|||
 | 
			
		||||
	if (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[],
 | 
			
		||||
| 
						 | 
				
			
			@ -3071,9 +3103,7 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
 | 
			
		|||
	    data[IFLA_MACSEC_PORT])
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	macsec_changelink_common(dev, data);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return macsec_changelink_common(dev, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void macsec_del_dev(struct macsec_dev *macsec)
 | 
			
		||||
| 
						 | 
				
			
			@ -3270,8 +3300,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 | 
			
		|||
	if (err)
 | 
			
		||||
		goto unlink;
 | 
			
		||||
 | 
			
		||||
	if (data)
 | 
			
		||||
		macsec_changelink_common(dev, data);
 | 
			
		||||
	if (data) {
 | 
			
		||||
		err = macsec_changelink_common(dev, data);
 | 
			
		||||
		if (err)
 | 
			
		||||
			goto del_dev;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = register_macsec_dev(real_dev, dev);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -3320,7 +3353,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[],
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	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:
 | 
			
		||||
		if (icv_len < MACSEC_MIN_ICV_LEN ||
 | 
			
		||||
		    icv_len > MACSEC_STD_ICV_LEN)
 | 
			
		||||
| 
						 | 
				
			
			@ -3390,12 +3424,24 @@ static int macsec_fill_info(struct sk_buff *skb,
 | 
			
		|||
{
 | 
			
		||||
	struct macsec_secy *secy = &macsec_priv(dev)->secy;
 | 
			
		||||
	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,
 | 
			
		||||
			IFLA_MACSEC_PAD) ||
 | 
			
		||||
	    nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) ||
 | 
			
		||||
	    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_ENCRYPT, tx_sc->encrypt) ||
 | 
			
		||||
	    nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) ||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,12 +18,17 @@
 | 
			
		|||
#define MACSEC_GENL_NAME "macsec"
 | 
			
		||||
#define MACSEC_GENL_VERSION 1
 | 
			
		||||
 | 
			
		||||
#define MACSEC_MAX_KEY_LEN 128
 | 
			
		||||
#define MACSEC_MAX_KEY_LEN 256
 | 
			
		||||
 | 
			
		||||
#define MACSEC_KEYID_LEN 16
 | 
			
		||||
 | 
			
		||||
#define MACSEC_DEFAULT_CIPHER_ID   0x0080020001000001ULL
 | 
			
		||||
#define MACSEC_DEFAULT_CIPHER_ALT  0x0080C20001000001ULL
 | 
			
		||||
/* cipher IDs as per IEEE802.1AEbn-2011 */
 | 
			
		||||
#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_MAX_ICV_LEN 32
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue