text: /******************************************************************************
  *  Copyright 2017 - 2018, Opulinks Technology Ltd.
  *  ---------------------------------------------------------------------------
  *  Statement:
  *  ----------
  *  This software is protected by Copyright and the information contained
  *  herein is confidential. The software may not be copied and the information
  *  contained herein may not be used or disclosed except with the written
  *  permission of Opulinks Technology Ltd. (C) 2018
  ******************************************************************************/
  
  #ifndef _WIFI_WPA_RSNE_H_
  #define _WIFI_WPA_RSNE_H_
  
  #include "wifi_mac_common.h"
  
  
  #define PATH_TO_APS			0
  #define PATH_TO_MSQ		1
  #define PATH_TO_NOTHING	2
  
  #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
  #define ETH_P_EAPOL ETH_P_PAE
  #define ETH_ALEN 6
  #define ETH_P_EAPOL_LEN 384
  
  #define BIT(x) (1 << (x))
  #define WPA_PROTO_WPA BIT(0)
  #define WPA_PROTO_RSN BIT(1)
  #define WPA_CIPHER_NONE BIT(0)
  #define WPA_CIPHER_WEP40 BIT(1)
  #define WPA_CIPHER_WEP104 BIT(2)
  #define WPA_CIPHER_TKIP BIT(3)
  #define WPA_CIPHER_CCMP BIT(4)
  #ifdef CONFIG_IEEE80211W    //802.11w : Protected Management Frame standard
  #define WPA_CIPHER_AES_128_CMAC BIT(5)
  #endif /* CONFIG_IEEE80211W */
  
  #define WPA_KEY_MGMT_IEEE8021X BIT(0)
  #define WPA_KEY_MGMT_PSK BIT(1)
  #define WPA_KEY_MGMT_NONE BIT(2)
  #define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3)
  #define WPA_KEY_MGMT_WPA_NONE BIT(4)
  #define WPA_KEY_MGMT_FT_IEEE8021X BIT(5)
  #define WPA_KEY_MGMT_FT_PSK BIT(6)
  #define WPA_KEY_MGMT_IEEE8021X_SHA256 BIT(7)
  #define WPA_KEY_MGMT_PSK_SHA256 BIT(8)
  #define WPA_KEY_MGMT_WPS BIT(9)
  
  /* IEEE 802.11i */
  #define PMKID_LEN 16
  #define PMK_LEN 32
  #define WPA_REPLAY_COUNTER_LEN 8
  #define WPA_NONCE_LEN 32
  #define WPA_KEY_RSC_LEN 8
  #define WPA_GMK_LEN 32
  #define WPA_GTK_MAX_LEN 32
  
  #define WPA_SELECTOR_LEN 4
  #define WPA_VERSION 1
  #define RSN_SELECTOR_LEN 4
  #define RSN_VERSION 1
  
  #define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
  #define WPA_PUT_BE16(a, val)			\
  	do {					\
  		(a)[0] = ((u16) (val)) >> 8;	\
  		(a)[1] = ((u16) (val)) & 0xff;	\
  	} while (0)
  #define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
  #define WPA_PUT_LE16(a, val)			\
  	do {					\
  		(a)[1] = ((u16) (val)) >> 8;	\
  		(a)[0] = ((u16) (val)) & 0xff;	\
  	} while (0)
  #define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
  			 (((u32) (a)[2]) << 8) | ((u32) (a)[3]))
  #define WPA_PUT_BE32(a, val)					\
  	do {							\
  		(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
  		(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
  		(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
  		(a)[3] = (u8) (((u32) (val)) & 0xff);		\
  	} while (0)
  
  #define RSN_SELECTOR(a, b, c, d) \
  	((((u32) (a)) << 24) | (((u32) (b)) << 16) | (((u32) (c)) << 8) | \
  	 (u32) (d))
  #define WPA_AUTH_KEY_MGMT_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0)
  #define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
  #define WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 2)
  #define WPA_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0)
  #define WPA_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
  #define WPA_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x50, 0xf2, 2)
  #if 0
  #define WPA_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x50, 0xf2, 3)
  #endif
  #define WPA_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x50, 0xf2, 4)
  #define WPA_CIPHER_SUITE_WEP104 RSN_SELECTOR(0x00, 0x50, 0xf2, 5)
  
  
  #define RSN_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
  #define RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
  #ifdef CONFIG_IEEE80211R
  #define RSN_AUTH_KEY_MGMT_FT_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 3)
  #define RSN_AUTH_KEY_MGMT_FT_PSK RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
  #endif /* CONFIG_IEEE80211R */
  #define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
  #define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
  
  #define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
  #define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
  #define RSN_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
  #if 0
  #define RSN_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x0f, 0xac, 3)
  #endif
  #define RSN_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
  #define RSN_CIPHER_SUITE_WEP104 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
  #ifdef CONFIG_IEEE80211W
  #define RSN_CIPHER_SUITE_AES_128_CMAC RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
  #endif /* CONFIG_IEEE80211W */
  
  /* EAPOL-Key Key Data Encapsulation
   * GroupKey and PeerKey require encryption, otherwise, encryption is optional.
   */
  #define RSN_KEY_DATA_GROUPKEY RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
  #if 0
  #define RSN_KEY_DATA_STAKEY RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
  #endif
  #define RSN_KEY_DATA_MAC_ADDR RSN_SELECTOR(0x00, 0x0f, 0xac, 3)
  #define RSN_KEY_DATA_PMKID RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
  #ifdef CONFIG_PEERKEY
  #define RSN_KEY_DATA_SMK RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
  #define RSN_KEY_DATA_NONCE RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
  #define RSN_KEY_DATA_LIFETIME RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
  #define RSN_KEY_DATA_ERROR RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
  #endif /* CONFIG_PEERKEY */
  #ifdef CONFIG_IEEE80211W
  #define RSN_KEY_DATA_IGTK RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
  #endif /* CONFIG_IEEE80211W */
  
  #define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
  
  #define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val))
  #define RSN_SELECTOR_GET(a) WPA_GET_BE32((const u8 *) (a))
  
  #define RSN_NUM_REPLAY_COUNTERS_1 0
  #define RSN_NUM_REPLAY_COUNTERS_2 1
  #define RSN_NUM_REPLAY_COUNTERS_4 2
  #define RSN_NUM_REPLAY_COUNTERS_16 3
  
  #define DEFAULT_PROTO (WPA_PROTO_WPA | WPA_PROTO_RSN)
  #define DEFAULT_KEY_MGMT (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X)
  #define DEFAULT_PAIRWISE (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP)
  #define DEFAULT_GROUP (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP /*| WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40*/)
  #define DEFAULT_FRAGMENT_SIZE 1398
  
  typedef struct wpa_ie_data
  {
      int proto;
      int pairwise_cipher;
      int group_cipher;
      int key_mgmt;
      int capabilities;
      size_t num_pmkid;
      const u8 *pmkid;
      int mgmt_group_cipher;
  }wpa_ie_data_t;
  
  typedef struct rsn_ie_hdr
  {
      //u8 elem_id; /* WLAN_EID_RSN */    //Element Header
      //u8 len;
      u8 version[2]; /* little endian */
  } rsn_ie_hdr_t;
  
  typedef struct wpa_ie_hdr {
  	//u8 elem_id;
  	//u8 len;
  	u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */
  	u8 version[2]; /* little endian */
  } wpa_ie_hdr_t;
  
  typedef struct //wpa_ssid
  {
  	/**
  	 * psk - WPA pre-shared key (256 bits)
  	 */
  	u8 psk[32];
  
  	/**
  	 * psk_set - Whether PSK field is configured
  	 */
  	int psk_set;
  
  	/**
  	 * passphrase - WPA ASCII passphrase
  	 *
  	 * If this is set, psk will be generated using the SSID and passphrase
  	 * configured for the network. ASCII passphrase must be between 8 and
  	 * 63 characters (inclusive).
  	 */
  	char *passphrase;
  
  	/**
  	 * pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
  	 */
  	int pairwise_cipher;
  
  	/**
  	 * group_cipher - Bitfield of allowed group ciphers, WPA_CIPHER_*
  	 */
  	int group_cipher;
  
  	/**
  	 * key_mgmt - Bitfield of allowed key management protocols
  	 *
  	 * WPA_KEY_MGMT_*
  	 */
  	int key_mgmt;
  
  	int mgmt_group_cipher;	//for 802.11w?
  	/**
  	 * proto - Bitfield of allowed protocols, WPA_PROTO_*
  	 */
  	int proto;
  
  #if 1//def IEEE8021X_EAPOL
  #define EAPOL_FLAG_REQUIRE_KEY_UNICAST BIT(0)
  #define EAPOL_FLAG_REQUIRE_KEY_BROADCAST BIT(1)
  	/**
  	 * eapol_flags - Bit field of IEEE 802.1X/EAPOL options (EAPOL_FLAG_*)
  	 */
  	int eapol_flags;
  
  	/**
  	 * eap - EAP peer configuration for this network
  	 */
  	//struct eap_peer_config eap;
  	/**
  	 * leap - Number of EAP methods using LEAP
  	 *
  	 * This field should be set to 1 if LEAP is enabled. This is used to
  	 * select IEEE 802.11 authentication algorithm.
  	 */
  	int leap;
  
  	/**
  	 * non_leap - Number of EAP methods not using LEAP
  	 *
  	 * This field should be set to >0 if any EAP method other than LEAP is
  	 * enabled. This is used to select IEEE 802.11 authentication
  	 * algorithm.
  	 */
  	int non_leap;
  
  	/**
  	 * eap_workaround - EAP workarounds enabled
  	 *
  	 * wpa_supplicant supports number of "EAP workarounds" to work around
  	 * interoperability issues with incorrectly behaving authentication
  	 * servers. This is recommended to be enabled by default because some
  	 * of the issues are present in large number of authentication servers.
  	 *
  	 * Strict EAP conformance mode can be configured by disabling
  	 * workarounds with eap_workaround = 0.
  	 */
  	unsigned int eap_workaround;
  
  
  #endif /* IEEE8021X_EAPOL */
  
  }wpa_ssid_t;
  
  typedef struct
  {
      //u8 * frame_buffer;
      u8 frame_buffer[ETH_P_EAPOL_LEN];
      uint32_t frame_length;
  }rx_eapol_report;
  
  extern wpa_ssid_t g_wpa_info;
  
  int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, wpa_ie_data_t *data);
  int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, wpa_ie_data_t *data);
  void wifi_sta_data_eapol(u8 *buf, u16 len);
  int wpa_supplicant_set_suites(u8 *bssid, u8 *wpa_ie, u8 *wpa_ie_len);
  s32 wifi_data_route_switch(u8 path);
  
  
  #endif /* _WIFI_WPA_RSNE_H_ */
  
  