18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * MACsec netdev header, used for h/w accelerated implementations.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2015 Sabrina Dubroca <sd@queasysnail.net>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#ifndef _NET_MACSEC_H_
88c2ecf20Sopenharmony_ci#define _NET_MACSEC_H_
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/u64_stats_sync.h>
118c2ecf20Sopenharmony_ci#include <uapi/linux/if_link.h>
128c2ecf20Sopenharmony_ci#include <uapi/linux/if_macsec.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define MACSEC_DEFAULT_PN_LEN 4
158c2ecf20Sopenharmony_ci#define MACSEC_XPN_PN_LEN 8
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define MACSEC_SALT_LEN 12
188c2ecf20Sopenharmony_ci#define MACSEC_NUM_AN 4 /* 2 bits for the association number */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_citypedef u64 __bitwise sci_t;
218c2ecf20Sopenharmony_citypedef u32 __bitwise ssci_t;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_citypedef union salt {
248c2ecf20Sopenharmony_ci	struct {
258c2ecf20Sopenharmony_ci		u32 ssci;
268c2ecf20Sopenharmony_ci		u64 pn;
278c2ecf20Sopenharmony_ci	} __packed;
288c2ecf20Sopenharmony_ci	u8 bytes[MACSEC_SALT_LEN];
298c2ecf20Sopenharmony_ci} __packed salt_t;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_citypedef union pn {
328c2ecf20Sopenharmony_ci	struct {
338c2ecf20Sopenharmony_ci#if defined(__LITTLE_ENDIAN_BITFIELD)
348c2ecf20Sopenharmony_ci		u32 lower;
358c2ecf20Sopenharmony_ci		u32 upper;
368c2ecf20Sopenharmony_ci#elif defined(__BIG_ENDIAN_BITFIELD)
378c2ecf20Sopenharmony_ci		u32 upper;
388c2ecf20Sopenharmony_ci		u32 lower;
398c2ecf20Sopenharmony_ci#else
408c2ecf20Sopenharmony_ci#error	"Please fix <asm/byteorder.h>"
418c2ecf20Sopenharmony_ci#endif
428c2ecf20Sopenharmony_ci	};
438c2ecf20Sopenharmony_ci	u64 full64;
448c2ecf20Sopenharmony_ci} pn_t;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/**
478c2ecf20Sopenharmony_ci * struct macsec_key - SA key
488c2ecf20Sopenharmony_ci * @id: user-provided key identifier
498c2ecf20Sopenharmony_ci * @tfm: crypto struct, key storage
508c2ecf20Sopenharmony_ci * @salt: salt used to generate IV in XPN cipher suites
518c2ecf20Sopenharmony_ci */
528c2ecf20Sopenharmony_cistruct macsec_key {
538c2ecf20Sopenharmony_ci	u8 id[MACSEC_KEYID_LEN];
548c2ecf20Sopenharmony_ci	struct crypto_aead *tfm;
558c2ecf20Sopenharmony_ci	salt_t salt;
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistruct macsec_rx_sc_stats {
598c2ecf20Sopenharmony_ci	__u64 InOctetsValidated;
608c2ecf20Sopenharmony_ci	__u64 InOctetsDecrypted;
618c2ecf20Sopenharmony_ci	__u64 InPktsUnchecked;
628c2ecf20Sopenharmony_ci	__u64 InPktsDelayed;
638c2ecf20Sopenharmony_ci	__u64 InPktsOK;
648c2ecf20Sopenharmony_ci	__u64 InPktsInvalid;
658c2ecf20Sopenharmony_ci	__u64 InPktsLate;
668c2ecf20Sopenharmony_ci	__u64 InPktsNotValid;
678c2ecf20Sopenharmony_ci	__u64 InPktsNotUsingSA;
688c2ecf20Sopenharmony_ci	__u64 InPktsUnusedSA;
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistruct macsec_rx_sa_stats {
728c2ecf20Sopenharmony_ci	__u32 InPktsOK;
738c2ecf20Sopenharmony_ci	__u32 InPktsInvalid;
748c2ecf20Sopenharmony_ci	__u32 InPktsNotValid;
758c2ecf20Sopenharmony_ci	__u32 InPktsNotUsingSA;
768c2ecf20Sopenharmony_ci	__u32 InPktsUnusedSA;
778c2ecf20Sopenharmony_ci};
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistruct macsec_tx_sa_stats {
808c2ecf20Sopenharmony_ci	__u32 OutPktsProtected;
818c2ecf20Sopenharmony_ci	__u32 OutPktsEncrypted;
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistruct macsec_tx_sc_stats {
858c2ecf20Sopenharmony_ci	__u64 OutPktsProtected;
868c2ecf20Sopenharmony_ci	__u64 OutPktsEncrypted;
878c2ecf20Sopenharmony_ci	__u64 OutOctetsProtected;
888c2ecf20Sopenharmony_ci	__u64 OutOctetsEncrypted;
898c2ecf20Sopenharmony_ci};
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistruct macsec_dev_stats {
928c2ecf20Sopenharmony_ci	__u64 OutPktsUntagged;
938c2ecf20Sopenharmony_ci	__u64 InPktsUntagged;
948c2ecf20Sopenharmony_ci	__u64 OutPktsTooLong;
958c2ecf20Sopenharmony_ci	__u64 InPktsNoTag;
968c2ecf20Sopenharmony_ci	__u64 InPktsBadTag;
978c2ecf20Sopenharmony_ci	__u64 InPktsUnknownSCI;
988c2ecf20Sopenharmony_ci	__u64 InPktsNoSCI;
998c2ecf20Sopenharmony_ci	__u64 InPktsOverrun;
1008c2ecf20Sopenharmony_ci};
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/**
1038c2ecf20Sopenharmony_ci * struct macsec_rx_sa - receive secure association
1048c2ecf20Sopenharmony_ci * @active:
1058c2ecf20Sopenharmony_ci * @next_pn: packet number expected for the next packet
1068c2ecf20Sopenharmony_ci * @lock: protects next_pn manipulations
1078c2ecf20Sopenharmony_ci * @key: key structure
1088c2ecf20Sopenharmony_ci * @ssci: short secure channel identifier
1098c2ecf20Sopenharmony_ci * @stats: per-SA stats
1108c2ecf20Sopenharmony_ci */
1118c2ecf20Sopenharmony_cistruct macsec_rx_sa {
1128c2ecf20Sopenharmony_ci	struct macsec_key key;
1138c2ecf20Sopenharmony_ci	ssci_t ssci;
1148c2ecf20Sopenharmony_ci	spinlock_t lock;
1158c2ecf20Sopenharmony_ci	union {
1168c2ecf20Sopenharmony_ci		pn_t next_pn_halves;
1178c2ecf20Sopenharmony_ci		u64 next_pn;
1188c2ecf20Sopenharmony_ci	};
1198c2ecf20Sopenharmony_ci	refcount_t refcnt;
1208c2ecf20Sopenharmony_ci	bool active;
1218c2ecf20Sopenharmony_ci	struct macsec_rx_sa_stats __percpu *stats;
1228c2ecf20Sopenharmony_ci	struct macsec_rx_sc *sc;
1238c2ecf20Sopenharmony_ci	struct rcu_head rcu;
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistruct pcpu_rx_sc_stats {
1278c2ecf20Sopenharmony_ci	struct macsec_rx_sc_stats stats;
1288c2ecf20Sopenharmony_ci	struct u64_stats_sync syncp;
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistruct pcpu_tx_sc_stats {
1328c2ecf20Sopenharmony_ci	struct macsec_tx_sc_stats stats;
1338c2ecf20Sopenharmony_ci	struct u64_stats_sync syncp;
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/**
1378c2ecf20Sopenharmony_ci * struct macsec_rx_sc - receive secure channel
1388c2ecf20Sopenharmony_ci * @sci: secure channel identifier for this SC
1398c2ecf20Sopenharmony_ci * @active: channel is active
1408c2ecf20Sopenharmony_ci * @sa: array of secure associations
1418c2ecf20Sopenharmony_ci * @stats: per-SC stats
1428c2ecf20Sopenharmony_ci */
1438c2ecf20Sopenharmony_cistruct macsec_rx_sc {
1448c2ecf20Sopenharmony_ci	struct macsec_rx_sc __rcu *next;
1458c2ecf20Sopenharmony_ci	sci_t sci;
1468c2ecf20Sopenharmony_ci	bool active;
1478c2ecf20Sopenharmony_ci	struct macsec_rx_sa __rcu *sa[MACSEC_NUM_AN];
1488c2ecf20Sopenharmony_ci	struct pcpu_rx_sc_stats __percpu *stats;
1498c2ecf20Sopenharmony_ci	refcount_t refcnt;
1508c2ecf20Sopenharmony_ci	struct rcu_head rcu_head;
1518c2ecf20Sopenharmony_ci};
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/**
1548c2ecf20Sopenharmony_ci * struct macsec_tx_sa - transmit secure association
1558c2ecf20Sopenharmony_ci * @active:
1568c2ecf20Sopenharmony_ci * @next_pn: packet number to use for the next packet
1578c2ecf20Sopenharmony_ci * @lock: protects next_pn manipulations
1588c2ecf20Sopenharmony_ci * @key: key structure
1598c2ecf20Sopenharmony_ci * @ssci: short secure channel identifier
1608c2ecf20Sopenharmony_ci * @stats: per-SA stats
1618c2ecf20Sopenharmony_ci */
1628c2ecf20Sopenharmony_cistruct macsec_tx_sa {
1638c2ecf20Sopenharmony_ci	struct macsec_key key;
1648c2ecf20Sopenharmony_ci	ssci_t ssci;
1658c2ecf20Sopenharmony_ci	spinlock_t lock;
1668c2ecf20Sopenharmony_ci	union {
1678c2ecf20Sopenharmony_ci		pn_t next_pn_halves;
1688c2ecf20Sopenharmony_ci		u64 next_pn;
1698c2ecf20Sopenharmony_ci	};
1708c2ecf20Sopenharmony_ci	refcount_t refcnt;
1718c2ecf20Sopenharmony_ci	bool active;
1728c2ecf20Sopenharmony_ci	struct macsec_tx_sa_stats __percpu *stats;
1738c2ecf20Sopenharmony_ci	struct rcu_head rcu;
1748c2ecf20Sopenharmony_ci};
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci/**
1778c2ecf20Sopenharmony_ci * struct macsec_tx_sc - transmit secure channel
1788c2ecf20Sopenharmony_ci * @active:
1798c2ecf20Sopenharmony_ci * @encoding_sa: association number of the SA currently in use
1808c2ecf20Sopenharmony_ci * @encrypt: encrypt packets on transmit, or authenticate only
1818c2ecf20Sopenharmony_ci * @send_sci: always include the SCI in the SecTAG
1828c2ecf20Sopenharmony_ci * @end_station:
1838c2ecf20Sopenharmony_ci * @scb: single copy broadcast flag
1848c2ecf20Sopenharmony_ci * @sa: array of secure associations
1858c2ecf20Sopenharmony_ci * @stats: stats for this TXSC
1868c2ecf20Sopenharmony_ci */
1878c2ecf20Sopenharmony_cistruct macsec_tx_sc {
1888c2ecf20Sopenharmony_ci	bool active;
1898c2ecf20Sopenharmony_ci	u8 encoding_sa;
1908c2ecf20Sopenharmony_ci	bool encrypt;
1918c2ecf20Sopenharmony_ci	bool send_sci;
1928c2ecf20Sopenharmony_ci	bool end_station;
1938c2ecf20Sopenharmony_ci	bool scb;
1948c2ecf20Sopenharmony_ci	struct macsec_tx_sa __rcu *sa[MACSEC_NUM_AN];
1958c2ecf20Sopenharmony_ci	struct pcpu_tx_sc_stats __percpu *stats;
1968c2ecf20Sopenharmony_ci};
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci/**
1998c2ecf20Sopenharmony_ci * struct macsec_secy - MACsec Security Entity
2008c2ecf20Sopenharmony_ci * @netdev: netdevice for this SecY
2018c2ecf20Sopenharmony_ci * @n_rx_sc: number of receive secure channels configured on this SecY
2028c2ecf20Sopenharmony_ci * @sci: secure channel identifier used for tx
2038c2ecf20Sopenharmony_ci * @key_len: length of keys used by the cipher suite
2048c2ecf20Sopenharmony_ci * @icv_len: length of ICV used by the cipher suite
2058c2ecf20Sopenharmony_ci * @validate_frames: validation mode
2068c2ecf20Sopenharmony_ci * @xpn: enable XPN for this SecY
2078c2ecf20Sopenharmony_ci * @operational: MAC_Operational flag
2088c2ecf20Sopenharmony_ci * @protect_frames: enable protection for this SecY
2098c2ecf20Sopenharmony_ci * @replay_protect: enable packet number checks on receive
2108c2ecf20Sopenharmony_ci * @replay_window: size of the replay window
2118c2ecf20Sopenharmony_ci * @tx_sc: transmit secure channel
2128c2ecf20Sopenharmony_ci * @rx_sc: linked list of receive secure channels
2138c2ecf20Sopenharmony_ci */
2148c2ecf20Sopenharmony_cistruct macsec_secy {
2158c2ecf20Sopenharmony_ci	struct net_device *netdev;
2168c2ecf20Sopenharmony_ci	unsigned int n_rx_sc;
2178c2ecf20Sopenharmony_ci	sci_t sci;
2188c2ecf20Sopenharmony_ci	u16 key_len;
2198c2ecf20Sopenharmony_ci	u16 icv_len;
2208c2ecf20Sopenharmony_ci	enum macsec_validation_type validate_frames;
2218c2ecf20Sopenharmony_ci	bool xpn;
2228c2ecf20Sopenharmony_ci	bool operational;
2238c2ecf20Sopenharmony_ci	bool protect_frames;
2248c2ecf20Sopenharmony_ci	bool replay_protect;
2258c2ecf20Sopenharmony_ci	u32 replay_window;
2268c2ecf20Sopenharmony_ci	struct macsec_tx_sc tx_sc;
2278c2ecf20Sopenharmony_ci	struct macsec_rx_sc __rcu *rx_sc;
2288c2ecf20Sopenharmony_ci};
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci/**
2318c2ecf20Sopenharmony_ci * struct macsec_context - MACsec context for hardware offloading
2328c2ecf20Sopenharmony_ci */
2338c2ecf20Sopenharmony_cistruct macsec_context {
2348c2ecf20Sopenharmony_ci	union {
2358c2ecf20Sopenharmony_ci		struct net_device *netdev;
2368c2ecf20Sopenharmony_ci		struct phy_device *phydev;
2378c2ecf20Sopenharmony_ci	};
2388c2ecf20Sopenharmony_ci	enum macsec_offload offload;
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci	struct macsec_secy *secy;
2418c2ecf20Sopenharmony_ci	struct macsec_rx_sc *rx_sc;
2428c2ecf20Sopenharmony_ci	struct {
2438c2ecf20Sopenharmony_ci		bool update_pn;
2448c2ecf20Sopenharmony_ci		unsigned char assoc_num;
2458c2ecf20Sopenharmony_ci		u8 key[MACSEC_MAX_KEY_LEN];
2468c2ecf20Sopenharmony_ci		union {
2478c2ecf20Sopenharmony_ci			struct macsec_rx_sa *rx_sa;
2488c2ecf20Sopenharmony_ci			struct macsec_tx_sa *tx_sa;
2498c2ecf20Sopenharmony_ci		};
2508c2ecf20Sopenharmony_ci	} sa;
2518c2ecf20Sopenharmony_ci	union {
2528c2ecf20Sopenharmony_ci		struct macsec_tx_sc_stats *tx_sc_stats;
2538c2ecf20Sopenharmony_ci		struct macsec_tx_sa_stats *tx_sa_stats;
2548c2ecf20Sopenharmony_ci		struct macsec_rx_sc_stats *rx_sc_stats;
2558c2ecf20Sopenharmony_ci		struct macsec_rx_sa_stats *rx_sa_stats;
2568c2ecf20Sopenharmony_ci		struct macsec_dev_stats  *dev_stats;
2578c2ecf20Sopenharmony_ci	} stats;
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	u8 prepare:1;
2608c2ecf20Sopenharmony_ci};
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci/**
2638c2ecf20Sopenharmony_ci * struct macsec_ops - MACsec offloading operations
2648c2ecf20Sopenharmony_ci */
2658c2ecf20Sopenharmony_cistruct macsec_ops {
2668c2ecf20Sopenharmony_ci	/* Device wide */
2678c2ecf20Sopenharmony_ci	int (*mdo_dev_open)(struct macsec_context *ctx);
2688c2ecf20Sopenharmony_ci	int (*mdo_dev_stop)(struct macsec_context *ctx);
2698c2ecf20Sopenharmony_ci	/* SecY */
2708c2ecf20Sopenharmony_ci	int (*mdo_add_secy)(struct macsec_context *ctx);
2718c2ecf20Sopenharmony_ci	int (*mdo_upd_secy)(struct macsec_context *ctx);
2728c2ecf20Sopenharmony_ci	int (*mdo_del_secy)(struct macsec_context *ctx);
2738c2ecf20Sopenharmony_ci	/* Security channels */
2748c2ecf20Sopenharmony_ci	int (*mdo_add_rxsc)(struct macsec_context *ctx);
2758c2ecf20Sopenharmony_ci	int (*mdo_upd_rxsc)(struct macsec_context *ctx);
2768c2ecf20Sopenharmony_ci	int (*mdo_del_rxsc)(struct macsec_context *ctx);
2778c2ecf20Sopenharmony_ci	/* Security associations */
2788c2ecf20Sopenharmony_ci	int (*mdo_add_rxsa)(struct macsec_context *ctx);
2798c2ecf20Sopenharmony_ci	int (*mdo_upd_rxsa)(struct macsec_context *ctx);
2808c2ecf20Sopenharmony_ci	int (*mdo_del_rxsa)(struct macsec_context *ctx);
2818c2ecf20Sopenharmony_ci	int (*mdo_add_txsa)(struct macsec_context *ctx);
2828c2ecf20Sopenharmony_ci	int (*mdo_upd_txsa)(struct macsec_context *ctx);
2838c2ecf20Sopenharmony_ci	int (*mdo_del_txsa)(struct macsec_context *ctx);
2848c2ecf20Sopenharmony_ci	/* Statistics */
2858c2ecf20Sopenharmony_ci	int (*mdo_get_dev_stats)(struct macsec_context *ctx);
2868c2ecf20Sopenharmony_ci	int (*mdo_get_tx_sc_stats)(struct macsec_context *ctx);
2878c2ecf20Sopenharmony_ci	int (*mdo_get_tx_sa_stats)(struct macsec_context *ctx);
2888c2ecf20Sopenharmony_ci	int (*mdo_get_rx_sc_stats)(struct macsec_context *ctx);
2898c2ecf20Sopenharmony_ci	int (*mdo_get_rx_sa_stats)(struct macsec_context *ctx);
2908c2ecf20Sopenharmony_ci};
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_civoid macsec_pn_wrapped(struct macsec_secy *secy, struct macsec_tx_sa *tx_sa);
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci#endif /* _NET_MACSEC_H_ */
295