Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

macsec: Netlink support of XPN cipher suites (IEEE 802.1AEbw)

Netlink support of extended packet number cipher suites,
allows adding and updating XPN macsec interfaces.

Added support in:
* Creating interfaces with GCM-AES-XPN-128 and GCM-AES-XPN-256 suites.
* Setting and getting 64bit packet numbers with of SAs.
* Setting (only on SA creation) and getting ssci of SAs.
* Setting salt when installing a SAK.

Added 2 cipher suite identifiers according to 802.1AE-2018 table 14-1:
* MACSEC_CIPHER_ID_GCM_AES_XPN_128
* MACSEC_CIPHER_ID_GCM_AES_XPN_256

In addition, added 2 new netlink attribute types:
* MACSEC_SA_ATTR_SSCI
* MACSEC_SA_ATTR_SALT

Depends on: macsec: Support XPN frame handling - IEEE 802.1AEbw.

Signed-off-by: Era Mayflower <mayflowerera@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Era Mayflower and committed by
David S. Miller
48ef50fa a21ecf0e

+157 -15
+148 -13
drivers/net/macsec.c
··· 240 240 #define MACSEC_PORT_ES (htons(0x0001)) 241 241 #define MACSEC_PORT_SCB (0x0000) 242 242 #define MACSEC_UNDEF_SCI ((__force sci_t)0xffffffffffffffffULL) 243 + #define MACSEC_UNDEF_SSCI ((__force ssci_t)0xffffffff) 243 244 244 245 #define MACSEC_GCM_AES_128_SAK_LEN 16 245 246 #define MACSEC_GCM_AES_256_SAK_LEN 32 246 247 247 248 #define DEFAULT_SAK_LEN MACSEC_GCM_AES_128_SAK_LEN 249 + #define DEFAULT_XPN false 248 250 #define DEFAULT_SEND_SCI true 249 251 #define DEFAULT_ENCRYPT false 250 252 #define DEFAULT_ENCODING_SA 0 ··· 1313 1311 return PTR_ERR(rx_sa->key.tfm); 1314 1312 } 1315 1313 1314 + rx_sa->ssci = MACSEC_UNDEF_SSCI; 1316 1315 rx_sa->active = false; 1317 1316 rx_sa->next_pn = 1; 1318 1317 refcount_set(&rx_sa->refcnt, 1); ··· 1412 1409 return PTR_ERR(tx_sa->key.tfm); 1413 1410 } 1414 1411 1412 + tx_sa->ssci = MACSEC_UNDEF_SSCI; 1415 1413 tx_sa->active = false; 1416 1414 refcount_set(&tx_sa->refcnt, 1); 1417 1415 spin_lock_init(&tx_sa->lock); ··· 1454 1450 int padattr) 1455 1451 { 1456 1452 return nla_put_u64_64bit(skb, attrtype, (__force u64)value, padattr); 1453 + } 1454 + 1455 + static ssci_t nla_get_ssci(const struct nlattr *nla) 1456 + { 1457 + return (__force ssci_t)nla_get_u32(nla); 1458 + } 1459 + 1460 + static int nla_put_ssci(struct sk_buff *skb, int attrtype, ssci_t value) 1461 + { 1462 + return nla_put_u32(skb, attrtype, (__force u64)value); 1457 1463 } 1458 1464 1459 1465 static struct macsec_tx_sa *get_txsa_from_nl(struct net *net, ··· 1581 1567 static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = { 1582 1568 [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 }, 1583 1569 [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 }, 1584 - [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 }, 1570 + [MACSEC_SA_ATTR_PN] = { .type = NLA_MIN_LEN, .len = 4 }, 1585 1571 [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY, 1586 1572 .len = MACSEC_KEYID_LEN, }, 1587 1573 [MACSEC_SA_ATTR_KEY] = { .type = NLA_BINARY, 1588 1574 .len = MACSEC_MAX_KEY_LEN, }, 1575 + [MACSEC_SA_ATTR_SSCI] = { .type = NLA_U32 }, 1576 + [MACSEC_SA_ATTR_SALT] = { .type = NLA_BINARY, 1577 + .len = MACSEC_SALT_LEN, }, 1589 1578 }; 1590 1579 1591 1580 static const struct nla_policy macsec_genl_offload_policy[NUM_MACSEC_OFFLOAD_ATTR] = { ··· 1661 1644 if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN) 1662 1645 return false; 1663 1646 1664 - if (attrs[MACSEC_SA_ATTR_PN] && nla_get_u32(attrs[MACSEC_SA_ATTR_PN]) == 0) 1647 + if (attrs[MACSEC_SA_ATTR_PN] && 1648 + *(u64 *)nla_data(attrs[MACSEC_SA_ATTR_PN]) == 0) 1665 1649 return false; 1666 1650 1667 1651 if (attrs[MACSEC_SA_ATTR_ACTIVE]) { ··· 1684 1666 struct macsec_rx_sc *rx_sc; 1685 1667 struct macsec_rx_sa *rx_sa; 1686 1668 unsigned char assoc_num; 1669 + int pn_len; 1687 1670 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1]; 1688 1671 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1]; 1689 1672 int err; ··· 1717 1698 return -EINVAL; 1718 1699 } 1719 1700 1701 + pn_len = secy->xpn ? MACSEC_XPN_PN_LEN : MACSEC_DEFAULT_PN_LEN; 1702 + if (nla_len(tb_sa[MACSEC_SA_ATTR_PN]) != pn_len) { 1703 + pr_notice("macsec: nl: add_rxsa: bad pn length: %d != %d\n", 1704 + nla_len(tb_sa[MACSEC_SA_ATTR_PN]), pn_len); 1705 + rtnl_unlock(); 1706 + return -EINVAL; 1707 + } 1708 + 1709 + if (secy->xpn) { 1710 + if (!tb_sa[MACSEC_SA_ATTR_SSCI] || !tb_sa[MACSEC_SA_ATTR_SALT]) { 1711 + rtnl_unlock(); 1712 + return -EINVAL; 1713 + } 1714 + 1715 + if (nla_len(tb_sa[MACSEC_SA_ATTR_SALT]) != MACSEC_SALT_LEN) { 1716 + pr_notice("macsec: nl: add_rxsa: bad salt length: %d != %d\n", 1717 + nla_len(tb_sa[MACSEC_SA_ATTR_SALT]), 1718 + MACSEC_SA_ATTR_SALT); 1719 + rtnl_unlock(); 1720 + return -EINVAL; 1721 + } 1722 + } 1723 + 1720 1724 rx_sa = rtnl_dereference(rx_sc->sa[assoc_num]); 1721 1725 if (rx_sa) { 1722 1726 rtnl_unlock(); ··· 1762 1720 1763 1721 if (tb_sa[MACSEC_SA_ATTR_PN]) { 1764 1722 spin_lock_bh(&rx_sa->lock); 1765 - rx_sa->next_pn_halves.lower = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]); 1723 + rx_sa->next_pn = nla_get_u64(tb_sa[MACSEC_SA_ATTR_PN]); 1766 1724 spin_unlock_bh(&rx_sa->lock); 1767 1725 } 1768 1726 ··· 1790 1748 err = macsec_offload(ops->mdo_add_rxsa, &ctx); 1791 1749 if (err) 1792 1750 goto cleanup; 1751 + } 1752 + 1753 + if (secy->xpn) { 1754 + rx_sa->ssci = nla_get_ssci(tb_sa[MACSEC_SA_ATTR_SSCI]); 1755 + nla_memcpy(rx_sa->key.salt.bytes, tb_sa[MACSEC_SA_ATTR_SALT], 1756 + MACSEC_SALT_LEN); 1793 1757 } 1794 1758 1795 1759 nla_memcpy(rx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEYID], MACSEC_KEYID_LEN); ··· 1922 1874 struct macsec_tx_sc *tx_sc; 1923 1875 struct macsec_tx_sa *tx_sa; 1924 1876 unsigned char assoc_num; 1877 + int pn_len; 1925 1878 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1]; 1926 1879 bool was_operational; 1927 1880 int err; ··· 1955 1906 return -EINVAL; 1956 1907 } 1957 1908 1909 + pn_len = secy->xpn ? MACSEC_XPN_PN_LEN : MACSEC_DEFAULT_PN_LEN; 1910 + if (nla_len(tb_sa[MACSEC_SA_ATTR_PN]) != pn_len) { 1911 + pr_notice("macsec: nl: add_txsa: bad pn length: %d != %d\n", 1912 + nla_len(tb_sa[MACSEC_SA_ATTR_PN]), pn_len); 1913 + rtnl_unlock(); 1914 + return -EINVAL; 1915 + } 1916 + 1917 + if (secy->xpn) { 1918 + if (!tb_sa[MACSEC_SA_ATTR_SSCI] || !tb_sa[MACSEC_SA_ATTR_SALT]) { 1919 + rtnl_unlock(); 1920 + return -EINVAL; 1921 + } 1922 + 1923 + if (nla_len(tb_sa[MACSEC_SA_ATTR_SALT]) != MACSEC_SALT_LEN) { 1924 + pr_notice("macsec: nl: add_txsa: bad salt length: %d != %d\n", 1925 + nla_len(tb_sa[MACSEC_SA_ATTR_SALT]), 1926 + MACSEC_SA_ATTR_SALT); 1927 + rtnl_unlock(); 1928 + return -EINVAL; 1929 + } 1930 + } 1931 + 1958 1932 tx_sa = rtnl_dereference(tx_sc->sa[assoc_num]); 1959 1933 if (tx_sa) { 1960 1934 rtnl_unlock(); ··· 1999 1927 } 2000 1928 2001 1929 spin_lock_bh(&tx_sa->lock); 2002 - tx_sa->next_pn_halves.lower = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]); 1930 + tx_sa->next_pn = nla_get_u64(tb_sa[MACSEC_SA_ATTR_PN]); 2003 1931 spin_unlock_bh(&tx_sa->lock); 2004 1932 2005 1933 if (tb_sa[MACSEC_SA_ATTR_ACTIVE]) ··· 2028 1956 err = macsec_offload(ops->mdo_add_txsa, &ctx); 2029 1957 if (err) 2030 1958 goto cleanup; 1959 + } 1960 + 1961 + if (secy->xpn) { 1962 + tx_sa->ssci = nla_get_ssci(tb_sa[MACSEC_SA_ATTR_SSCI]); 1963 + nla_memcpy(tx_sa->key.salt.bytes, tb_sa[MACSEC_SA_ATTR_SALT], 1964 + MACSEC_SALT_LEN); 2031 1965 } 2032 1966 2033 1967 nla_memcpy(tx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEYID], MACSEC_KEYID_LEN); ··· 2242 2164 { 2243 2165 if (!attrs[MACSEC_SA_ATTR_AN] || 2244 2166 attrs[MACSEC_SA_ATTR_KEY] || 2245 - attrs[MACSEC_SA_ATTR_KEYID]) 2167 + attrs[MACSEC_SA_ATTR_KEYID] || 2168 + attrs[MACSEC_SA_ATTR_SSCI] || 2169 + attrs[MACSEC_SA_ATTR_SALT]) 2246 2170 return false; 2247 2171 2248 2172 if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN) ··· 2294 2214 } 2295 2215 2296 2216 if (tb_sa[MACSEC_SA_ATTR_PN]) { 2217 + int pn_len; 2218 + 2219 + pn_len = secy->xpn ? MACSEC_XPN_PN_LEN : MACSEC_DEFAULT_PN_LEN; 2220 + if (nla_len(tb_sa[MACSEC_SA_ATTR_PN]) != pn_len) { 2221 + pr_notice("macsec: nl: upd_txsa: bad pn length: %d != %d\n", 2222 + nla_len(tb_sa[MACSEC_SA_ATTR_PN]), pn_len); 2223 + rtnl_unlock(); 2224 + return -EINVAL; 2225 + } 2226 + 2297 2227 spin_lock_bh(&tx_sa->lock); 2298 2228 prev_pn = tx_sa->next_pn_halves; 2299 - tx_sa->next_pn_halves.lower = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]); 2229 + tx_sa->next_pn = nla_get_u64(tb_sa[MACSEC_SA_ATTR_PN]); 2300 2230 spin_unlock_bh(&tx_sa->lock); 2301 2231 } 2302 2232 ··· 2390 2300 } 2391 2301 2392 2302 if (tb_sa[MACSEC_SA_ATTR_PN]) { 2303 + int pn_len; 2304 + 2305 + pn_len = secy->xpn ? MACSEC_XPN_PN_LEN : MACSEC_DEFAULT_PN_LEN; 2306 + if (nla_len(tb_sa[MACSEC_SA_ATTR_PN]) != pn_len) { 2307 + pr_notice("macsec: nl: upd_rxsa: bad pn length: %d != %d\n", 2308 + nla_len(tb_sa[MACSEC_SA_ATTR_PN]), pn_len); 2309 + rtnl_unlock(); 2310 + return -EINVAL; 2311 + } 2312 + 2393 2313 spin_lock_bh(&rx_sa->lock); 2394 2314 prev_pn = rx_sa->next_pn_halves; 2395 - rx_sa->next_pn_halves.lower = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]); 2315 + rx_sa->next_pn = nla_get_u64(tb_sa[MACSEC_SA_ATTR_PN]); 2396 2316 spin_unlock_bh(&rx_sa->lock); 2397 2317 } 2398 2318 ··· 2849 2749 2850 2750 switch (secy->key_len) { 2851 2751 case MACSEC_GCM_AES_128_SAK_LEN: 2852 - csid = MACSEC_DEFAULT_CIPHER_ID; 2752 + csid = secy->xpn ? MACSEC_CIPHER_ID_GCM_AES_XPN_128 : MACSEC_DEFAULT_CIPHER_ID; 2853 2753 break; 2854 2754 case MACSEC_GCM_AES_256_SAK_LEN: 2855 - csid = MACSEC_CIPHER_ID_GCM_AES_256; 2755 + csid = secy->xpn ? MACSEC_CIPHER_ID_GCM_AES_XPN_256 : MACSEC_CIPHER_ID_GCM_AES_256; 2856 2756 break; 2857 2757 default: 2858 2758 goto cancel; ··· 2943 2843 for (i = 0, j = 1; i < MACSEC_NUM_AN; i++) { 2944 2844 struct macsec_tx_sa *tx_sa = rtnl_dereference(tx_sc->sa[i]); 2945 2845 struct nlattr *txsa_nest; 2846 + u64 pn; 2847 + int pn_len; 2946 2848 2947 2849 if (!tx_sa) 2948 2850 continue; ··· 2955 2853 goto nla_put_failure; 2956 2854 } 2957 2855 2856 + if (secy->xpn) { 2857 + pn = tx_sa->next_pn; 2858 + pn_len = MACSEC_XPN_PN_LEN; 2859 + } else { 2860 + pn = tx_sa->next_pn_halves.lower; 2861 + pn_len = MACSEC_DEFAULT_PN_LEN; 2862 + } 2863 + 2958 2864 if (nla_put_u8(skb, MACSEC_SA_ATTR_AN, i) || 2959 - nla_put_u32(skb, MACSEC_SA_ATTR_PN, tx_sa->next_pn_halves.lower) || 2865 + nla_put(skb, MACSEC_SA_ATTR_PN, pn_len, &pn) || 2960 2866 nla_put(skb, MACSEC_SA_ATTR_KEYID, MACSEC_KEYID_LEN, tx_sa->key.id) || 2867 + (secy->xpn && nla_put_ssci(skb, MACSEC_SA_ATTR_SSCI, tx_sa->ssci)) || 2961 2868 nla_put_u8(skb, MACSEC_SA_ATTR_ACTIVE, tx_sa->active)) { 2962 2869 nla_nest_cancel(skb, txsa_nest); 2963 2870 nla_nest_cancel(skb, txsa_list); ··· 3039 2928 for (i = 0, k = 1; i < MACSEC_NUM_AN; i++) { 3040 2929 struct macsec_rx_sa *rx_sa = rtnl_dereference(rx_sc->sa[i]); 3041 2930 struct nlattr *rxsa_nest; 2931 + u64 pn; 2932 + int pn_len; 3042 2933 3043 2934 if (!rx_sa) 3044 2935 continue; ··· 3070 2957 } 3071 2958 nla_nest_end(skb, attr); 3072 2959 2960 + if (secy->xpn) { 2961 + pn = rx_sa->next_pn; 2962 + pn_len = MACSEC_XPN_PN_LEN; 2963 + } else { 2964 + pn = rx_sa->next_pn_halves.lower; 2965 + pn_len = MACSEC_DEFAULT_PN_LEN; 2966 + } 2967 + 3073 2968 if (nla_put_u8(skb, MACSEC_SA_ATTR_AN, i) || 3074 - nla_put_u32(skb, MACSEC_SA_ATTR_PN, rx_sa->next_pn_halves.lower) || 2969 + nla_put(skb, MACSEC_SA_ATTR_PN, pn_len, &pn) || 3075 2970 nla_put(skb, MACSEC_SA_ATTR_KEYID, MACSEC_KEYID_LEN, rx_sa->key.id) || 2971 + (secy->xpn && nla_put_ssci(skb, MACSEC_SA_ATTR_SSCI, rx_sa->ssci)) || 3076 2972 nla_put_u8(skb, MACSEC_SA_ATTR_ACTIVE, rx_sa->active)) { 3077 2973 nla_nest_cancel(skb, rxsa_nest); 3078 2974 nla_nest_cancel(skb, rxsc_nest); ··· 3625 3503 case MACSEC_CIPHER_ID_GCM_AES_128: 3626 3504 case MACSEC_DEFAULT_CIPHER_ID: 3627 3505 secy->key_len = MACSEC_GCM_AES_128_SAK_LEN; 3506 + secy->xpn = false; 3628 3507 break; 3629 3508 case MACSEC_CIPHER_ID_GCM_AES_256: 3630 3509 secy->key_len = MACSEC_GCM_AES_256_SAK_LEN; 3510 + secy->xpn = false; 3511 + break; 3512 + case MACSEC_CIPHER_ID_GCM_AES_XPN_128: 3513 + secy->key_len = MACSEC_GCM_AES_128_SAK_LEN; 3514 + secy->xpn = true; 3515 + break; 3516 + case MACSEC_CIPHER_ID_GCM_AES_XPN_256: 3517 + secy->key_len = MACSEC_GCM_AES_256_SAK_LEN; 3518 + secy->xpn = true; 3631 3519 break; 3632 3520 default: 3633 3521 return -EINVAL; ··· 3827 3695 secy->validate_frames = MACSEC_VALIDATE_DEFAULT; 3828 3696 secy->protect_frames = true; 3829 3697 secy->replay_protect = false; 3698 + secy->xpn = DEFAULT_XPN; 3830 3699 3831 3700 secy->sci = sci; 3832 3701 secy->tx_sc.active = true; ··· 3957 3824 switch (csid) { 3958 3825 case MACSEC_CIPHER_ID_GCM_AES_128: 3959 3826 case MACSEC_CIPHER_ID_GCM_AES_256: 3827 + case MACSEC_CIPHER_ID_GCM_AES_XPN_128: 3828 + case MACSEC_CIPHER_ID_GCM_AES_XPN_256: 3960 3829 case MACSEC_DEFAULT_CIPHER_ID: 3961 3830 if (icv_len < MACSEC_MIN_ICV_LEN || 3962 3831 icv_len > MACSEC_STD_ICV_LEN) ··· 4032 3897 4033 3898 switch (secy->key_len) { 4034 3899 case MACSEC_GCM_AES_128_SAK_LEN: 4035 - csid = MACSEC_DEFAULT_CIPHER_ID; 3900 + csid = secy->xpn ? MACSEC_CIPHER_ID_GCM_AES_XPN_128 : MACSEC_DEFAULT_CIPHER_ID; 4036 3901 break; 4037 3902 case MACSEC_GCM_AES_256_SAK_LEN: 4038 - csid = MACSEC_CIPHER_ID_GCM_AES_256; 3903 + csid = secy->xpn ? MACSEC_CIPHER_ID_GCM_AES_XPN_256 : MACSEC_CIPHER_ID_GCM_AES_256; 4039 3904 break; 4040 3905 default: 4041 3906 goto nla_put_failure;
+3
include/net/macsec.h
··· 11 11 #include <uapi/linux/if_link.h> 12 12 #include <uapi/linux/if_macsec.h> 13 13 14 + #define MACSEC_DEFAULT_PN_LEN 4 15 + #define MACSEC_XPN_PN_LEN 8 16 + 14 17 #define MACSEC_SALT_LEN 12 15 18 #define MACSEC_NUM_AN 4 /* 2 bits for the association number */ 16 19
+6 -2
include/uapi/linux/if_macsec.h
··· 22 22 23 23 #define MACSEC_KEYID_LEN 16 24 24 25 - /* cipher IDs as per IEEE802.1AEbn-2011 */ 25 + /* cipher IDs as per IEEE802.1AE-2018 (Table 14-1) */ 26 26 #define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL 27 27 #define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL 28 + #define MACSEC_CIPHER_ID_GCM_AES_XPN_128 0x0080C20001000003ULL 29 + #define MACSEC_CIPHER_ID_GCM_AES_XPN_256 0x0080C20001000004ULL 28 30 29 31 /* deprecated cipher ID for GCM-AES-128 */ 30 32 #define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL ··· 90 88 MACSEC_SA_ATTR_UNSPEC, 91 89 MACSEC_SA_ATTR_AN, /* config/dump, u8 0..3 */ 92 90 MACSEC_SA_ATTR_ACTIVE, /* config/dump, u8 0..1 */ 93 - MACSEC_SA_ATTR_PN, /* config/dump, u32 */ 91 + MACSEC_SA_ATTR_PN, /* config/dump, u32/u64 (u64 if XPN) */ 94 92 MACSEC_SA_ATTR_KEY, /* config, data */ 95 93 MACSEC_SA_ATTR_KEYID, /* config/dump, 128-bit */ 96 94 MACSEC_SA_ATTR_STATS, /* dump, nested, macsec_sa_stats_attr */ 97 95 MACSEC_SA_ATTR_PAD, 96 + MACSEC_SA_ATTR_SSCI, /* config/dump, u32 - XPN only */ 97 + MACSEC_SA_ATTR_SALT, /* config, 96-bit - XPN only */ 98 98 __MACSEC_SA_ATTR_END, 99 99 NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END, 100 100 MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END - 1,