197 lines
5.5 KiB
C
197 lines
5.5 KiB
C
#ifndef WPA_H
|
|
#define WPA_H
|
|
|
|
#define WPA_NONCE_LEN 32
|
|
#define WPA_PMK_LEN PMK_LEN
|
|
#define WPA_REPLAY_COUNTER_LEN 8
|
|
#define WPA_GMK_LEN 32
|
|
#define WPA_GTK_MAX_LEN 32
|
|
#define WPA_KEY_RSC_LEN 8
|
|
#define PMKID_LEN 16
|
|
|
|
struct rsn_pmksa_cache {
|
|
struct rsn_pmksa_cache *next, *hnext;
|
|
u8 pmkid[PMKID_LEN];
|
|
u8 pmk[PMK_LEN];
|
|
time_t expiration;
|
|
int akmp; /* WPA_KEY_MGMT_* */
|
|
u8 spa[ETH_ALEN];
|
|
u8 *identity;
|
|
size_t identity_len;
|
|
struct radius_class_data radius_class;
|
|
};
|
|
|
|
struct rsn_preauth_interface {
|
|
struct rsn_preauth_interface *next;
|
|
struct hostapd_data *hapd;
|
|
struct l2_packet_data *l2;
|
|
char *ifname;
|
|
int ifindex;
|
|
};
|
|
|
|
struct wpa_eapol_key {
|
|
u8 type;
|
|
u16 key_info;
|
|
u16 key_length;
|
|
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
|
|
u8 key_nonce[WPA_NONCE_LEN];
|
|
u8 key_iv[16];
|
|
u8 key_rsc[WPA_KEY_RSC_LEN];
|
|
u8 key_id[8]; /* Reserved */
|
|
u8 key_mic[16];
|
|
u16 key_data_length;
|
|
/* followed by key_data_length bytes of key_data */
|
|
} __attribute__ ((packed));
|
|
|
|
#define WPA_KEY_INFO_TYPE_MASK (BIT(0) | BIT(1) | BIT(2))
|
|
#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0)
|
|
#define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1)
|
|
#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */
|
|
/* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */
|
|
#define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5))
|
|
#define WPA_KEY_INFO_KEY_INDEX_SHIFT 4
|
|
#define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */
|
|
#define WPA_KEY_INFO_TXRX BIT(6) /* group */
|
|
#define WPA_KEY_INFO_ACK BIT(7)
|
|
#define WPA_KEY_INFO_MIC BIT(8)
|
|
#define WPA_KEY_INFO_SECURE BIT(9)
|
|
#define WPA_KEY_INFO_ERROR BIT(10)
|
|
#define WPA_KEY_INFO_REQUEST BIT(11)
|
|
#define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12)
|
|
|
|
|
|
/* per STA state machine data */
|
|
|
|
struct wpa_ptk {
|
|
u8 mic_key[16]; /* EAPOL-Key MIC Key (MK) */
|
|
u8 encr_key[16]; /* EAPOL-Key Encryption Key (EK) */
|
|
u8 tk1[16]; /* Temporal Key 1 (TK1) */
|
|
union {
|
|
u8 tk2[16]; /* Temporal Key 2 (TK2) */
|
|
struct {
|
|
u8 tx_mic_key[8];
|
|
u8 rx_mic_key[8];
|
|
} auth;
|
|
} u;
|
|
} __attribute__ ((packed));
|
|
|
|
struct wpa_state_machine {
|
|
struct hostapd_data *hapd;
|
|
struct sta_info *sta;
|
|
|
|
enum {
|
|
WPA_PTK_INITIALIZE, WPA_PTK_DISCONNECT, WPA_PTK_DISCONNECTED,
|
|
WPA_PTK_AUTHENTICATION, WPA_PTK_AUTHENTICATION2,
|
|
WPA_PTK_INITPMK, WPA_PTK_INITPSK, WPA_PTK_PTKSTART,
|
|
WPA_PTK_PTKCALCNEGOTIATING, WPA_PTK_PTKCALCNEGOTIATING2,
|
|
WPA_PTK_PTKINITNEGOTIATING, WPA_PTK_PTKINITDONE
|
|
} wpa_ptk_state;
|
|
|
|
enum {
|
|
WPA_PTK_GROUP_IDLE = 0,
|
|
WPA_PTK_GROUP_REKEYNEGOTIATING,
|
|
WPA_PTK_GROUP_REKEYESTABLISHED,
|
|
WPA_PTK_GROUP_KEYERROR
|
|
} wpa_ptk_group_state;
|
|
|
|
Boolean Init;
|
|
Boolean DeauthenticationRequest;
|
|
Boolean AuthenticationRequest;
|
|
Boolean ReAuthenticationRequest;
|
|
Boolean Disconnect;
|
|
int TimeoutCtr;
|
|
int GTimeoutCtr;
|
|
Boolean TimeoutEvt;
|
|
Boolean EAPOLKeyReceived;
|
|
Boolean EAPOLKeyPairwise;
|
|
Boolean EAPOLKeyRequest;
|
|
Boolean MICVerified;
|
|
Boolean GUpdateStationKeys;
|
|
u8 ANonce[WPA_NONCE_LEN];
|
|
u8 SNonce[WPA_NONCE_LEN];
|
|
u8 PMK[WPA_PMK_LEN];
|
|
struct wpa_ptk PTK;
|
|
Boolean PTK_valid;
|
|
Boolean pairwise_set;
|
|
int keycount;
|
|
Boolean Pair;
|
|
u8 key_replay_counter[WPA_REPLAY_COUNTER_LEN];
|
|
Boolean key_replay_counter_valid;
|
|
Boolean PInitAKeys; /* WPA only, not in IEEE 802.11i/D8 */
|
|
Boolean PTKRequest; /* not in IEEE 802.11i state machine */
|
|
Boolean has_GTK;
|
|
|
|
u8 *last_rx_eapol_key; /* starting from IEEE 802.1X header */
|
|
size_t last_rx_eapol_key_len;
|
|
|
|
Boolean changed;
|
|
};
|
|
|
|
/* per authenticator data */
|
|
struct wpa_authenticator {
|
|
Boolean GInit;
|
|
int GNoStations;
|
|
int GKeyDoneStations;
|
|
Boolean GTKReKey;
|
|
int GTK_len;
|
|
int GN, GM;
|
|
Boolean GTKAuthenticator;
|
|
u8 Counter[WPA_NONCE_LEN];
|
|
|
|
enum {
|
|
WPA_GROUP_GTK_INIT = 0,
|
|
WPA_GROUP_SETKEYS, WPA_GROUP_SETKEYSDONE
|
|
} wpa_group_state;
|
|
|
|
u8 GMK[WPA_GMK_LEN];
|
|
u8 GTK[2][WPA_GTK_MAX_LEN];
|
|
u8 GNonce[WPA_NONCE_LEN];
|
|
Boolean changed;
|
|
|
|
unsigned int dot11RSNAStatsTKIPRemoteMICFailures;
|
|
u8 dot11RSNAAuthenticationSuiteSelected[4];
|
|
u8 dot11RSNAPairwiseCipherSelected[4];
|
|
u8 dot11RSNAGroupCipherSelected[4];
|
|
u8 dot11RSNAPMKIDUsed[PMKID_LEN];
|
|
u8 dot11RSNAAuthenticationSuiteRequested[4]; /* FIX: update */
|
|
u8 dot11RSNAPairwiseCipherRequested[4]; /* FIX: update */
|
|
u8 dot11RSNAGroupCipherRequested[4]; /* FIX: update */
|
|
unsigned int dot11RSNATKIPCounterMeasuresInvoked;
|
|
unsigned int dot11RSNA4WayHandshakeFailures;
|
|
};
|
|
|
|
|
|
int wpa_init(struct hostapd_data *hapd);
|
|
void wpa_deinit(struct hostapd_data *hapd);
|
|
|
|
enum {
|
|
WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE,
|
|
WPA_INVALID_AKMP
|
|
};
|
|
|
|
int wpa_validate_wpa_ie(struct hostapd_data *hapd, struct sta_info *sta,
|
|
const u8 *wpa_ie, size_t wpa_ie_len, int version);
|
|
void wpa_new_station(struct hostapd_data *hapd, struct sta_info *sta);
|
|
void wpa_free_station(struct sta_info *sta);
|
|
void wpa_receive(struct hostapd_data *hapd, struct sta_info *sta,
|
|
u8 *data, size_t data_len);
|
|
typedef enum {
|
|
WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH,
|
|
WPA_REAUTH_EAPOL
|
|
} wpa_event;
|
|
void wpa_sm_event(struct hostapd_data *hapd, struct sta_info *sta,
|
|
wpa_event event);
|
|
void wpa_sm_notify(struct hostapd_data *hapd, struct sta_info *sta);
|
|
void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk,
|
|
int session_timeout);
|
|
void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
|
|
int success);
|
|
void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
|
|
u8 *buf, size_t len);
|
|
void wpa_gtk_rekey(struct hostapd_data *hapd);
|
|
int wpa_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen);
|
|
int wpa_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
|
char *buf, size_t buflen);
|
|
|
|
#endif /* WPA_H */
|