--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/eapol_common/include/eapol_key_state.h Thu Dec 17 08:47:43 2009 +0200
@@ -0,0 +1,981 @@
+/*
+* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: EAP and WLAN authentication protocols.
+*
+*/
+
+
+
+
+#if !defined(_EAPOL_KEY_STATE_H_)
+#define _EAPOL_KEY_STATE_H_
+
+
+#include "eap_tools.h"
+#include "eap_am_export.h"
+#include "eapol_rsna_key_data_header.h"
+#include "eapol_rsna_key_header.h"
+#include "eap_am_network_id.h"
+#include "eapol_key_types.h"
+
+class abs_eapol_core_c;
+class abs_eapol_key_state_c;
+class eapol_rsna_key_data_payloads_c;
+class eap_core_retransmission_c;
+
+
+#if defined(EAPOL_KEY_TEST_PRIVATE_FUNCTION)
+#define EAP_KEY_TEST_PUBLIC_FUNCTION public:
+#define EAP_KEY_TEST_PRIVATE_FUNCTION private:
+#else
+#define EAP_KEY_TEST_PUBLIC_FUNCTION
+#define EAP_KEY_TEST_PRIVATE_FUNCTION
+#endif // #if defined(EAPOL_KEY_TEST_PRIVATE_FUNCTION)
+
+/** @file */
+
+/**
+ * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer().
+ */
+enum eapol_key_state_timer_id_e
+{
+ EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT.
+ EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, ///< See EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT.
+ EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_PMK_CACHING_TIMEOUT.
+ EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT.
+ EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT.
+ EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT.
+};
+
+/**
+ * These are the default timeout values.
+ */
+enum eapol_key_state_timer_timeout_value_e
+{
+ EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT = 20000ul, // milli seconds
+ EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT = 2000ul, // milli seconds
+ EAPOL_KEY_STATE_RETRANSMISSION_COUNTER = 3ul,
+ EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT = 43200000ul, // milli seconds = 12 hours
+ EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT = 500ul, // milli seconds
+ EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT = 0ul, // milli seconds, this is for testing, zero means in test case group key is updated immediately.
+ EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT = 100ul, // milli seconds before client initializes 4-Way Handshake.
+ EAPOL_KEY_STATE_TIMER_WPXM_CACHE_TIMEOUT = 1000ul, // milli seconds, This is short timeout to remove WPXM SA.
+};
+
+
+const u8_t EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL[] = "Pairwise key expansion";
+const u32_t EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL_LENGTH = (sizeof(EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL) - 1ul); // Terminating null is not included.
+
+const u8_t EAPOL_RSNA_PMK_NAME_LABEL[] = "PMK Name";
+const u32_t EAPOL_RSNA_PMK_NAME_LABEL_LENGTH = (sizeof(EAPOL_RSNA_PMK_NAME_LABEL) - 1ul); // Terminating null is not included.
+
+enum eapol_key_wpxm_constant_e
+{
+ eapol_key_constant_wpxm_initial_wpxc_counter_value = 1,
+};
+
+
+//--------------------------------------------------------------------------------------------------
+
+
+/// Class eapol_key_state_c
+/**
+ * This class stores the EAPOL-Key state.
+ */
+class EAP_EXPORT eapol_key_state_c
+: public abs_eap_base_timer_c
+{
+
+public:
+ //--------------------------------------------------
+
+ //--------------------------------------------------
+private:
+ //--------------------------------------------------
+
+ /// This is pointer to the tools class.
+ abs_eap_am_tools_c * const m_am_tools;
+
+ /// This is back pointer to object which created this object.
+ /// Packets are sent to the partner.
+ abs_eapol_key_state_c * const m_key_state_partner;
+
+ /// This is back pointer to object which created eapol_core_c object.
+ /// eapol_key_state_c object sent packets to this object.
+ abs_eapol_core_c * const m_eapol_partner;
+
+ eap_am_network_id_c m_send_network_id;
+
+ /// Authenticator RSN IE. Authenticator sends this in Beacon or Probe message.
+ eap_variable_data_c m_authenticator_RSNA_IE;
+
+ /// If a second RSN IE is provided in the message, the Supplicant shall use
+ // the unicast cipher suite specified in the second RSN IE or deauthenticate.
+ eap_variable_data_c m_unicast_cipher_suite_RSNA_IE;
+
+ /// Supplicant RSN IE. Supplicant sends this in (re)association request message.
+ eap_variable_data_c m_supplicant_RSNA_IE;
+
+ /// Received Pairwise Master Key ID (PMKID). Authenticator sends this in 4-Way Handshake message 1.
+ eap_variable_data_c m_received_PMKID;
+
+ /// This is Supplicant's MAC address. This is given from MAC layer when EAPOL-Key state is initialized.
+ eap_variable_data_c m_supplicant_MAC_address;
+
+ /// This is Authenticator's MAC address. This is given from MAC layer when EAPOL-Key state is initialized.
+ eap_variable_data_c m_authenticator_MAC_address;
+
+ /// This is Athenticator Nonce.
+ eap_variable_data_c m_ANonce;
+
+ /// This is Supplicant Nonce.
+ eap_variable_data_c m_SNonce;
+
+ /// This is EAPOL-Key IV.
+ eap_variable_data_c m_EAPOL_key_IV;
+
+ /// This is the Pairwise Master Key (PMK 802.11i or WPXK3 WPXM) derived from a successful authentication.
+ eap_variable_data_c m_pairwise_PMK_WPXK3;
+
+ /// Pairwise Master Key ID (PMKID). Derived with function:
+ /// PMKID = HMAC-SHA1-128(PMK, "PMK Name" || Authenticator-MAC-Addr || Supplicant-MAC-Addr).
+ eap_variable_data_c m_PMKID;
+
+ /// Pairwise Transient Key (PTK).
+ /// PTK = PRF-X(PMK, "Pairwise key expansion", Min(AA,SA) || Max(AA, SA) || Min(ANonce,SNonce) || Max(ANonce,SNonce)).
+ eap_variable_data_c m_transient_PTK;
+
+ /// EAPOL-Key Confirmation Key (KCK).
+ /// KCK = L(PTK, 0, 128).
+ eap_variable_data_c m_confirmation_KCK;
+
+ /// EAPOL-Key Encryption Key (KEK).
+ /// KEK = L(PTK, 128, 128).
+ eap_variable_data_c m_encryption_KEK;
+
+ /// Temporal Key (TK).
+ /// In TKIP: TK = L(PTK, 256, 256).
+ /// In CCMP: TK = L(PTK, 256, 128).
+ eap_variable_data_c m_temporal_TK;
+
+ /// Group Temporal Key (GTK).
+ /// In TKIP: 256 bits.
+ /// In CCMP: 128 bits.
+ /// In WEP 40: 40 bits.
+ /// In WEP 104: 104 bits.
+ eap_variable_data_c m_group_GTK;
+
+#if defined(EAP_USE_WPXM)
+ eap_variable_data_c m_WPXM_WPXK1;
+ eap_variable_data_c m_WPXM_WPXK2;
+
+ u32_t m_WPXM_WPXC;
+#endif //#if defined(EAP_USE_WPXM)
+
+ bool m_received_802_1x_keys[eapol_key_type_last_type];
+
+ u8_t m_group_GTK_ID;
+
+ bool m_group_GTK_Tx_bit;
+
+ u32_t m_eapol_header_offset;
+
+ u32_t m_MTU;
+
+ u32_t m_trailer_length;
+
+ /// Re-transmission is used to test protocols.
+ /// This stores the information to resent a message. This is used for testing purposes.
+ eap_core_retransmission_c *m_retransmission;
+
+ /// Re-transmission is used to test protocols.
+ /// This is the time after resent a message. This is used for testing purposes.
+ u32_t m_retransmission_time;
+
+ /// Re-transmission is used to test protocols.
+ /// This is the maximum count of retransmission of one message. This is used for testing purposes.
+ u32_t m_retransmission_counter;
+
+ /// This is the maximum time EAPOL-Key Handshake could succeed.
+ /// EAPOl-Key Handshake is terminated after this time elapses.
+ u32_t m_handshake_timeout;
+
+
+#if defined(EAP_USE_WPXM)
+
+ /// This is the maximum time WPXM reassociation could succeed.
+ /// WPXM reassociation is terminated after this time elapses.
+ u32_t m_wpxm_reassociate_timeout;
+
+ /// This is used in test server. WPXM can be configured to to use RSNA or WPA Key descriptor.
+ eapol_key_descriptor_type_e m_EAPOL_WPXM_key_descriptor_type;
+
+#endif //#if defined(EAP_USE_WPXM)
+
+ /// This is the authentication type. One of RSNA, WPA or 802.1X.
+ eapol_key_authentication_type_e m_authentication_type;
+
+ /// This is the selected pairwise cipher.
+ eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_eapol_pairwise_cipher;
+
+ /// This is the selected group cipher.
+ eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_eapol_group_cipher;
+
+ /// This is the state of EAPOL-Key Handshake.
+ eapol_key_state_e m_eapol_key_state;
+
+ /// This is the the current running handshake type.
+ eapol_key_handshake_type_e m_eapol_key_handshake_type;
+
+ /// This used in EAPOL key MIC failure tests. Activation requires USE_EAPOL_KEY_TEST_FAILURES compiler flag.
+ eapol_key_state_e m_create_key_failure;
+
+ u32_t m_pmksa_caching_timeout;
+
+ /// This is Key Reply Counter.
+ u64_t m_key_reply_counter;
+
+ /// This is Key Reply Counter for requests that client sends.
+ u64_t m_client_send_key_reply_counter;
+
+ /// This indicates whether this object is client (true) or server (false).
+ /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false).
+ bool m_is_client;
+
+ /// This indicates whether this object was generated successfully.
+ bool m_is_valid;
+
+ /// This flag indicates that this object is marked to removed asynchronously.
+ /// The very same object could be taken use before the removing timer elapses.
+ bool m_marked_removed;
+
+ bool m_shutdown_was_called;
+
+ /// This flag tells whether broken 4-Way Handshake message 1 without PMKID is allowed (true) or dropped (false).
+ /// Default value id false.
+ /// Use configuration option EAPOL_key_state_allow_missing_PMKID_in_message_1 to change this value.
+ bool m_allow_missing_PMKID_in_message_1;
+
+ /// This flag tells whether broken 4-Way Handshake message 1 without PMKID is created in server (true) or not (false).
+ /// Default value id false.
+ /// Use configuration option EAPOL_key_state_skip_PMKID_key_data_in_message_1 to change this value.
+ bool m_skip_PMKID_key_data_in_message_1;
+
+ /// This flag tells whether broken 4-Way Handshake message 1 with non zero MIC or non zero reserved is allowed (true) or dropped (false).
+ /// Default value id false.
+ /// Use configuration option EAPOL_key_state_allow_non_zero_mic_in_message_1 to change this value.
+ bool m_allow_non_zero_mic_and_reserved_in_message_1;
+
+ /// This flag tells the EAPOL must indicate PMKID to lower layers (true) or not (false).
+ /// The configuration option is EAPOL_key_state_indicate_pmkid_to_lower_layer.
+ bool m_indicate_pmkid_to_lower_layer;
+
+ /// This flag tells the handshake timeout is already active (true) or not (false).
+ bool m_handshake_timeout_set;
+
+ /// This flag activates group key update test (true) or not (false).
+ /// The configuration option is EAPOL_key_state_TEST_group_key_update.
+ bool m_server_TEST_group_key_update;
+
+#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
+ bool m_is_associated;
+#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
+
+ // - - - - - - - - - - - - - - - - - - - - - - - -
+
+ enum eapol_key_state_constants_e
+ {
+ eapol_key_state_mppe_key_length_leap = 16ul, // LEAP gives only 16 bytes of key material
+ eapol_key_state_mppe_key_length = 32ul,
+ EAPOL_RSNA_PMK_LENGTH_BYTES = 32ul,
+ EAPOL_RSNA_NONCE_LENGTH_BYTES = 32ul,
+ EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES = eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH
+ + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE, // sizeof(Key Data Encapsulation header) 6 + sizeof(PMKID) 16
+ EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH = 256ul,
+ EAPOL_RSNA_TKIP_PTK_LENGTH_BITS = 512ul,
+ EAPOL_RSNA_CCMP_PTK_LENGTH_BITS = 384ul,
+ EAPOL_RSNA_KCK_LENGTH_BYTES = 16ul,
+ EAPOL_RSNA_KEK_LENGTH_BYTES = 16ul,
+ EAPOL_RSNA_TK_LENGTH_BYTES = 32ul,
+ EAPOL_RSNA_TKIP_TK_LENGTH_BYTES = 32ul,
+ EAPOL_RSNA_CCMP_TK_LENGTH_BYTES = 16ul,
+ EAPOL_RSNA_KCK_OFFSET_BYTES = 0ul,
+ EAPOL_RSNA_KEK_OFFSET_BYTES = EAPOL_RSNA_KCK_OFFSET_BYTES + EAPOL_RSNA_KCK_LENGTH_BYTES,
+ EAPOL_RSNA_TK_OFFSET_BYTES = EAPOL_RSNA_KEK_OFFSET_BYTES + EAPOL_RSNA_KEK_LENGTH_BYTES,
+ };
+
+
+ EAP_FUNC_IMPORT eap_status_e trace_eapol_key_message(
+ const i8_t * const prefix,
+ eapol_RSNA_key_header_c * const eapol_key_message);
+
+ eap_status_e trace_eapol_rsna_key_data_payload(
+ const bool is_RSNA,
+ const bool is_WPXM,
+ const eapol_key_descriptor_type_e eapol_key_descriptor_type,
+ const i8_t * const prefix,
+ const eapol_rsna_key_data_header_c * const key_data_payload,
+ const u32_t buffer_length);
+
+#if defined(USE_EAP_TRACE)
+
+ #define TRACE_EAPOL_KEY_MESSAGE(prefix, eapol_key_message) \
+ trace_eapol_key_message(prefix, eapol_key_message)
+
+ #define EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(is_RSNA, is_WPXM, eapol_key_descriptor_type, prefix, key_data_payload, buffer_length) \
+ trace_eapol_rsna_key_data_payload(is_RSNA, is_WPXM, eapol_key_descriptor_type, prefix, key_data_payload, buffer_length)
+
+#else
+
+ #define TRACE_EAPOL_KEY_MESSAGE(prefix, eapol_key_message)
+
+ #define EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(is_RSNA, is_WPXM, eapol_key_descriptor_type, prefix, key_data_payload, buffer_length)
+
+#endif //#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS)
+
+
+ eap_status_e handshake_failure_notification();
+
+ eap_status_e set_mac_addresses(
+ const eap_am_network_id_c * const receive_network_id);
+
+ EAP_FUNC_IMPORT eap_status_e save_parameters(
+ const eapol_key_authentication_type_e authentication_type,
+ const eap_variable_data_c * const authenticator_RSNA_IE,
+ const eap_variable_data_c * const supplicant_RSNA_IE,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher);
+
+ eap_status_e packet_data_session_key(
+ eap_variable_data_c * const key, ///< Here is the key.
+ const eapol_key_type_e key_type, ///< This the type of the key.
+ const u32_t key_index, ///< This is the index of the key.
+ const bool key_tx_bit, ///< This is the TX bit of the key.
+ const u8_t * const key_RSC, ///< This is the RSC counter
+ const u32_t key_RSC_size ///< This is the size of RSC counter
+ );
+
+ EAP_FUNC_IMPORT eap_status_e check_is_aes_key_wrap_padding(
+ const eapol_RSNA_key_descriptor_type_e current_key_data_type,
+ eapol_rsna_key_data_header_c * const key_data_payload,
+ const u32_t key_data_max_length
+ );
+
+ EAP_FUNC_IMPORT eap_status_e parse_generic_key_data_payload(
+ const eapol_key_descriptor_type_e key_descriptor_type,
+ const eapol_RSNA_key_descriptor_type_e current_key_data_payload,
+ eapol_rsna_key_data_header_c * const key_data_payload,
+ u32_t * const key_data_max_length,
+ eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads,
+ const eapol_key_state_e expected_key_message);
+
+ EAP_FUNC_IMPORT eap_status_e parse_key_data(
+ const eapol_key_descriptor_type_e key_descriptor_type,
+ const eapol_rsna_key_data_header_c * const p_payload,
+ u32_t * const buffer_length,
+ eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads,
+ const eapol_key_state_e expected_key_message,
+ const eapol_RSNA_key_header_c::key_descriptor_version_e key_descriptor_version);
+
+ EAP_FUNC_IMPORT eap_status_e rsna_prf(
+ const eap_variable_data_c * const key_K,
+ const eap_variable_data_c * const label_A,
+ const eap_variable_data_c * const input_B,
+ const u32_t output_length,
+ eap_variable_data_c * const output
+ );
+
+ EAP_FUNC_IMPORT eap_status_e select_minimum(
+ const eap_variable_data_c * const input_a,
+ const eap_variable_data_c * const input_b,
+ const eap_variable_data_c ** const minimum,
+ const eap_variable_data_c ** const maximum);
+
+
+ EAP_FUNC_IMPORT eap_status_e create_PMKID();
+
+ eap_status_e set_reassociation_parameters(
+ const eap_variable_data_c * const pairwise_PMK_WPXK3,
+ const eap_variable_data_c * const PMKID,
+ const eap_variable_data_c * const transient_PTK,
+ const eap_variable_data_c * const confirmation_KCK,
+ const eap_variable_data_c * const encryption_KEK,
+ const eap_variable_data_c * const temporal_TK,
+ const eap_variable_data_c * const WPXM_WPXK1,
+ const eap_variable_data_c * const WPXM_WPXK2,
+ const u32_t WPXM_WPXC,
+ const eapol_key_handshake_type_e eapol_key_handshake_type,
+ const eapol_key_authentication_type_e authentication_type
+ );
+
+ eap_status_e send_RC4_eapol_key_message(
+ const eapol_RC4_key_flags_e flags);
+
+ void send_error_notification(const eap_status_e error);
+
+ eap_status_e save_keys_for_test_use(
+ const eap_variable_data_c * const confirmation_KCK,
+ const eap_variable_data_c * const encryption_KEK,
+ const eap_variable_data_c * const temporal_TK,
+ const u32_t WPXM_WPXC);
+
+EAP_KEY_TEST_PUBLIC_FUNCTION
+
+
+ EAP_FUNC_IMPORT eap_status_e derive_PTK();
+
+
+EAP_KEY_TEST_PRIVATE_FUNCTION
+
+
+ EAP_FUNC_IMPORT eap_status_e derive_WPXM_WPXK1_WPXK2();
+
+ EAP_FUNC_IMPORT eap_status_e derive_WPXM_PTK(const u32_t WPXM_WPXC);
+
+ EAP_FUNC_IMPORT eap_status_e verify_field_is_zero(
+ const u8_t * const field,
+ const u32_t field_length);
+
+ EAP_FUNC_IMPORT eap_status_e encrypt_key_data(
+ eapol_RSNA_key_header_c * const eapol_key_message);
+
+ EAP_FUNC_IMPORT eap_status_e decrypt_key_data(
+ eapol_RSNA_key_header_c * const eapol_key_message);
+
+
+ EAP_FUNC_IMPORT eap_status_e create_key_mic(
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const eap_variable_data_c * const confirmation_key);
+
+ EAP_FUNC_IMPORT eap_status_e verify_key_mic(
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const eap_variable_data_c * const confirmation_key);
+
+
+ EAP_FUNC_IMPORT eap_status_e create_nonce(
+ eap_variable_data_c * const nonce,
+ const u32_t nonce_length);
+
+ EAP_FUNC_IMPORT eap_status_e initialize_4_way_handshake(
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_protocol_version_e received_eapol_version);
+
+ EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_1(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+ EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_2(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const u64_t received_key_replay_counter,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+ EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_3(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+ EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_4(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const u64_t received_key_replay_counter,
+ const bool received_secure_bit,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_2_payloads(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_3_payloads_a(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length,
+ bool * const group_key_received);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_3_payloads_b(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length,
+ const bool group_key_received);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_0(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_1(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_2(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_3(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_4(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+
+ EAP_FUNC_IMPORT eap_status_e start_group_key_handshake(
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+ EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message_0(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message_1(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message_2(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+
+ EAP_FUNC_IMPORT eap_status_e create_eapol_key_handshake_message_0(
+ const bool true_when_4_way_handshake, ///< With false initiates Group Key Handshake.
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const u64_t received_key_replay_counter,
+ const eapol_protocol_version_e received_eapol_version);
+
+ EAP_FUNC_IMPORT eap_status_e create_group_key_handshake_message_1(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+ EAP_FUNC_IMPORT eap_status_e create_group_key_handshake_message_2(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const u64_t received_key_replay_counter,
+ const eapol_protocol_version_e received_eapol_version,
+ const eapol_key_descriptor_type_e received_key_descriptor_type);
+
+
+ EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message(
+ const eap_am_network_id_c * const receive_network_id,
+ eapol_RSNA_key_header_c * const eapol_key_message,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_RSNA_key_descriptor(
+ const eap_am_network_id_c * const receive_network_id,
+ eap_general_header_base_c * const packet_data,
+ const u32_t packet_length);
+
+ EAP_FUNC_IMPORT eap_status_e process_RC4_key_descriptor(
+ const eap_am_network_id_c * const receive_network_id,
+ eap_general_header_base_c * const packet_data,
+ const u32_t packet_length);
+
+ // This is documented in abs_eap_stack_interface_c::set_is_valid().
+ EAP_FUNC_IMPORT void set_is_valid();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_authenticator_RSNA_IE();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_unicast_cipher_suite_RSNA_IE();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_supplicant_RSNA_IE();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_received_PMKID();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_supplicant_MAC_address();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_authenticator_MAC_address();
+
+ //
+ EAP_FUNC_IMPORT u64_t get_key_reply_counter();
+
+ //
+ EAP_FUNC_IMPORT void increase_key_reply_counter();
+
+ //
+ EAP_FUNC_IMPORT void set_key_reply_counter(
+ const u64_t reply_counter);
+
+ //
+ EAP_FUNC_IMPORT u64_t get_client_send_key_reply_counter();
+
+ //
+ EAP_FUNC_IMPORT void increase_client_send_key_reply_counter();
+
+ //
+ EAP_FUNC_IMPORT void set_client_send_key_reply_counter(
+ const u64_t reply_counter);
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_ANonce();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_SNonce();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_confirmation_KCK();
+
+ //
+ EAP_FUNC_IMPORT eap_variable_data_c * get_encryption_KEK();
+
+ //
+ EAP_FUNC_IMPORT void set_eapol_key_state(const eapol_key_state_e state);
+
+ //
+ EAP_FUNC_IMPORT eapol_key_state_e get_eapol_key_state() const;
+
+ EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eapol_key_state();
+
+ //
+ EAP_FUNC_IMPORT eap_status_e packet_send(
+ const eap_am_network_id_c * const send_network_id,
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t header_offset,
+ const u32_t data_length,
+ const u32_t buffer_length);
+
+ //
+ EAP_FUNC_IMPORT eap_status_e resend_packet(
+ const eap_am_network_id_c * const send_network_id,
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t header_offset,
+ const u32_t data_length,
+ const u32_t buffer_length);
+
+ //
+ EAP_FUNC_IMPORT eap_status_e cancel_retransmission();
+
+
+ //
+ EAP_FUNC_IMPORT eap_status_e cancel_handshake_timeout();
+
+ //
+ EAP_FUNC_IMPORT eap_status_e init_handshake_timeout(
+ const u32_t timeout);
+
+
+ //
+ eap_status_e cancel_reassociate_timeout();
+
+ //
+ eap_status_e init_reassociate_timeout(
+ const u32_t timeout);
+
+
+ eap_status_e cancel_4_way_handshake_start_timeout();
+
+ eap_status_e init_4_way_handshake_start_timeout();
+
+ //
+ EAP_FUNC_IMPORT eap_status_e cancel_pmksa_caching_timeout();
+
+ //
+ EAP_FUNC_IMPORT eap_status_e init_retransmission(
+ const eap_am_network_id_c * const send_network_id,
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t header_offset,
+ const u32_t data_length,
+ const eap_code_value_e eap_code,
+ const u8_t eap_identifier,
+ const eap_type_value_e eap_type
+ );
+
+ EAP_FUNC_IMPORT eap_status_e cancel_group_key_update_timeout();
+
+ EAP_FUNC_IMPORT eap_status_e init_group_key_update_timeout(
+ const u32_t timeout);
+
+ //
+ EAP_FUNC_IMPORT eap_status_e create_tkip_mic_failure_message(
+ eap_buf_chain_wr_c * const sent_packet,
+ const u32_t eapol_header_offset,
+ u32_t * const data_length,
+ u32_t * const buffer_length,
+ const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type,
+ const eapol_protocol_version_e received_eapol_version);
+
+
+ EAP_FUNC_IMPORT bool get_is_RSNA();
+
+ EAP_FUNC_IMPORT bool get_is_WPA();
+
+ EAP_FUNC_IMPORT bool get_is_WPXM();
+
+
+ EAP_FUNC_IMPORT eap_status_e add_RSN_GTK_payload(
+ const eapol_RSNA_key_header_c * const eapol_key_message,
+ eap_variable_data_c * const group_GTK,
+ u32_t * const eapol_data_length);
+
+ EAP_FUNC_IMPORT eap_status_e add_RSN_IE_payload(
+ const eapol_RSNA_key_header_c * const eapol_key_message,
+ eap_variable_data_c * const RSNA_IE,
+ u32_t * const eapol_data_length);
+
+ EAP_FUNC_IMPORT eap_status_e get_key_length(
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e cipher,
+ u16_t * const key_length);
+
+ EAP_FUNC_IMPORT eap_status_e send_RC4_eapol_key_messages();
+
+ //--------------------------------------------------
+protected:
+ //--------------------------------------------------
+
+ //--------------------------------------------------
+public:
+ //--------------------------------------------------
+
+ //
+ EAP_FUNC_IMPORT virtual ~eapol_key_state_c();
+
+ //
+ EAP_FUNC_IMPORT eapol_key_state_c(
+ abs_eap_am_tools_c * const tools,
+ abs_eapol_key_state_c * const key_state_partner,
+ abs_eapol_core_c * const eapol_partner,
+ const bool is_client_when_true,
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type,
+ const eap_variable_data_c * const authenticator_RSNA_IE,
+ const eap_variable_data_c * const supplicant_RSNA_IE,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
+ const eap_variable_data_c * const pre_shared_key);
+
+ //
+ EAP_FUNC_IMPORT eapol_key_state_c(
+ abs_eap_am_tools_c * const tools,
+ abs_eapol_key_state_c * const key_state_partner,
+ abs_eapol_core_c * const eapol_partner,
+ const bool is_client_when_true,
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type);
+
+
+ EAP_FUNC_IMPORT eap_status_e initialize(
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type,
+ const eap_variable_data_c * const authenticator_RSNA_IE,
+ const eap_variable_data_c * const supplicant_RSNA_IE,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
+ const eap_variable_data_c * const pre_shared_key);
+
+#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
+
+ EAP_FUNC_IMPORT eap_status_e initialize(
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type);
+
+#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
+
+ EAP_FUNC_IMPORT eapol_key_state_c *copy(const eap_am_network_id_c * const receive_network_id);
+
+ EAP_FUNC_IMPORT bool get_is_encryption_on();
+
+
+#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
+
+ EAP_FUNC_IMPORT bool get_is_associated();
+
+#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
+
+
+ //
+ EAP_FUNC_IMPORT eap_status_e started_eap_authentication();
+
+ /**
+ * This function checks whether cached PMKSA have correct cipher suite.
+ */
+ EAP_FUNC_IMPORT eap_status_e check_pmksa_cache(
+ const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+ EAP_FUNC_IMPORT eap_status_e initialize_preauthentication(
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type);
+
+ EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters(
+ const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+ const eapol_key_authentication_type_e authentication_type,
+ eap_variable_data_c * const PMKID,
+ const eap_variable_data_c * const received_WPA_ie,
+ const eap_variable_data_c * const sent_WPA_ie);
+
+ EAP_FUNC_IMPORT eap_status_e complete_reassociation(
+ const eapol_wlan_authentication_state_e reassociation_result,
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type,
+ const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL
+ const eap_variable_data_c * const sent_WPA_IE,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+ const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+ EAP_FUNC_IMPORT eap_status_e start_WPXM_reassociation(
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type,
+ eap_variable_data_c * const send_reassociation_request_ie);
+
+ EAP_FUNC_IMPORT eap_status_e complete_WPXM_reassociation(
+ const eapol_wlan_authentication_state_e reassociation_result,
+ const eap_am_network_id_c * const receive_network_id,
+ const eapol_key_authentication_type_e authentication_type,
+ const eap_variable_data_c * const received_reassociation_ie);
+
+ EAP_FUNC_IMPORT eap_status_e configure();
+
+ EAP_FUNC_IMPORT eap_status_e shutdown();
+
+ EAP_FUNC_IMPORT eap_status_e set_WPXM_parameters(
+ const eap_am_network_id_c * const receive_network_id);
+
+ EAP_FUNC_IMPORT eap_status_e set_s_nonce(
+ const eap_variable_data_c * const s_nonce);
+
+ EAP_FUNC_IMPORT eap_status_e set_pairwise_PMK(
+ const eap_variable_data_c * const key,
+ const eap_am_network_id_c * const send_network_id);
+
+ EAP_FUNC_IMPORT eap_status_e allow_4_way_handshake();
+
+ EAP_FUNC_IMPORT eap_status_e start_4_way_handshake(
+ const eap_am_network_id_c * const receive_network_id);
+
+ //
+ EAP_FUNC_IMPORT eap_status_e process_eapol_key_frame(
+ const eap_am_network_id_c * const receive_network_id,
+ eap_general_header_base_c * const packet_data,
+ const u32_t packet_length);
+
+ // This is documented in abs_eap_stack_interface_c::get_is_valid().
+ EAP_FUNC_IMPORT bool get_is_valid();
+
+ /**
+ * The object_increase_reference_count() function increases the reference count.
+ */
+ EAP_FUNC_IMPORT void object_increase_reference_count();
+
+ /**
+ * The object_decrease_reference_count () function decreases
+ * the reference count and returns the remaining value.
+ * The EAP type is removed after there is no references to it.
+ */
+ EAP_FUNC_IMPORT u32_t object_decrease_reference_count();
+
+ // See abs_eap_base_timer_c::timer_expired().
+ EAP_FUNC_IMPORT eap_status_e timer_expired(
+ const u32_t id, void *data);
+
+ // See abs_eap_base_timer_c::timer_delete_data().
+ EAP_FUNC_IMPORT eap_status_e timer_delete_data(
+ const u32_t id, void *data);
+
+ /**
+ * Gets flag whether this session is marked removed.
+ * Session is removed later if it is not reused.
+ */
+ EAP_FUNC_IMPORT bool get_marked_removed();
+
+ /**
+ * Marks this session removed.
+ * Session is removed later if it is not reused.
+ */
+ EAP_FUNC_IMPORT void set_marked_removed();
+
+ /**
+ * Marks this session not removed.
+ * Session is not removed it is reused.
+ */
+ EAP_FUNC_IMPORT void unset_marked_removed();
+
+ /**
+ * This function resets object partially.
+ * Member attributes needed in reassociation are left untouched.
+ */
+ EAP_FUNC_IMPORT eap_status_e reset_cached_pmksa();
+
+ /**
+ * This function resets the full state of object to same as
+ * state was after the configure() function call.
+ * If object reset succeeds this function must return eap_status_ok.
+ * If object reset fails this function must return corresponding error status.
+ * @return This function returns the status of reset operation.
+ */
+ EAP_FUNC_IMPORT eap_status_e reset();
+
+ EAP_FUNC_IMPORT eap_status_e tkip_mic_failure(
+ const bool fatal_failure_when_true,
+ const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type);
+
+ //
+ EAP_FUNC_IMPORT eap_status_e init_pmksa_caching_timeout();
+
+ //
+ EAP_FUNC_IMPORT eap_status_e cancel_authentication_session();
+
+ //--------------------------------------------------
+}; // class eapol_key_state_c
+
+
+//--------------------------------------------------
+
+#endif //#if !defined(_EAPOL_KEY_STATE_H_)
+
+//--------------------------------------------------
+
+
+// End.