1f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc/* 2f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * Copyright 2002-2004, Instant802 Networks, Inc. 3f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * Copyright 2005, Devicescape Software, Inc. 4f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * 5f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * This program is free software; you can redistribute it and/or modify 6f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * it under the terms of the GNU General Public License version 2 as 7f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * published by the Free Software Foundation. 8f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc */ 9f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 10f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#ifndef IEEE80211_KEY_H 11f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#define IEEE80211_KEY_H 12f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 13f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/types.h> 148f37171a6243a8370211a1e86d58be683ccf01f0Johannes Berg#include <linux/list.h> 15f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/crypto.h> 16db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg#include <linux/rcupdate.h> 17f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <net/mac80211.h> 18f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 19e31b82136d1adc7a599b6e99d3321e5831841f5aJohannes Berg#define NUM_DEFAULT_KEYS 4 20e31b82136d1adc7a599b6e99d3321e5831841f5aJohannes Berg#define NUM_DEFAULT_MGMT_KEYS 2 212475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov#define MAX_PN_LEN 16 22e31b82136d1adc7a599b6e99d3321e5831841f5aJohannes Berg 2311a843b7e16062389c53ba393c7913956e034eb2Johannes Bergstruct ieee80211_local; 2411a843b7e16062389c53ba393c7913956e034eb2Johannes Bergstruct ieee80211_sub_if_data; 2511a843b7e16062389c53ba393c7913956e034eb2Johannes Bergstruct sta_info; 2611a843b7e16062389c53ba393c7913956e034eb2Johannes Berg 27db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg/** 28db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg * enum ieee80211_internal_key_flags - internal key flags 29db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg * 30db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present 31db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg * in the hardware for TX crypto hardware acceleration. 3295acac61ba66c4abd40e038dae8c1ed2e176c7b1Johannes Berg * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped. 33db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg */ 34db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Bergenum ieee80211_internal_key_flags { 35db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), 3695acac61ba66c4abd40e038dae8c1ed2e176c7b1Johannes Berg KEY_FLAG_TAINTED = BIT(1), 37db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg}; 3811a843b7e16062389c53ba393c7913956e034eb2Johannes Berg 39ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowskienum ieee80211_internal_tkip_state { 40ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowski TKIP_STATE_NOT_INIT, 41ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowski TKIP_STATE_PHASE1_DONE, 42ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowski TKIP_STATE_PHASE1_HW_UPLOADED, 43ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowski}; 44ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowski 45b0f76b335f8b1c324b4b2be06369d391b26a7cc9Harvey Harrisonstruct tkip_ctx { 46523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg u32 iv32; /* current iv32 */ 47523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg u16 iv16; /* current iv16 */ 48523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg u16 p1k[5]; /* p1k cache */ 49523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg u32 p1k_iv32; /* iv32 for which p1k computed */ 50ca99861d5421c91f5a8fd3a77acb4b7be14f119dgregor kowski enum ieee80211_internal_tkip_state state; 51b0f76b335f8b1c324b4b2be06369d391b26a7cc9Harvey Harrison}; 52b0f76b335f8b1c324b4b2be06369d391b26a7cc9Harvey Harrison 53f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstruct ieee80211_key { 5411a843b7e16062389c53ba393c7913956e034eb2Johannes Berg struct ieee80211_local *local; 5511a843b7e16062389c53ba393c7913956e034eb2Johannes Berg struct ieee80211_sub_if_data *sdata; 5611a843b7e16062389c53ba393c7913956e034eb2Johannes Berg struct sta_info *sta; 5711a843b7e16062389c53ba393c7913956e034eb2Johannes Berg 583b96766f0e643f52ae19e134664df6730c737e87Johannes Berg /* for sdata list */ 5911a843b7e16062389c53ba393c7913956e034eb2Johannes Berg struct list_head list; 6011a843b7e16062389c53ba393c7913956e034eb2Johannes Berg 61ad0e2b5a00dbec303e4682b403bb6703d11dcdb2Johannes Berg /* protected by key mutex */ 6211a843b7e16062389c53ba393c7913956e034eb2Johannes Berg unsigned int flags; 6311a843b7e16062389c53ba393c7913956e034eb2Johannes Berg 64f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc union { 65f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc struct { 66523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg /* protects tx context */ 67523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg spinlock_t txlock; 68523b02ea23b175dd3e46e3daf1bc9354376640a3Johannes Berg 69f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc /* last used TSC */ 70b0f76b335f8b1c324b4b2be06369d391b26a7cc9Harvey Harrison struct tkip_ctx tx; 71f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 72f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc /* last received RSC */ 735a306f5887d5fd840beb8ea872897fa89e8fcdefJohannes Berg struct tkip_ctx rx[IEEE80211_NUM_TIDS]; 74b98ea05861d76f458029096e8b2939fcb58e9530Saravana 75b98ea05861d76f458029096e8b2939fcb58e9530Saravana /* number of mic failures */ 76b98ea05861d76f458029096e8b2939fcb58e9530Saravana u32 mic_failures; 77f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc } tkip; 78f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc struct { 79aba83a0b301c32dbb91c017f33307611e1a1d384Johannes Berg atomic64_t tx_pn; 809190252c952a33efa1ceff4ef35188f8a27b81cbJouni Malinen /* 819190252c952a33efa1ceff4ef35188f8a27b81cbJouni Malinen * Last received packet number. The first 825a306f5887d5fd840beb8ea872897fa89e8fcdefJohannes Berg * IEEE80211_NUM_TIDS counters are used with Data 839190252c952a33efa1ceff4ef35188f8a27b81cbJouni Malinen * frames and the last counter is used with Robust 849190252c952a33efa1ceff4ef35188f8a27b81cbJouni Malinen * Management frames. 859190252c952a33efa1ceff4ef35188f8a27b81cbJouni Malinen */ 864325f6caad98c075b39f0eaaac6693a0dd43f646Johannes Berg u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; 877ec7c4a9a686c608315739ab6a2b0527a240883cArd Biesheuvel struct crypto_aead *tfm; 88f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc u32 replays; /* dot11RSNAStatsCCMPReplays */ 89f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc } ccmp; 90765cb46a3fc856245ea68a7c961ac87c77e4ae2dJouni Malinen struct { 9175396ae6d433b49482e377e6f8dbf1f42ad53f3aJohannes Berg atomic64_t tx_pn; 924325f6caad98c075b39f0eaaac6693a0dd43f646Johannes Berg u8 rx_pn[IEEE80211_CMAC_PN_LEN]; 93765cb46a3fc856245ea68a7c961ac87c77e4ae2dJouni Malinen struct crypto_cipher *tfm; 94765cb46a3fc856245ea68a7c961ac87c77e4ae2dJouni Malinen u32 replays; /* dot11RSNAStatsCMACReplays */ 95765cb46a3fc856245ea68a7c961ac87c77e4ae2dJouni Malinen u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 96765cb46a3fc856245ea68a7c961ac87c77e4ae2dJouni Malinen } aes_cmac; 972475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov struct { 982475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov /* generic cipher scheme */ 992475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN]; 1002475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov } gen; 101f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc } u; 102f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 1038f20fc24986a083228823d9b68adca20714b254eJohannes Berg /* number of times this key has been used */ 1048f20fc24986a083228823d9b68adca20714b254eJohannes Berg int tx_rx_count; 105f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 106e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#ifdef CONFIG_MAC80211_DEBUGFS 107e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct { 108e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct dentry *stalink; 109e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct dentry *dir; 110d9c58f30b08bfe1e689537af5bc855a76d0fae25Johannes Berg int cnt; 111e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc } debugfs; 112e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#endif 113e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 1148f20fc24986a083228823d9b68adca20714b254eJohannes Berg /* 1158f20fc24986a083228823d9b68adca20714b254eJohannes Berg * key config, must be last because it contains key 1168f20fc24986a083228823d9b68adca20714b254eJohannes Berg * material as variable length member 1178f20fc24986a083228823d9b68adca20714b254eJohannes Berg */ 1188f20fc24986a083228823d9b68adca20714b254eJohannes Berg struct ieee80211_key_conf conf; 119f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}; 120f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc 1212475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanovstruct ieee80211_key * 1222475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanovieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 1232475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov const u8 *key_data, 1242475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov size_t seq_len, const u8 *seq, 1252475b1cc0d5283a33144b79f3eba6d401d873962Max Stepanov const struct ieee80211_cipher_scheme *cs); 126db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg/* 127db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg * Insert a key into data structures (sdata, sta if necessary) 12879cf2dfa362f3e6368ad8ecb10aa82b39678fedcJohannes Berg * to make it used, free old key. On failure, also free the new key. 129db4d1169d0b893bfb7923b6526748fe2c5a7373fJohannes Berg */ 13079cf2dfa362f3e6368ad8ecb10aa82b39678fedcJohannes Bergint ieee80211_key_link(struct ieee80211_key *key, 13179cf2dfa362f3e6368ad8ecb10aa82b39678fedcJohannes Berg struct ieee80211_sub_if_data *sdata, 13279cf2dfa362f3e6368ad8ecb10aa82b39678fedcJohannes Berg struct sta_info *sta); 1333b8d9c290364c86fc9f4baff7c82264a96f706d6Johannes Bergvoid ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); 13479cf2dfa362f3e6368ad8ecb10aa82b39678fedcJohannes Bergvoid ieee80211_key_free_unused(struct ieee80211_key *key); 135f7e0104c1a4e77cc4f23d5969b0677bdc4f62c63Johannes Bergvoid ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 136f7e0104c1a4e77cc4f23d5969b0677bdc4f62c63Johannes Berg bool uni, bool multi); 1373cfcf6ac6d69dc290e96416731eea5c88ac7d426Jouni Malinenvoid ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 1383cfcf6ac6d69dc290e96416731eea5c88ac7d426Jouni Malinen int idx); 1397907c7d33c3733b2265dadc6385fe028af72b4c7Johannes Bergvoid ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, 1407907c7d33c3733b2265dadc6385fe028af72b4c7Johannes Berg bool force_synchronize); 1416d10e46be5ac1d0ae787babd3dafd52b30686db5Johannes Bergvoid ieee80211_free_sta_keys(struct ieee80211_local *local, 1426d10e46be5ac1d0ae787babd3dafd52b30686db5Johannes Berg struct sta_info *sta); 14311a843b7e16062389c53ba393c7913956e034eb2Johannes Bergvoid ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 14411a843b7e16062389c53ba393c7913956e034eb2Johannes Berg 14540b275b69ee660274b77fb612b0db31fd282fc3fJohannes Berg#define key_mtx_dereference(local, ref) \ 14640b275b69ee660274b77fb612b0db31fd282fc3fJohannes Berg rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) 14740b275b69ee660274b77fb612b0db31fd282fc3fJohannes Berg 1488d1f7ecd2af55c0c82ffd2bff0ef0b26f16ea69fJohannes Bergvoid ieee80211_delayed_tailroom_dec(struct work_struct *wk); 1498d1f7ecd2af55c0c82ffd2bff0ef0b26f16ea69fJohannes Berg 150f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#endif /* IEEE80211_KEY_H */ 151