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. 523a5f0afSJohannes Berg * Copyright (C) 2019, 2022 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); 168*3d901102SJohannes Berg int ieee80211_key_switch_links(struct ieee80211_sub_if_data *sdata, 169*3d901102SJohannes Berg unsigned long del_links_mask, 170*3d901102SJohannes Berg unsigned long add_links_mask); 1712c8dccc7SJohannes Berg 17240b275b6SJohannes Berg #define key_mtx_dereference(local, ref) \ 17340b275b6SJohannes Berg rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) 1748cbf0c2aSJohannes Berg #define rcu_dereference_check_key_mtx(local, ref) \ 1758cbf0c2aSJohannes Berg rcu_dereference_check(ref, lockdep_is_held(&((local)->key_mtx))) 17640b275b6SJohannes Berg 1778d1f7ecdSJohannes Berg void ieee80211_delayed_tailroom_dec(struct work_struct *wk); 1788d1f7ecdSJohannes Berg 1792c8dccc7SJohannes Berg #endif /* IEEE80211_KEY_H */ 180