xref: /linux/net/mac80211/key.h (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
22c8dccc7SJohannes Berg /*
32c8dccc7SJohannes Berg  * Copyright 2002-2004, Instant802 Networks, Inc.
42c8dccc7SJohannes Berg  * Copyright 2005, Devicescape Software, Inc.
5*e3208fb7SJohannes Berg  * Copyright (C) 2019, 2022-2023 Intel Corporation
62c8dccc7SJohannes Berg  */
72c8dccc7SJohannes Berg 
82c8dccc7SJohannes Berg #ifndef IEEE80211_KEY_H
92c8dccc7SJohannes Berg #define IEEE80211_KEY_H
102c8dccc7SJohannes Berg 
112c8dccc7SJohannes Berg #include <linux/types.h>
122c8dccc7SJohannes Berg #include <linux/list.h>
132c8dccc7SJohannes Berg #include <linux/crypto.h>
142c8dccc7SJohannes Berg #include <linux/rcupdate.h>
155fdb3735SArd Biesheuvel #include <crypto/arc4.h>
162c8dccc7SJohannes Berg #include <net/mac80211.h>
172c8dccc7SJohannes Berg 
18e31b8213SJohannes Berg #define NUM_DEFAULT_KEYS 4
19e31b8213SJohannes Berg #define NUM_DEFAULT_MGMT_KEYS 2
20e5473e80SJouni Malinen #define NUM_DEFAULT_BEACON_KEYS 2
2196fc6efbSAlexander Wetzel #define INVALID_PTK_KEYIDX 2 /* Keyidx always pointing to a NULL key for PTK */
22e31b8213SJohannes Berg 
232c8dccc7SJohannes Berg struct ieee80211_local;
242c8dccc7SJohannes Berg struct ieee80211_sub_if_data;
25ccdde7c7SJohannes Berg struct ieee80211_link_data;
262c8dccc7SJohannes Berg struct sta_info;
272c8dccc7SJohannes Berg 
282c8dccc7SJohannes Berg /**
292c8dccc7SJohannes Berg  * enum ieee80211_internal_key_flags - internal key flags
302c8dccc7SJohannes Berg  *
312c8dccc7SJohannes Berg  * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present
322c8dccc7SJohannes Berg  *	in the hardware for TX crypto hardware acceleration.
3395acac61SJohannes Berg  * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped.
342c8dccc7SJohannes Berg  */
352c8dccc7SJohannes Berg enum ieee80211_internal_key_flags {
362c8dccc7SJohannes Berg 	KEY_FLAG_UPLOADED_TO_HARDWARE	= BIT(0),
3795acac61SJohannes Berg 	KEY_FLAG_TAINTED		= BIT(1),
382c8dccc7SJohannes Berg };
392c8dccc7SJohannes Berg 
40ca99861dSgregor kowski enum ieee80211_internal_tkip_state {
41ca99861dSgregor kowski 	TKIP_STATE_NOT_INIT,
42ca99861dSgregor kowski 	TKIP_STATE_PHASE1_DONE,
43ca99861dSgregor kowski 	TKIP_STATE_PHASE1_HW_UPLOADED,
44ca99861dSgregor kowski };
45ca99861dSgregor kowski 
46b0f76b33SHarvey Harrison struct tkip_ctx {
47523b02eaSJohannes Berg 	u16 p1k[5];	/* p1k cache */
48523b02eaSJohannes Berg 	u32 p1k_iv32;	/* iv32 for which p1k computed */
49ca99861dSgregor kowski 	enum ieee80211_internal_tkip_state state;
50b0f76b33SHarvey Harrison };
51b0f76b33SHarvey Harrison 
52f8079d43SEliad Peller struct tkip_ctx_rx {
53f8079d43SEliad Peller 	struct tkip_ctx ctx;
54f8079d43SEliad Peller 	u32 iv32;	/* current iv32 */
55f8079d43SEliad Peller 	u16 iv16;	/* current iv16 */
56f8079d43SEliad Peller };
57f8079d43SEliad Peller 
582c8dccc7SJohannes Berg struct ieee80211_key {
592c8dccc7SJohannes Berg 	struct ieee80211_local *local;
602c8dccc7SJohannes Berg 	struct ieee80211_sub_if_data *sdata;
612c8dccc7SJohannes Berg 	struct sta_info *sta;
622c8dccc7SJohannes Berg 
632c8dccc7SJohannes Berg 	/* for sdata list */
642c8dccc7SJohannes Berg 	struct list_head list;
652c8dccc7SJohannes Berg 
66ad0e2b5aSJohannes Berg 	/* protected by key mutex */
672c8dccc7SJohannes Berg 	unsigned int flags;
682c8dccc7SJohannes Berg 
692c8dccc7SJohannes Berg 	union {
702c8dccc7SJohannes Berg 		struct {
71523b02eaSJohannes Berg 			/* protects tx context */
72523b02eaSJohannes Berg 			spinlock_t txlock;
73523b02eaSJohannes Berg 
742c8dccc7SJohannes Berg 			/* last used TSC */
75b0f76b33SHarvey Harrison 			struct tkip_ctx tx;
762c8dccc7SJohannes Berg 
772c8dccc7SJohannes Berg 			/* last received RSC */
78f8079d43SEliad Peller 			struct tkip_ctx_rx rx[IEEE80211_NUM_TIDS];
79b98ea058SSaravana 
80b98ea058SSaravana 			/* number of mic failures */
81b98ea058SSaravana 			u32 mic_failures;
822c8dccc7SJohannes Berg 		} tkip;
832c8dccc7SJohannes Berg 		struct {
849190252cSJouni Malinen 			/*
859190252cSJouni Malinen 			 * Last received packet number. The first
865a306f58SJohannes Berg 			 * IEEE80211_NUM_TIDS counters are used with Data
879190252cSJouni Malinen 			 * frames and the last counter is used with Robust
889190252cSJouni Malinen 			 * Management frames.
899190252cSJouni Malinen 			 */
904325f6caSJohannes Berg 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
917ec7c4a9SArd Biesheuvel 			struct crypto_aead *tfm;
922c8dccc7SJohannes Berg 			u32 replays; /* dot11RSNAStatsCCMPReplays */
932c8dccc7SJohannes Berg 		} ccmp;
94765cb46aSJouni Malinen 		struct {
954325f6caSJohannes Berg 			u8 rx_pn[IEEE80211_CMAC_PN_LEN];
9626717828SArd Biesheuvel 			struct crypto_shash *tfm;
97765cb46aSJouni Malinen 			u32 replays; /* dot11RSNAStatsCMACReplays */
98765cb46aSJouni Malinen 			u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
99765cb46aSJouni Malinen 		} aes_cmac;
1002475b1ccSMax Stepanov 		struct {
1018ade538bSJouni Malinen 			u8 rx_pn[IEEE80211_GMAC_PN_LEN];
1028ade538bSJouni Malinen 			struct crypto_aead *tfm;
1038ade538bSJouni Malinen 			u32 replays; /* dot11RSNAStatsCMACReplays */
1048ade538bSJouni Malinen 			u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
1058ade538bSJouni Malinen 		} aes_gmac;
1068ade538bSJouni Malinen 		struct {
10700b9cfa3SJouni Malinen 			/* Last received packet number. The first
10800b9cfa3SJouni Malinen 			 * IEEE80211_NUM_TIDS counters are used with Data
10900b9cfa3SJouni Malinen 			 * frames and the last counter is used with Robust
11000b9cfa3SJouni Malinen 			 * Management frames.
11100b9cfa3SJouni Malinen 			 */
11200b9cfa3SJouni Malinen 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_GCMP_PN_LEN];
11300b9cfa3SJouni Malinen 			struct crypto_aead *tfm;
11400b9cfa3SJouni Malinen 			u32 replays; /* dot11RSNAStatsGCMPReplays */
11500b9cfa3SJouni Malinen 		} gcmp;
11600b9cfa3SJouni Malinen 		struct {
1172475b1ccSMax Stepanov 			/* generic cipher scheme */
118a31cf1c6SJohannes Berg 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_MAX_PN_LEN];
1192475b1ccSMax Stepanov 		} gen;
1202c8dccc7SJohannes Berg 	} u;
1212c8dccc7SJohannes Berg 
1222c8dccc7SJohannes Berg #ifdef CONFIG_MAC80211_DEBUGFS
1232c8dccc7SJohannes Berg 	struct {
1242c8dccc7SJohannes Berg 		struct dentry *stalink;
1252c8dccc7SJohannes Berg 		struct dentry *dir;
126d9c58f30SJohannes Berg 		int cnt;
1272c8dccc7SJohannes Berg 	} debugfs;
1282c8dccc7SJohannes Berg #endif
1292c8dccc7SJohannes Berg 
13094034c40SMathy Vanhoef 	unsigned int color;
13194034c40SMathy Vanhoef 
1322c8dccc7SJohannes Berg 	/*
1332c8dccc7SJohannes Berg 	 * key config, must be last because it contains key
1342c8dccc7SJohannes Berg 	 * material as variable length member
1352c8dccc7SJohannes Berg 	 */
1362c8dccc7SJohannes Berg 	struct ieee80211_key_conf conf;
1372c8dccc7SJohannes Berg };
1382c8dccc7SJohannes Berg 
1392475b1ccSMax Stepanov struct ieee80211_key *
1402475b1ccSMax Stepanov ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
141faa8fdc8SJouni Malinen 		    const u8 *key_data,
14223a5f0afSJohannes Berg 		    size_t seq_len, const u8 *seq);
1432c8dccc7SJohannes Berg /*
1442c8dccc7SJohannes Berg  * Insert a key into data structures (sdata, sta if necessary)
14579cf2dfaSJohannes Berg  * to make it used, free old key. On failure, also free the new key.
1462c8dccc7SJohannes Berg  */
14779cf2dfaSJohannes Berg int ieee80211_key_link(struct ieee80211_key *key,
148ccdde7c7SJohannes Berg 		       struct ieee80211_link_data *link,
1492c8dccc7SJohannes Berg 		       struct sta_info *sta);
15096fc6efbSAlexander Wetzel int ieee80211_set_tx_key(struct ieee80211_key *key);
1513b8d9c29SJohannes Berg void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
15279cf2dfaSJohannes Berg void ieee80211_key_free_unused(struct ieee80211_key *key);
153ccdde7c7SJohannes Berg void ieee80211_set_default_key(struct ieee80211_link_data *link, int idx,
154f7e0104cSJohannes Berg 			       bool uni, bool multi);
155ccdde7c7SJohannes Berg void ieee80211_set_default_mgmt_key(struct ieee80211_link_data *link,
1563cfcf6acSJouni Malinen 				    int idx);
157ccdde7c7SJohannes Berg void ieee80211_set_default_beacon_key(struct ieee80211_link_data *link,
158e5473e80SJouni Malinen 				      int idx);
159ccdde7c7SJohannes Berg void ieee80211_remove_link_keys(struct ieee80211_link_data *link,
160ccdde7c7SJohannes Berg 				struct list_head *keys);
161ccdde7c7SJohannes Berg void ieee80211_free_key_list(struct ieee80211_local *local,
162ccdde7c7SJohannes Berg 			     struct list_head *keys);
1637907c7d3SJohannes Berg void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
1647907c7d3SJohannes Berg 			 bool force_synchronize);
1656d10e46bSJohannes Berg void ieee80211_free_sta_keys(struct ieee80211_local *local,
1666d10e46bSJohannes Berg 			     struct sta_info *sta);
167624ff4b2SLior Cohen void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata);
1683d901102SJohannes Berg int ieee80211_key_switch_links(struct ieee80211_sub_if_data *sdata,
1693d901102SJohannes Berg 			       unsigned long del_links_mask,
1703d901102SJohannes Berg 			       unsigned long add_links_mask);
171*e3208fb7SJohannes Berg void ieee80211_delayed_tailroom_dec(struct wiphy *wiphy,
172*e3208fb7SJohannes Berg 				    struct wiphy_work *wk);
1738d1f7ecdSJohannes Berg 
1742c8dccc7SJohannes Berg #endif /* IEEE80211_KEY_H */
175