diff --git a/Makefile.am b/Makefile.am index 9f80b005..1575f037 100644 --- a/Makefile.am +++ b/Makefile.am @@ -112,6 +112,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \ src/dbus.h src/dbus.c \ src/mpdu.h src/mpdu.c \ src/eapol.h src/eapol.c \ + src/eapolutil.h src/eapolutil.c \ src/handshake.h src/handshake.c \ src/scan.h src/scan.c \ src/common.h src/common.c \ @@ -187,10 +188,8 @@ monitor_iwmon_SOURCES = monitor/main.c linux/nl80211.h \ src/util.h src/util.c \ src/crypto.h src/crypto.c \ src/watchlist.h src/watchlist.c \ - src/eapol.h src/eapol.c \ - src/handshake.h src/handshake.c \ - src/eap.h src/eap.c src/eap-private.h \ - src/eap-dummy.c + src/eapolutil.h src/eapolutil.c \ + src/handshake.h src/handshake.c monitor_iwmon_LDADD = ell/libell-internal.la endif @@ -258,6 +257,7 @@ unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \ src/ie.h src/ie.c \ src/watchlist.h src/watchlist.c \ src/eapol.h src/eapol.c \ + src/eapolutil.h src/eapolutil.c \ src/handshake.h src/handshake.c \ src/eap.h src/eap.c src/eap-private.h \ src/util.h src/util.c \ @@ -312,6 +312,7 @@ unit_test_eapol_SOURCES = unit/test-eapol.c \ src/ie.h src/ie.c \ src/watchlist.h src/watchlist.c \ src/eapol.h src/eapol.c \ + src/eapolutil.h src/eapolutil.c \ src/handshake.h src/handshake.c \ src/eap.h src/eap.c src/eap-private.h \ src/eap-tls.c src/eap-ttls.c \ @@ -331,6 +332,7 @@ unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \ src/ie.h src/ie.c \ src/watchlist.h src/watchlist.c \ src/eapol.h src/eapol.c \ + src/eapolutil.h src/eapolutil.c \ src/handshake.h src/handshake.c \ src/eap.h src/eap.c src/eap-private.h \ src/util.h src/util.c \ diff --git a/src/eap-dummy.c b/src/eap-dummy.c deleted file mode 100644 index df1da2af..00000000 --- a/src/eap-dummy.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Wireless daemon for Linux - * - * Copyright (C) 2016 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "eap.h" -#include "eap-private.h" - -static int eap_dummy_init(void) -{ - return 0; -} - -static void eap_dummy_exit(void) -{ -} - -EAP_METHOD_BUILTIN(eap_dummy, eap_dummy_init, eap_dummy_exit) diff --git a/src/eapol.c b/src/eapol.c index 9a3d43f7..e3ee8662 100644 --- a/src/eapol.c +++ b/src/eapol.c @@ -273,53 +273,6 @@ void eapol_key_data_append(struct eapol_key *ek, enum handshake_kde selector, ek->key_data_len = L_CPU_TO_BE16(key_data_len); } -const struct eapol_key *eapol_key_validate(const uint8_t *frame, size_t len) -{ - const struct eapol_key *ek; - uint16_t key_data_len; - - if (len < sizeof(struct eapol_key)) - return NULL; - - ek = (const struct eapol_key *) frame; - - switch (ek->header.protocol_version) { - case EAPOL_PROTOCOL_VERSION_2001: - case EAPOL_PROTOCOL_VERSION_2004: - break; - default: - return NULL; - } - - if (ek->header.packet_type != 3) - return NULL; - - switch (ek->descriptor_type) { - case EAPOL_DESCRIPTOR_TYPE_RC4: - case EAPOL_DESCRIPTOR_TYPE_80211: - case EAPOL_DESCRIPTOR_TYPE_WPA: - break; - default: - return NULL; - } - - switch (ek->key_descriptor_version) { - case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_MD5_ARC4: - case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES: - case EAPOL_KEY_DESCRIPTOR_VERSION_AES_128_CMAC_AES: - case EAPOL_KEY_DESCRIPTOR_VERSION_AKM_DEFINED: - break; - default: - return NULL; - } - - key_data_len = L_BE16_TO_CPU(ek->key_data_len); - if (len < sizeof(struct eapol_key) + key_data_len) - return NULL; - - return ek; -} - #define VERIFY_PTK_COMMON(ek) \ if (!ek->key_type) \ return false; \ diff --git a/src/eapol.h b/src/eapol.h index f284ad11..f2d5b413 100644 --- a/src/eapol.h +++ b/src/eapol.h @@ -24,29 +24,7 @@ #include #include #include - -enum eapol_protocol_version { - EAPOL_PROTOCOL_VERSION_2001 = 1, - EAPOL_PROTOCOL_VERSION_2004 = 2, -}; - -/* - * 802.1X-2010: Table 11-5—Descriptor Type value assignments - * The WPA key type of 254 comes from somewhere else. Seems it is a legacy - * value that might still be used by older implementations - */ -enum eapol_descriptor_type { - EAPOL_DESCRIPTOR_TYPE_RC4 = 1, - EAPOL_DESCRIPTOR_TYPE_80211 = 2, - EAPOL_DESCRIPTOR_TYPE_WPA = 254, -}; - -enum eapol_key_descriptor_version { - EAPOL_KEY_DESCRIPTOR_VERSION_AKM_DEFINED = 0, - EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_MD5_ARC4 = 1, - EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES = 2, - EAPOL_KEY_DESCRIPTOR_VERSION_AES_128_CMAC_AES = 3, -}; +#include "src/eapolutil.h" struct eapol_sm; struct handshake_state; @@ -54,61 +32,6 @@ struct preauth_sm; enum handshake_kde; enum ie_rsn_akm_suite; -struct eapol_header { - uint8_t protocol_version; - uint8_t packet_type; - __be16 packet_len; -} __attribute__ ((packed)); - -struct eapol_frame { - struct eapol_header header; - uint8_t data[0]; -} __attribute__ ((packed)); - -struct eapol_key { - struct eapol_header header; - uint8_t descriptor_type; -#if defined(__LITTLE_ENDIAN_BITFIELD) - bool key_mic:1; - bool secure:1; - bool error:1; - bool request:1; - bool encrypted_key_data:1; - bool smk_message:1; - uint8_t reserved2:2; - uint8_t key_descriptor_version:3; - bool key_type:1; - uint8_t wpa_key_id:2; /* Bits 4-5 reserved in RSN, Key ID in WPA */ - bool install:1; - bool key_ack:1; -#elif defined (__BIG_ENDIAN_BITFIELD) - uint8_t reserved2:2; - bool smk_message:1; - bool encrypted_key_data:1; - bool request:1; - bool error:1; - bool secure:1; - bool key_mic:1; - bool key_ack:1; - bool install:1; - uint8_t wpa_key_id:2; /* Bits 4-5 reserved in RSN, Key ID in WPA */ - bool key_type:1; - uint8_t key_descriptor_version:3; -#else -#error "Please fix " -#endif - - __be16 key_length; - __be64 key_replay_counter; - uint8_t key_nonce[32]; - uint8_t eapol_key_iv[16]; - uint8_t key_rsc[8]; - uint8_t reserved[8]; - uint8_t key_mic_data[16]; - __be16 key_data_len; - uint8_t key_data[0]; -} __attribute__ ((packed)); - typedef int (*eapol_tx_packet_func_t)(uint32_t ifindex, const uint8_t *dest, uint16_t proto, const struct eapol_frame *ef, @@ -142,8 +65,6 @@ bool eapol_encrypt_key_data(const uint8_t *kek, uint8_t *key_data, void eapol_key_data_append(struct eapol_key *ek, enum handshake_kde selector, const uint8_t *data, size_t data_len); -const struct eapol_key *eapol_key_validate(const uint8_t *frame, size_t len); - bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek); bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek); bool eapol_verify_ptk_3_of_4(const struct eapol_key *ek, bool is_wpa); diff --git a/src/eapolutil.c b/src/eapolutil.c new file mode 100644 index 00000000..fd8858cd --- /dev/null +++ b/src/eapolutil.c @@ -0,0 +1,77 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "eapolutil.h" + +const struct eapol_key *eapol_key_validate(const uint8_t *frame, size_t len) +{ + const struct eapol_key *ek; + uint16_t key_data_len; + + if (len < sizeof(struct eapol_key)) + return NULL; + + ek = (const struct eapol_key *) frame; + + switch (ek->header.protocol_version) { + case EAPOL_PROTOCOL_VERSION_2001: + case EAPOL_PROTOCOL_VERSION_2004: + break; + default: + return NULL; + } + + if (ek->header.packet_type != 3) + return NULL; + + switch (ek->descriptor_type) { + case EAPOL_DESCRIPTOR_TYPE_RC4: + case EAPOL_DESCRIPTOR_TYPE_80211: + case EAPOL_DESCRIPTOR_TYPE_WPA: + break; + default: + return NULL; + } + + switch (ek->key_descriptor_version) { + case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_MD5_ARC4: + case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES: + case EAPOL_KEY_DESCRIPTOR_VERSION_AES_128_CMAC_AES: + case EAPOL_KEY_DESCRIPTOR_VERSION_AKM_DEFINED: + break; + default: + return NULL; + } + + key_data_len = L_BE16_TO_CPU(ek->key_data_len); + if (len < sizeof(struct eapol_key) + key_data_len) + return NULL; + + return ek; +} diff --git a/src/eapolutil.h b/src/eapolutil.h new file mode 100644 index 00000000..f8e00748 --- /dev/null +++ b/src/eapolutil.h @@ -0,0 +1,106 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include + +enum eapol_protocol_version { + EAPOL_PROTOCOL_VERSION_2001 = 1, + EAPOL_PROTOCOL_VERSION_2004 = 2, +}; + +/* + * 802.1X-2010: Table 11-5—Descriptor Type value assignments + * The WPA key type of 254 comes from somewhere else. Seems it is a legacy + * value that might still be used by older implementations + */ +enum eapol_descriptor_type { + EAPOL_DESCRIPTOR_TYPE_RC4 = 1, + EAPOL_DESCRIPTOR_TYPE_80211 = 2, + EAPOL_DESCRIPTOR_TYPE_WPA = 254, +}; + +enum eapol_key_descriptor_version { + EAPOL_KEY_DESCRIPTOR_VERSION_AKM_DEFINED = 0, + EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_MD5_ARC4 = 1, + EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES = 2, + EAPOL_KEY_DESCRIPTOR_VERSION_AES_128_CMAC_AES = 3, +}; + +struct eapol_header { + uint8_t protocol_version; + uint8_t packet_type; + __be16 packet_len; +} __attribute__ ((packed)); + +struct eapol_frame { + struct eapol_header header; + uint8_t data[0]; +} __attribute__ ((packed)); + +struct eapol_key { + struct eapol_header header; + uint8_t descriptor_type; +#if defined(__LITTLE_ENDIAN_BITFIELD) + bool key_mic:1; + bool secure:1; + bool error:1; + bool request:1; + bool encrypted_key_data:1; + bool smk_message:1; + uint8_t reserved2:2; + uint8_t key_descriptor_version:3; + bool key_type:1; + uint8_t wpa_key_id:2; /* Bits 4-5 reserved in RSN, Key ID in WPA */ + bool install:1; + bool key_ack:1; +#elif defined (__BIG_ENDIAN_BITFIELD) + uint8_t reserved2:2; + bool smk_message:1; + bool encrypted_key_data:1; + bool request:1; + bool error:1; + bool secure:1; + bool key_mic:1; + bool key_ack:1; + bool install:1; + uint8_t wpa_key_id:2; /* Bits 4-5 reserved in RSN, Key ID in WPA */ + bool key_type:1; + uint8_t key_descriptor_version:3; +#else +#error "Please fix " +#endif + + __be16 key_length; + __be64 key_replay_counter; + uint8_t key_nonce[32]; + uint8_t eapol_key_iv[16]; + uint8_t key_rsc[8]; + uint8_t reserved[8]; + uint8_t key_mic_data[16]; + __be16 key_data_len; + uint8_t key_data[0]; +} __attribute__ ((packed)); + +const struct eapol_key *eapol_key_validate(const uint8_t *frame, size_t len);