/*
* 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.
*
*/
/*
* %version: 14.1.4 %
*/
#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.