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