aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2006-12-27 23:05:55 +0000
committerGerald Combs <gerald@wireshark.org>2006-12-27 23:05:55 +0000
commit2437fd2e778b10418e22917d32a2679b2203435a (patch)
treed3f8e772ec737813b09289115d67b06bcc849331
parent25862eff23f5981ca5764217346d7dfa62c1494e (diff)
Prepare to move the airpdcap code to epan/crypt (SVN won't let me actually
move the files until these changes are checked in). Add an AC_DEFINE for airpdcap (which will be removed once the changes have settled). Update the airpdcap code to compile on non-Windows systems. Fix up comments and whitespace to conform more closely to the rest of the code base. Verified to compile under Windows and OS X. svn path=/trunk/; revision=20227
-rw-r--r--Makefile.am7
-rw-r--r--airpcap.h5
-rw-r--r--airpcap_loader.c41
-rw-r--r--airpcap_loader.h66
-rw-r--r--airpdcap/Makefile.am28
-rw-r--r--airpdcap/Makefile.nmake2
-rw-r--r--airpdcap/airpdcap.c2500
-rw-r--r--airpdcap/airpdcap_ccmp.c45
-rw-r--r--airpdcap/airpdcap_ccmp.h23
-rw-r--r--airpdcap/airpdcap_debug.c4
-rw-r--r--airpdcap/airpdcap_debug.h2
-rw-r--r--airpdcap/airpdcap_int.h4
-rw-r--r--airpdcap/airpdcap_interop.h66
-rw-r--r--airpdcap/airpdcap_md5.c102
-rw-r--r--airpdcap/airpdcap_md5.h25
-rw-r--r--airpdcap/airpdcap_rijndael.c60
-rw-r--r--airpdcap/airpdcap_rijndael.h24
-rw-r--r--airpdcap/airpdcap_sha1.c85
-rw-r--r--airpdcap/airpdcap_sha1.h9
-rw-r--r--airpdcap/airpdcap_system.h434
-rw-r--r--airpdcap/airpdcap_tkip.c75
-rw-r--r--airpdcap/airpdcap_tkip.h27
-rw-r--r--airpdcap/airpdcap_user.h145
-rw-r--r--airpdcap/airpdcap_wep.c12
-rw-r--r--airpdcap/airpdcap_wep.h8
-rw-r--r--airpdcap/airpdcap_ws.h4
-rw-r--r--configure.in7
-rw-r--r--epan/Makefile.am4
-rw-r--r--epan/dissectors/packet-ieee80211.c15
-rw-r--r--gtk/main.c2
30 files changed, 1843 insertions, 1988 deletions
diff --git a/Makefile.am b/Makefile.am
index 8bf2a6b243..974de3205c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -312,6 +312,7 @@ tshark_additional_libs = \
wiretap/libwiretap.la \
epan/libwireshark.la
+
# This is the automake dependency variable for the executable
tshark_DEPENDENCIES = \
$(wireshark_optional_objects) \
@@ -712,12 +713,12 @@ else
install-exec-hook:
endif
-DIST_SUBDIRS = asn1 codecs doc epan gtk help packaging plugins tools wiretap
+DIST_SUBDIRS = asn1 codecs doc airpdcap epan gtk help packaging plugins tools wiretap
if HAVE_PLUGINS
-SUBDIRS = tools wiretap doc epan plugins packaging help @wireshark_SUBDIRS@
+SUBDIRS = tools wiretap doc airpdcap epan plugins packaging help @wireshark_SUBDIRS@
else
-SUBDIRS = tools wiretap doc epan packaging help @wireshark_SUBDIRS@
+SUBDIRS = tools wiretap doc airpdcap epan packaging help @wireshark_SUBDIRS@
endif
wireshark.1: doc/wireshark.pod AUTHORS-SHORT-FORMAT
diff --git a/airpcap.h b/airpcap.h
index 1a7aeb28d4..13f1155cac 100644
--- a/airpcap.h
+++ b/airpcap.h
@@ -83,12 +83,7 @@ typedef struct _AirpcapDeviceDescription
PCHAR Description; /* Device description */
} AirpcapDeviceDescription, *PAirpcapDeviceDescription;
-#define MAX_ENCRYPTION_KEYS 64
-#define WEP_KEY_MAX_SIZE 32 /* Maximum size of a WEP key, in bytes. This is the size of an entry in the */
- /* AirpcapWepKeysCollection structure */
-
-
#ifndef __MINGW32__
#pragma pack(push)
#pragma pack(1)
diff --git a/airpcap_loader.c b/airpcap_loader.c
index bd5c9c1d9f..cf3f1e80f8 100644
--- a/airpcap_loader.c
+++ b/airpcap_loader.c
@@ -42,16 +42,17 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/prefs-int.h>
+#include <epan/crypt/wep-wpadefs.h>
#include "capture_ui_utils.h"
#include "simple_dialog.h"
+/* AirPDcap */
+#include "airpdcap/airpdcap_ws.h"
+
#include <airpcap.h>
#include "airpcap_loader.h"
-/* AirPDcap */
-#include "../airpdcap/airpdcap_ws.h"
-
/*
* We load dinamically the dag library in order link it only when
* it's present on the system
@@ -109,8 +110,8 @@ airpcap_if_info_t *airpcap_if_active = NULL;
/* WLAN preferences pointer */
module_t *wlan_prefs = NULL;
-/*
- * Callback used by the load_wlan_keys() routine in order to read a WEP decryption key
+/*
+ * Callback used by the load_wlan_keys() routine in order to read a WEP decryption key
*/
static guint
get_wep_key(pref_t *pref, gpointer ud _U_)
@@ -395,8 +396,8 @@ fake_info_if = airpcap_driver_fake_if_info_new();
if(fake_info_if == NULL)
return FALSE;
-/*
- * XXX - When WPA will be supported, change this to: keys_in_list = g_list_length(key_list);
+/*
+ * XXX - When WPA will be supported, change this to: keys_in_list = g_list_length(key_list);
* but right now we will have to count only the WEP keys (or we will have a malloc-mess :-) )
*/
n = g_list_length(key_list);
@@ -428,8 +429,8 @@ if(!KeysCollection)
*/
KeysCollection->nKeys = keys_in_list;
-/*
- * XXX - If we have, let's say, six keys, the first three are WEP, then two are WPA, and the
+/*
+ * XXX - If we have, let's say, six keys, the first three are WEP, then two are WPA, and the
* last is WEP, we have to scroll the whole list (n) but increment the array counter only
* when a WEP key is found (y) .. When WPA will be supported by the driver, I'll have to change
* this
@@ -440,7 +441,7 @@ for(i = 0; i < n; i++)
{
/* Retrieve the Item corresponding to the i-th key */
key_item = (decryption_key_t*)g_list_nth_data(key_list,i);
-
+
/*
* XXX - The AIRPDCAP_KEY_TYPE_WEP is the only supportd right now!
* We will have to modify the AirpcapKey structure in order to
@@ -2018,7 +2019,7 @@ for(i=0;i<n2;i++)
}
/*
- * XXX - END : Remove from START to END when the WPA/WPA2 decryption will be implemented in
+ * XXX - END : Remove from START to END when the WPA/WPA2 decryption will be implemented in
* the Driver
*/
@@ -2389,7 +2390,7 @@ decryption_key_t *dk;
if(input_string == NULL)
return NULL;
-/*
+/*
* Parse the input_string. It should be in the form <key type>:<key data>[:<ssid>]
* XXX - For backward compatibility, the a WEP key can be just a string of hexadecimal
* characters (if WEP key is wrong, null will be returned...).
@@ -2407,7 +2408,7 @@ if(n == 0)
return NULL;
}
-/*
+/*
* 'n' contains the number of tokens. If the key string is correct, we should have
* 2 or 3 tokens... If we have 1 token, it can be an 'old style' WEP key... check for it...
*/
@@ -2471,9 +2472,9 @@ if(n == 1)
/* There were at least 2 tokens... copy the type value */
type = g_strdup(tokens[0]);
-/*
-* The second token is the key (right now it doesn't matter
-* if it is a passphrase or an hexadecimal one)
+/*
+* The second token is the key (right now it doesn't matter
+* if it is a passphrase or an hexadecimal one)
*/
key = g_strdup(tokens[1]);
@@ -2492,7 +2493,7 @@ else
ssid = NULL;
}
-/*
+/*
* Now the initial key string has been divided in two/three tokens... let's see
* which kind of key it is, and if it is the correct form
*/
@@ -2623,7 +2624,7 @@ else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PWD) == 0) /* WPA key *//* If the
/*
* XXX - Maybe we need some check on the characters? I'm not sure if only standard ASCII are ok...
- */
+ */
if( ((ssid_string->len) > WPA_SSID_MAX_CHAR_SIZE) || ((ssid_string->len) < WPA_SSID_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
@@ -2645,9 +2646,9 @@ else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PWD) == 0) /* WPA key *//* If the
dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
dk->key = g_string_new(key);
dk->bits = 256; /* This is the lenght of the array pf bytes that will be generated using key+ssid ...*/
- if(ssid != NULL)
+ if(ssid != NULL)
dk->ssid = g_string_new(ssid);
- else
+ else
dk->ssid = NULL;
g_string_free(key_string, TRUE);
diff --git a/airpcap_loader.h b/airpcap_loader.h
index 70a28465dc..84766c90e3 100644
--- a/airpcap_loader.h
+++ b/airpcap_loader.h
@@ -34,63 +34,13 @@
#define AIRPCAP_CHANNEL_ANY_NAME "ANY"
-/*
- * WEP_KEY_MAX_SIZE is in bytes, but each byte is rapresented in strings with an ascii char
- * 4 bit are needed to store an exadecimal number, 8 bit to store a char...
- */
-#define WEP_KEY_MAX_CHAR_SIZE (WEP_KEY_MAX_SIZE*2)
-
-/*
- * WEP_KEY_MAX_SIZE is in bytes, this is in bits...
- */
-#define WEP_KEY_MAX_BIT_SIZE (WEP_KEY_MAX_SIZE*8)
-
-#define WEP_KEY_MIN_CHAR_SIZE 2
-#define WEP_KEY_MIN_BIT_SIZE 8
-
-/*
- * XXX - The next #define should probably be moved in airpcap.h,
- * near WEP_KEY_MAX_SIZE ...
- */
-#define WPA_KEY_MAX_SIZE 63 /* 63 chars followed by a '\0' */
-
-#define WPA_KEY_MAX_CHAR_SIZE (WPA_KEY_MAX_SIZE*1)
-#define WPA_KEY_MAX_BIT_SIZE (WPA_KEY_MAX_SIZE*8)
-#define WPA_KEY_MIN_CHAR_SIZE 8
-#define WPA_KEY_MIN_BIT_SIZE (WPA_KEY_MIN_CHAR_SIZE*8)
-
-/*
- * XXX - The next #define should probably be moved in airpcap.h,
- * near WEP_KEY_MAX_SIZE ...
- */
-#define WPA_SSID_MAX_SIZE 32
-
-#define WPA_SSID_MAX_CHAR_SIZE (WPA_SSID_MAX_SIZE*1)
-#define WPA_SSID_MAX_BIT_SIZE (WPA_SSID_MAX_SIZE*8)
-#define WPA_SSID_MIN_CHAR_SIZE 0
-#define WPA_SSID_MIN_BIT_SIZE (WPA_SSID_MIN_CHAR_SIZE*8)
-
-/*
- * User can enter the binary PSK, instead of the passphrase+ssid...
- */
-#define WPA_PSK_KEY_SIZE 32 /* Fixed size, 32 bytes (256bit) */
-#define WPA_PSK_KEY_CHAR_SIZE (WPA_PSK_KEY_SIZE*2)
-#define WPA_PSK_KEY_BIT_SIZE (WPA_PSK_KEY_SIZE*8)
-
#define AIRPCAP_WEP_KEY_STRING "WEP"
/*
- * XXX - WPA_PWD is the passphrase+ssid and WPA-PSK is the hexadecimal key
+ * XXX - WPA_PWD is the passphrase+ssid and WPA-PSK is the hexadecimal key
*/
#define AIRPCAP_WPA_PWD_KEY_STRING "WPA-PWD"
#define AIRPCAP_WPA_BIN_KEY_STRING "WPA-PSK"
-/*
- * Key string defines
- */
-#define STRING_KEY_TYPE_WEP "wep"
-#define STRING_KEY_TYPE_WPA_PWD "wpa-pwd"
-#define STRING_KEY_TYPE_WPA_PSK "wpa-psk"
-
#define AIRPCAP_DLL_OK 0
#define AIRPCAP_DLL_OLD 1
#define AIRPCAP_DLL_ERROR 2
@@ -152,16 +102,6 @@ typedef struct {
} airpcap_if_info_t;
/*
- * Struct to store infos about a specific decryption key.
- */
-typedef struct {
- GString *key;
- GString *ssid;
- guint bits;
- guint type;
-} decryption_key_t;
-
-/*
* Struct used to store infos to pass to the preferences manager callbacks
*/
typedef struct {
@@ -480,13 +420,13 @@ write_wlan_driver_wep_keys_to_regitry(GList* key_list);
void
airpcap_if_clear_decryption_settings(airpcap_if_info_t* info_if);
-/*
+/*
* Function used to save to the preference file the Decryption Keys.
*/
int
save_wlan_driver_wep_keys();
-/*
+/*
* Function used to save to the preference file the Decryption Keys.
*/
int
diff --git a/airpdcap/Makefile.am b/airpdcap/Makefile.am
index 5d7d27bc48..fc50901c83 100644
--- a/airpdcap/Makefile.am
+++ b/airpdcap/Makefile.am
@@ -21,32 +21,24 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+include Makefile.common
-noinst_LIBRARIES = airpdcap.a
+noinst_LIBRARIES = \
+ libairpdcap.a
+
+DISTCLEANFILES = \
+ libairpdcap.a
CLEANFILES = \
- airpdcap.a \
+ libairpdcap.a \
*~
MAINTAINERCLEANFILES = \
Makefile.in
-airpdcap_a_SOURCES = \
- airpdcap.c \
- airpdcap_ccmp.c airpdcap_ccmp.h \
- airpdcap_debug.c airpdcap_debug.h \
- airpdcap_md5.c airpdcap_md5.h \
- airpdcap_rijndael.c airpdcap_rijndael.h \
- airpdcap_sha1.c airpdcap_sha1.h \
- airpdcap_tkip.c airpdcap_tkip.h \
- airpdcap_wep.c airpdcap_wep.h \
- airpdcap_interop.h \
- airpdcap_ws.h \
- airpdcap_types.h \
- airpdcap_user.h \
- airpdcap_system.h
-
-airpdcap_a_DEPENDENCIES =
+libairpdcap_a_SOURCES = \
+ $(LIBAIRPDCAP_SRC) \
+ $(LIBAIRPDCAP_INCLUDES)
EXTRA_DIST = \
Makefile.nmake
diff --git a/airpdcap/Makefile.nmake b/airpdcap/Makefile.nmake
index 10cadce94f..e2f5f4bd54 100644
--- a/airpdcap/Makefile.nmake
+++ b/airpdcap/Makefile.nmake
@@ -7,7 +7,7 @@ include ..\config.nmake
############### no need to modify below this line #########
-CFLAGS=-DHAVE_CONFIG_H -DHAVE_WIRESHARK $(GLIB_CFLAGS) -D_U_="" $(LOCAL_CFLAGS)
+CFLAGS=-DHAVE_CONFIG_H $(GLIB_CFLAGS) -D_U_="" $(LOCAL_CFLAGS)
.c.obj::
$(CC) $(CFLAGS) -Fd.\ -c $<
diff --git a/airpdcap/airpdcap.c b/airpdcap/airpdcap.c
index 7f7d8dd3d0..ce220ac472 100644
--- a/airpdcap/airpdcap.c
+++ b/airpdcap/airpdcap.c
@@ -4,13 +4,10 @@
#include "airpdcap_system.h"
#include "airpdcap_int.h"
-#include "airpdcap_tkip.h"
-#include "airpdcap_ccmp.h"
#include "airpdcap_wep.h"
#include "airpdcap_sha1.h"
-#include "airpdcap_md5.h"
-#include "airpdcap_debug.h"
+#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -20,36 +17,35 @@
#define AIRPDCAP_SHA_DIGEST_LEN 20
/* EAPOL definitions */
-/*!
-/brief
-Length of the EAPOL-Key key confirmation key (KCK) used to calculate MIC over EAPOL frame and validate an EAPOL packet (128 bits)
-*/
+/**
+ * Length of the EAPOL-Key key confirmation key (KCK) used to calculate
+ * MIC over EAPOL frame and validate an EAPOL packet (128 bits)
+ */
#define AIRPDCAP_WPA_KCK_LEN 16
-/*!
-/brief
-Offset of the Key MIC in the EAPOL packet body
-*/
+/**
+ *Offset of the Key MIC in the EAPOL packet body
+ */
#define AIRPDCAP_WPA_MICKEY_OFFSET 77
-/*!
-/brief
-Maximum length of the EAPOL packet (it depends on the maximum MAC frame size)
-*/
+/**
+ * Maximum length of the EAPOL packet (it depends on the maximum MAC
+ * frame size)
+ */
#define AIRPDCAP_WPA_MAX_EAPOL_LEN 4095
-/*!
-/brief
-EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and from a STA when neither the
-group nor pairwise ciphers are CCMP for Key Descriptor 1.
-/note
-Defined in 802.11i-2004, page 78
-*/
+/**
+ * EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and
+ * from a STA when neither the group nor pairwise ciphers are CCMP for
+ * Key Descriptor 1.
+ * @note
+ * Defined in 802.11i-2004, page 78
+ */
#define AIRPDCAP_WPA_KEY_VER_CCMP 1
-/*!
-/brief
-EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and from a STA when either the
-pairwise or the group cipher is AES-CCMP for Key Descriptor 2.
-/note
-Defined in 802.11i-2004, page 78
-*/
+/**
+ * EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and
+ * from a STA when either the pairwise or the group cipher is AES-CCMP
+ * for Key Descriptor 2.
+ * /note
+ * Defined in 802.11i-2004, page 78
+ */
#define AIRPDCAP_WPA_KEY_VER_AES_CCMP 2
/* */
/******************************************************************************/
@@ -77,154 +73,137 @@ extern const UINT32 crc32_table[256];
extern "C" {
#endif
- /*!
- /brief
- It is a step of the PBKDF2 (specifically the PKCS #5 v2.0) defined in the RFC 2898 to derive a key (used as PMK in WPA)
-
- /param password
- [IN] pointer to a password (sequence of between 8 and 63 ASCII encoded characters)
-
- /param ssid
- [IN] pointer to the SSID string encoded in max 32 ASCII encoded characters
-
- /param iterations
- [IN] times to hash the password (4096 for WPA)
-
- /param count
- [IN] ???
-
- /param output
- [OUT] pointer to a preallocated buffer of AIRPDCAP_SHA_DIGEST_LEN characters that will contain a part of the key
- */
- INT AirPDcapRsnaPwd2PskStep(
- const CHAR *password,
- const CHAR *ssid,
- const size_t ssidLength,
- const INT iterations,
- const INT count,
- UCHAR *output)
- ;
-
- /*!
- /brief
- It calculates the passphrase-to-PSK mapping reccomanded for use with RSNAs. This implementation uses the PBKDF2 method defined in the RFC 2898.
-
- /param password
- [IN] pointer to a password (sequence of between 8 and 63 ASCII encoded characters)
-
- /param ssid
- [IN] pointer to the SSID string encoded in max 32 ASCII encoded characters
-
- /param output
- [OUT] calculated PSK (to use as PMK in WPA)
-
- /note
- Described in 802.11i-2004, page 165
- */
- INT AirPDcapRsnaPwd2Psk(
- const CHAR *password,
- const CHAR *ssid,
- const size_t ssidLength,
- UCHAR *output)
- ;
-
- INT AirPDcapRsnaMng(
- UCHAR *decrypt_data,
- size_t *decrypt_len,
- PAIRPDCAP_KEY_ITEM key,
- AIRPDCAP_SEC_ASSOCIATION *sa,
- INT offset,
- UINT8 fcsPresent)
- ;
-
- INT AirPDcapWepMng(
- PAIRPDCAP_CONTEXT ctx,
- UCHAR *decrypt_data,
- size_t *decrypt_len,
- PAIRPDCAP_KEY_ITEM key,
- AIRPDCAP_SEC_ASSOCIATION *sa,
- INT offset,
- UINT8 fcsPresent)
- ;
-
- INT AirPDcapRsna4WHandshake(
- PAIRPDCAP_CONTEXT ctx,
- const UCHAR *data,
- AIRPDCAP_SEC_ASSOCIATION *sa,
- PAIRPDCAP_KEY_ITEM key,
- INT offset)
- ;
- ;
- /*!
- /brief
- It checks whether the specified key is corrected or not.
- /note
- For a standard WEP key the length will be changed to the standard length, and the type changed in a generic WEP key.
-
- /param key
- [IN] pointer to the key to validate
-
- /return
- - TRUE: the key contains valid fields and values
- - FALSE: the key has some invalid field or value
- */
- INT AirPDcapValidateKey(
- PAIRPDCAP_KEY_ITEM key)
- ;
-
- INT AirPDcapRsnaMicCheck(
- UCHAR *eapol,
- const USHORT eapol_len,
- const UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
- const USHORT key_ver)
- ;
-
- /*!
- /brief it gets the index of the Security Association structure for the specified BSSID and STA MAC address
- /param ctx
- [IN] pointer to the current context
- /param id
- [IN] id of the association (composed by BSSID and MAC of the station)
- /return
- - index of the Security Association structure if found
- - -1, if the specified addresses pair BSSID-STA MAC has not been found
- */
- INT AirPDcapGetSa(
- PAIRPDCAP_CONTEXT ctx,
- AIRPDCAP_SEC_ASSOCIATION_ID *id)
- ;
-
- INT AirPDcapFreeSa(
- PAIRPDCAP_CONTEXT ctx,
- INT index) /* index of the structure to free */
- ;
-
- INT AirPDcapStoreSa(
- PAIRPDCAP_CONTEXT ctx,
- AIRPDCAP_SEC_ASSOCIATION_ID *id)
- ;
-
- UCHAR * AirPDcapGetStaAddress(
- PAIRPDCAP_MAC_FRAME frame)
- ;
-
- UCHAR * AirPDcapGetBssidAddress(
- PAIRPDCAP_MAC_FRAME frame)
- ;
-
- void AirPDcapRsnaPrfX(
- AIRPDCAP_SEC_ASSOCIATION *sa,
- const UCHAR pmk[32],
- const UCHAR snonce[32],
- const INT x, /* for TKIP 512, for CCMP 384 */
- UCHAR *ptk)
- ;
-
- INT AirPDcapAlgCrc32(
- UCHAR *buf,
- size_t nr,
- ULONG *cval)
- ;
+/**
+ * It is a step of the PBKDF2 (specifically the PKCS #5 v2.0) defined in
+ * the RFC 2898 to derive a key (used as PMK in WPA)
+ * @param password [IN] pointer to a password (sequence of between 8 and
+ * 63 ASCII encoded characters)
+ * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
+ * encoded characters
+ * @param iterations [IN] times to hash the password (4096 for WPA)
+ * @param count [IN] ???
+ * @param output [OUT] pointer to a preallocated buffer of
+ * AIRPDCAP_SHA_DIGEST_LEN characters that will contain a part of the key
+ */
+INT AirPDcapRsnaPwd2PskStep(
+ const CHAR *password,
+ const CHAR *ssid,
+ const size_t ssidLength,
+ const INT iterations,
+ const INT count,
+ UCHAR *output)
+ ;
+
+/**
+ * It calculates the passphrase-to-PSK mapping reccomanded for use with
+ * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
+ * 2898.
+ * @param password [IN] pointer to a password (sequence of between 8 and
+ * 63 ASCII encoded characters)
+ * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
+ * encoded characters
+ * @param output [OUT] calculated PSK (to use as PMK in WPA)
+ * @note
+ * Described in 802.11i-2004, page 165
+ */
+INT AirPDcapRsnaPwd2Psk(
+ const CHAR *password,
+ const CHAR *ssid,
+ const size_t ssidLength,
+ UCHAR *output)
+ ;
+
+INT AirPDcapRsnaMng(
+ UCHAR *decrypt_data,
+ size_t *decrypt_len,
+ PAIRPDCAP_KEY_ITEM key,
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ INT offset,
+ UINT8 fcsPresent)
+ ;
+
+INT AirPDcapWepMng(
+ PAIRPDCAP_CONTEXT ctx,
+ UCHAR *decrypt_data,
+ size_t *decrypt_len,
+ PAIRPDCAP_KEY_ITEM key,
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ INT offset,
+ UINT8 fcsPresent)
+ ;
+
+INT AirPDcapRsna4WHandshake(
+ PAIRPDCAP_CONTEXT ctx,
+ const UCHAR *data,
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ PAIRPDCAP_KEY_ITEM key,
+ INT offset)
+ ;
+/**
+ * It checks whether the specified key is corrected or not.
+ * @note
+ * For a standard WEP key the length will be changed to the standard
+ * length, and the type changed in a generic WEP key.
+ * @param key [IN] pointer to the key to validate
+ * @return
+ * - TRUE: the key contains valid fields and values
+ * - FALSE: the key has some invalid field or value
+ */
+INT AirPDcapValidateKey(
+ PAIRPDCAP_KEY_ITEM key)
+ ;
+
+INT AirPDcapRsnaMicCheck(
+ UCHAR *eapol,
+ const USHORT eapol_len,
+ const UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
+ const USHORT key_ver)
+ ;
+
+/**
+ * @param ctx [IN] pointer to the current context
+ * @param id [IN] id of the association (composed by BSSID and MAC of
+ * the station)
+ * @return
+ * - index of the Security Association structure if found
+ * - -1, if the specified addresses pair BSSID-STA MAC has not been found
+ */
+INT AirPDcapGetSa(
+ PAIRPDCAP_CONTEXT ctx,
+ AIRPDCAP_SEC_ASSOCIATION_ID *id)
+ ;
+
+INT AirPDcapFreeSa(
+ PAIRPDCAP_CONTEXT ctx,
+ INT index) /* index of the structure to free */
+ ;
+
+INT AirPDcapStoreSa(
+ PAIRPDCAP_CONTEXT ctx,
+ AIRPDCAP_SEC_ASSOCIATION_ID *id)
+ ;
+
+UCHAR * AirPDcapGetStaAddress(
+ PAIRPDCAP_MAC_FRAME frame)
+ ;
+
+UCHAR * AirPDcapGetBssidAddress(
+ PAIRPDCAP_MAC_FRAME frame)
+ ;
+
+void AirPDcapRsnaPrfX(
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ const UCHAR pmk[32],
+ const UCHAR snonce[32],
+ const INT x, /* for TKIP 512, for CCMP 384 */
+ UCHAR *ptk)
+ ;
+
+INT AirPDcapAlgCrc32(
+ UCHAR *buf,
+ size_t nr,
+ ULONG *cval)
+ ;
#ifdef __cplusplus
}
@@ -238,349 +217,350 @@ extern "C" {
#ifdef __cplusplus
extern "C" {
#endif
- INT AirPDcapPacketProcess(
- PAIRPDCAP_CONTEXT ctx,
- const UCHAR *data,
- const size_t len,
- UCHAR *decrypt_data,
- size_t *decrypt_len,
- PAIRPDCAP_KEY_ITEM key,
- UINT8 fcsPresent,
- UINT8 radioTapPresent,
- UINT8 mngHandshake,
- UINT8 mngDecrypt)
- {
- size_t mac_header_len;
- UCHAR *address;
- AIRPDCAP_SEC_ASSOCIATION_ID id;
- INT index;
- PAIRPDCAP_SEC_ASSOCIATION sa;
- INT offset;
- UINT16 bodyLength;
+
+INT AirPDcapPacketProcess(
+ PAIRPDCAP_CONTEXT ctx,
+ const UCHAR *data,
+ const size_t len,
+ UCHAR *decrypt_data,
+ size_t *decrypt_len,
+ PAIRPDCAP_KEY_ITEM key,
+ UINT8 fcsPresent,
+ UINT8 radioTapPresent,
+ UINT8 mngHandshake,
+ UINT8 mngDecrypt)
+{
+ size_t mac_header_len;
+ UCHAR *address;
+ AIRPDCAP_SEC_ASSOCIATION_ID id;
+ INT index;
+ PAIRPDCAP_SEC_ASSOCIATION sa;
+ INT offset;
+ UINT16 bodyLength;
#ifdef _DEBUG
- CHAR msgbuf[255];
+ CHAR msgbuf[255];
#endif
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapPacketProcess");
-
- if (ctx==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
- return AIRPDCAP_RET_UNSUCCESS;
- }
- if (data==NULL || len==0) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
- return AIRPDCAP_RET_UNSUCCESS;
- }
-
- if (radioTapPresent)
- offset=AIRPDCAP_RADIOTAP_HEADER_LEN;
- else
- offset=0;
-
- /* check if the packet is of data type */
- /* TODO consider packets send on an ad-hoc net (QoS) */
- if (AIRPDCAP_TYPE(data[offset])!=AIRPDCAP_TYPE_DATA) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_DATA;
- }
-
- /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
- mac_header_len=AIRPDCAP_HEADER_LEN(data[offset+1]);
- if (len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_WRONG_DATA_SIZE;
- }
-
- /* get BSSID */
- if ( (address=AirPDcapGetBssidAddress((PAIRPDCAP_MAC_FRAME)(data+offset))) != NULL) {
- memcpy(id.bssid, address, AIRPDCAP_MAC_LEN);
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapPacketProcess");
+
+ if (ctx==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
+ return AIRPDCAP_RET_UNSUCCESS;
+ }
+ if (data==NULL || len==0) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
+ return AIRPDCAP_RET_UNSUCCESS;
+ }
+
+ if (radioTapPresent)
+ offset=AIRPDCAP_RADIOTAP_HEADER_LEN;
+ else
+ offset=0;
+
+ /* check if the packet is of data type */
+ /* TODO consider packets send on an ad-hoc net (QoS) */
+ if (AIRPDCAP_TYPE(data[offset])!=AIRPDCAP_TYPE_DATA) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_DATA;
+ }
+
+ /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
+ mac_header_len=AIRPDCAP_HEADER_LEN(data[offset+1]);
+ if (len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_WRONG_DATA_SIZE;
+ }
+
+ /* get BSSID */
+ if ( (address=AirPDcapGetBssidAddress((PAIRPDCAP_MAC_FRAME)(data+offset))) != NULL) {
+ memcpy(id.bssid, address, AIRPDCAP_MAC_LEN);
#ifdef _DEBUG
- sprintf(msgbuf, "BSSID: %2X.%2X.%2X.%2X.%2X.%2X\t", id.bssid[0],id.bssid[1],id.bssid[2],id.bssid[3],id.bssid[4],id.bssid[5]);
+ sprintf(msgbuf, "BSSID: %2X.%2X.%2X.%2X.%2X.%2X\t", id.bssid[0],id.bssid[1],id.bssid[2],id.bssid[3],id.bssid[4],id.bssid[5]);
#endif
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
- } else {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_REQ_DATA;
- }
-
- /* get STA address */
- if ( (address=AirPDcapGetStaAddress((PAIRPDCAP_MAC_FRAME)(data+offset))) != NULL) {
- memcpy(id.sta, address, AIRPDCAP_MAC_LEN);
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
+ } else {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_REQ_DATA;
+ }
+
+ /* get STA address */
+ if ( (address=AirPDcapGetStaAddress((PAIRPDCAP_MAC_FRAME)(data+offset))) != NULL) {
+ memcpy(id.sta, address, AIRPDCAP_MAC_LEN);
#ifdef _DEBUG
- sprintf(msgbuf, "ST_MAC: %2X.%2X.%2X.%2X.%2X.%2X\t", id.sta[0],id.sta[1],id.sta[2],id.sta[3],id.sta[4],id.sta[5]);
+ sprintf(msgbuf, "ST_MAC: %2X.%2X.%2X.%2X.%2X.%2X\t", id.sta[0],id.sta[1],id.sta[2],id.sta[3],id.sta[4],id.sta[5]);
#endif
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
- } else {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_REQ_DATA;
- }
-
- /* search for a cached Security Association for current BSSID and station MAC */
- if ((index=AirPDcapGetSa(ctx, &id))==-1) {
- /* create a new Security Association */
- if ((index=AirPDcapStoreSa(ctx, &id))==-1) {
- return AIRPDCAP_RET_UNSUCCESS;
- }
- }
-
- /* get the Security Association structure */
- sa=&ctx->sa[index];
-
- /* cache offset in the packet data (to scan encryption data) */
- offset+=AIRPDCAP_HEADER_LEN(data[offset+1]);
-
- /* check if data is encrypted (use the WEP bit in the Frame Control field) */
- if (AIRPDCAP_WEP(data[1])==0)
- {
- if (mngHandshake) {
- /* data is sent in cleartext, check if is an authentication message or end the process */
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Unencrypted data", AIRPDCAP_DEBUG_LEVEL_3);
-
- /* check if the packet as an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
- if (data[offset]==0xAA && /* DSAP=SNAP */
- data[offset+1]==0xAA && /* SSAP=SNAP */
- data[offset+2]==0x03 && /* Control field=Unnumbered frame */
- data[offset+3]==0x00 && /* Org. code=encaps. Ethernet */
- data[offset+4]==0x00 &&
- data[offset+5]==0x00 &&
- data[offset+6]==0x88 && /* Type: 802.1X authentication */
- data[offset+7]==0x8E) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
-
- /* skip LLC header */
- offset+=8;
-
- /* check the version of the EAPOL protocol used (IEEE 802.1X-2004, pg. 24) */
- /* TODO EAPOL protocol version to check? */
- /*if (data[offset]!=2) {
- AIRPDCAP_DEBUG_PRINT_LINE("EAPOL protocol version not recognized", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
- }*/
-
- /* check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25) */
- if (data[offset+1]!=3) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
- }
-
- /* get and check the body length (IEEE 802.1X-2004, pg. 25) */
- bodyLength=ntohs(*(UINT16 *)(data+offset+2));
- if (((len-offset-4)!=bodyLength && !fcsPresent) || ((len-offset-8)!=bodyLength && fcsPresent)) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body not valid (wrong length)", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
- }
-
- /* skip EAPOL MPDU and go to the first byte of the body */
- offset+=4;
-
- /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
- if (/*data[offset]!=0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
- data[offset]!=0x2 && /* IEEE 802.11 Key Descriptor Type */
- data[offset]!=0xFE) /* TODO what's this value??? */
- {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
- }
-
- /* start with descriptor body */
- offset+=1;
-
- /* manage the 4-way handshake to define the key */
- return AirPDcapRsna4WHandshake(ctx, data, sa, key, offset);
- } else {
- /* cleartext message, not authentication */
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "No authentication data", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_DATA_ENCRYPTED;
- }
- }
- } else {
- if (mngDecrypt) {
-
- if (decrypt_data==NULL)
- return AIRPDCAP_RET_UNSUCCESS;
-
- /* create new header and data to modify */
- *decrypt_len=len;
- memcpy(decrypt_data, data, *decrypt_len);
-
- /* encrypted data */
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3);
-
- if (fcsPresent)
- /* remove from next computation FCS */
- *decrypt_len-=4;
-
- /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
- /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP, */
- /* IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP, */
- /* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */
- if (AIRPDCAP_EXTIV(data[offset+3])==0) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3);
- return AirPDcapWepMng(ctx, decrypt_data, decrypt_len, key, sa, offset, fcsPresent);
- } else {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3);
- return AirPDcapRsnaMng(decrypt_data, decrypt_len, key, sa, offset, fcsPresent);
- }
- }
- }
-
- return AIRPDCAP_RET_UNSUCCESS;
- }
-
- INT AirPDcapSetKeys(
- PAIRPDCAP_CONTEXT ctx,
- AIRPDCAP_KEY_ITEM keys[],
- const size_t keys_nr)
- {
- INT i;
- INT success;
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapSetKeys");
-
- if (ctx==NULL || keys==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "NULL context or NULL keys array", AIRPDCAP_DEBUG_LEVEL_3);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
- return 0;
- }
-
- if (keys_nr>AIRPDCAP_MAX_KEYS_NR) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Keys number greater than maximum", AIRPDCAP_DEBUG_LEVEL_3);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
- return 0;
- }
-
- /* clean keys collection before setting new ones */
- AirPDcapCleanKeys(ctx);
-
- /* check and insert keys */
- for (i=0, success=0; i<(INT)keys_nr; i++) {
- if (AirPDcapValidateKey(keys+i)==TRUE) {
- if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PWD key", AIRPDCAP_DEBUG_LEVEL_4);
- AirPDcapRsnaPwd2Psk(keys[i].KeyData.Wpa.UserPwd.Passphrase, keys[i].KeyData.Wpa.UserPwd.Ssid, keys[i].KeyData.Wpa.UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
- }
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
+ } else {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_REQ_DATA;
+ }
+
+ /* search for a cached Security Association for current BSSID and station MAC */
+ if ((index=AirPDcapGetSa(ctx, &id))==-1) {
+ /* create a new Security Association */
+ if ((index=AirPDcapStoreSa(ctx, &id))==-1) {
+ return AIRPDCAP_RET_UNSUCCESS;
+ }
+ }
+
+ /* get the Security Association structure */
+ sa=&ctx->sa[index];
+
+ /* cache offset in the packet data (to scan encryption data) */
+ offset+=AIRPDCAP_HEADER_LEN(data[offset+1]);
+
+ /* check if data is encrypted (use the WEP bit in the Frame Control field) */
+ if (AIRPDCAP_WEP(data[1])==0)
+ {
+ if (mngHandshake) {
+ /* data is sent in cleartext, check if is an authentication message or end the process */
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Unencrypted data", AIRPDCAP_DEBUG_LEVEL_3);
+
+ /* check if the packet as an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
+ if (data[offset]==0xAA && /* DSAP=SNAP */
+ data[offset+1]==0xAA && /* SSAP=SNAP */
+ data[offset+2]==0x03 && /* Control field=Unnumbered frame */
+ data[offset+3]==0x00 && /* Org. code=encaps. Ethernet */
+ data[offset+4]==0x00 &&
+ data[offset+5]==0x00 &&
+ data[offset+6]==0x88 && /* Type: 802.1X authentication */
+ data[offset+7]==0x8E) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
+
+ /* skip LLC header */
+ offset+=8;
+
+ /* check the version of the EAPOL protocol used (IEEE 802.1X-2004, pg. 24) */
+ /* TODO EAPOL protocol version to check? */
+ /*if (data[offset]!=2) {
+ AIRPDCAP_DEBUG_PRINT_LINE("EAPOL protocol version not recognized", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
+ }*/
+
+ /* check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25) */
+ if (data[offset+1]!=3) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
+ }
+
+ /* get and check the body length (IEEE 802.1X-2004, pg. 25) */
+ bodyLength=ntohs(*(UINT16 *)(data+offset+2));
+ if (((len-offset-4)!=bodyLength && !fcsPresent) || ((len-offset-8)!=bodyLength && fcsPresent)) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body not valid (wrong length)", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
+ }
+
+ /* skip EAPOL MPDU and go to the first byte of the body */
+ offset+=4;
+
+ /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
+ if (/*data[offset]!=0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
+ data[offset]!=0x2 && /* IEEE 802.11 Key Descriptor Type */
+ data[offset]!=0xFE) /* TODO what's this value??? */
+ {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
+ }
+
+ /* start with descriptor body */
+ offset+=1;
+
+ /* manage the 4-way handshake to define the key */
+ return AirPDcapRsna4WHandshake(ctx, data, sa, key, offset);
+ } else {
+ /* cleartext message, not authentication */
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "No authentication data", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_DATA_ENCRYPTED;
+ }
+ }
+ } else {
+ if (mngDecrypt) {
+
+ if (decrypt_data==NULL)
+ return AIRPDCAP_RET_UNSUCCESS;
+
+ /* create new header and data to modify */
+ *decrypt_len=len;
+ memcpy(decrypt_data, data, *decrypt_len);
+
+ /* encrypted data */
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3);
+
+ if (fcsPresent)
+ /* remove from next computation FCS */
+ *decrypt_len-=4;
+
+ /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
+ /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP, */
+ /* IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP, */
+ /* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */
+ if (AIRPDCAP_EXTIV(data[offset+3])==0) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3);
+ return AirPDcapWepMng(ctx, decrypt_data, decrypt_len, key, sa, offset, fcsPresent);
+ } else {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3);
+ return AirPDcapRsnaMng(decrypt_data, decrypt_len, key, sa, offset, fcsPresent);
+ }
+ }
+ }
+
+ return AIRPDCAP_RET_UNSUCCESS;
+}
+
+INT AirPDcapSetKeys(
+ PAIRPDCAP_CONTEXT ctx,
+ AIRPDCAP_KEY_ITEM keys[],
+ const size_t keys_nr)
+{
+ INT i;
+ INT success;
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapSetKeys");
+
+ if (ctx==NULL || keys==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "NULL context or NULL keys array", AIRPDCAP_DEBUG_LEVEL_3);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
+ return 0;
+ }
+
+ if (keys_nr>AIRPDCAP_MAX_KEYS_NR) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Keys number greater than maximum", AIRPDCAP_DEBUG_LEVEL_3);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
+ return 0;
+ }
+
+ /* clean keys collection before setting new ones */
+ AirPDcapCleanKeys(ctx);
+
+ /* check and insert keys */
+ for (i=0, success=0; i<(INT)keys_nr; i++) {
+ if (AirPDcapValidateKey(keys+i)==TRUE) {
+ if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PWD key", AIRPDCAP_DEBUG_LEVEL_4);
+ AirPDcapRsnaPwd2Psk(keys[i].KeyData.Wpa.UserPwd.Passphrase, keys[i].KeyData.Wpa.UserPwd.Ssid, keys[i].KeyData.Wpa.UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
+ }
#ifdef _DEBUG
- else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PMK key", AIRPDCAP_DEBUG_LEVEL_4);
- } else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WEP) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WEP key", AIRPDCAP_DEBUG_LEVEL_4);
- } else {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a key", AIRPDCAP_DEBUG_LEVEL_4);
- }
+ else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PMK key", AIRPDCAP_DEBUG_LEVEL_4);
+ } else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WEP) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WEP key", AIRPDCAP_DEBUG_LEVEL_4);
+ } else {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a key", AIRPDCAP_DEBUG_LEVEL_4);
+ }
#endif
- ctx->keys[success].KeyType=keys[i].KeyType;
- memcpy(&ctx->keys[success].KeyData, &keys[i].KeyData, sizeof(keys[i].KeyData));
-
- success++;
- }
- }
-
- ctx->keys_nr=success;
-
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
- return success;
- }
-
- INT AirPDcapCleanKeys(
- PAIRPDCAP_CONTEXT ctx)
- {
- INT i;
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapCleanKeys");
-
- if (ctx==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
- return 0;
- }
-
- for (i=0; i<AIRPDCAP_MAX_KEYS_NR; i++) {
- memset(&ctx->keys[i], 0, sizeof(AIRPDCAP_KEY_ITEM));
- }
-
- ctx->keys_nr=0;
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "Keys collection cleaned!", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
-
- return i;
- }
-
- INT AirPDcapGetKeys(
- const PAIRPDCAP_CONTEXT ctx,
- AIRPDCAP_KEY_ITEM keys[],
- const size_t keys_nr)
- {
- UINT i;
- UINT j;
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapGetKeys");
-
- if (ctx==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
- return 0;
- } else if (keys==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL keys array", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
- return (INT)ctx->keys_nr;
- } else {
- for (i=0, j=0; i<ctx->keys_nr && i<keys_nr && i<AIRPDCAP_MAX_KEYS_NR; i++) {
- keys[j].KeyType=ctx->keys[i].KeyType;
- memcpy(&keys[j].KeyData, &ctx->keys[i].KeyData, sizeof(keys[j].KeyData));
- j++;
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "Got a key", AIRPDCAP_DEBUG_LEVEL_5);
- }
-
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
- return j;
- }
- }
-
- INT AirPDcapInitContext(
- PAIRPDCAP_CONTEXT ctx)
- {
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapInitContext");
-
- if (ctx==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
- return AIRPDCAP_RET_UNSUCCESS;
- }
-
- AirPDcapCleanKeys(ctx);
-
- ctx->first_free_index=0;
- ctx->index=-1;
- ctx->last_stored_index=-1;
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "Context initialized!", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
- return AIRPDCAP_RET_SUCCESS;
- }
-
- INT AirPDcapDestroyContext(
- PAIRPDCAP_CONTEXT ctx)
- {
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapDestroyContext");
-
- if (ctx==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
- return AIRPDCAP_RET_UNSUCCESS;
- }
-
- AirPDcapCleanKeys(ctx);
-
- ctx->first_free_index=0;
- ctx->index=-1;
- ctx->last_stored_index=-1;
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "Context destroyed!", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
- return AIRPDCAP_RET_SUCCESS;
- }
+ ctx->keys[success].KeyType=keys[i].KeyType;
+ memcpy(&ctx->keys[success].KeyData, &keys[i].KeyData, sizeof(keys[i].KeyData));
+
+ success++;
+ }
+ }
+
+ ctx->keys_nr=success;
+
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
+ return success;
+}
+
+INT AirPDcapCleanKeys(
+ PAIRPDCAP_CONTEXT ctx)
+{
+ INT i;
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapCleanKeys");
+
+ if (ctx==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
+ return 0;
+ }
+
+ for (i=0; i<AIRPDCAP_MAX_KEYS_NR; i++) {
+ memset(&ctx->keys[i], 0, sizeof(AIRPDCAP_KEY_ITEM));
+ }
+
+ ctx->keys_nr=0;
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "Keys collection cleaned!", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
+
+ return i;
+}
+
+INT AirPDcapGetKeys(
+ const PAIRPDCAP_CONTEXT ctx,
+ AIRPDCAP_KEY_ITEM keys[],
+ const size_t keys_nr)
+{
+ UINT i;
+ UINT j;
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapGetKeys");
+
+ if (ctx==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
+ return 0;
+ } else if (keys==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL keys array", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
+ return (INT)ctx->keys_nr;
+ } else {
+ for (i=0, j=0; i<ctx->keys_nr && i<keys_nr && i<AIRPDCAP_MAX_KEYS_NR; i++) {
+ keys[j].KeyType=ctx->keys[i].KeyType;
+ memcpy(&keys[j].KeyData, &ctx->keys[i].KeyData, sizeof(keys[j].KeyData));
+ j++;
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "Got a key", AIRPDCAP_DEBUG_LEVEL_5);
+ }
+
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
+ return j;
+ }
+}
+
+INT AirPDcapInitContext(
+ PAIRPDCAP_CONTEXT ctx)
+{
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapInitContext");
+
+ if (ctx==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
+ return AIRPDCAP_RET_UNSUCCESS;
+ }
+
+ AirPDcapCleanKeys(ctx);
+
+ ctx->first_free_index=0;
+ ctx->index=-1;
+ ctx->last_stored_index=-1;
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "Context initialized!", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
+ return AIRPDCAP_RET_SUCCESS;
+}
+
+INT AirPDcapDestroyContext(
+ PAIRPDCAP_CONTEXT ctx)
+{
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapDestroyContext");
+
+ if (ctx==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
+ return AIRPDCAP_RET_UNSUCCESS;
+ }
+
+ AirPDcapCleanKeys(ctx);
+
+ ctx->first_free_index=0;
+ ctx->index=-1;
+ ctx->last_stored_index=-1;
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "Context destroyed!", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
+ return AIRPDCAP_RET_SUCCESS;
+}
#ifdef __cplusplus
}
@@ -595,756 +575,756 @@ extern "C" {
extern "C" {
#endif
- INT AirPDcapRsnaMng(
- UCHAR *decrypt_data,
- size_t *decrypt_len,
- PAIRPDCAP_KEY_ITEM key,
- AIRPDCAP_SEC_ASSOCIATION *sa,
- INT offset,
- UINT8 fcsPresent)
- {
- INT ret_value;
- ULONG crc;
-
- if (sa->key==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3);
- return AIRPDCAP_RET_REQ_DATA;
- }
- if (sa->validKey==FALSE) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Key not yet valid", AIRPDCAP_DEBUG_LEVEL_3);
- return AIRPDCAP_RET_UNSUCCESS;
- }
- if (sa->wpa.key_ver==1) {
- /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP", AIRPDCAP_DEBUG_LEVEL_3);
-
- ret_value=AirPDcapTkipDecrypt(decrypt_data+offset, *decrypt_len-offset, decrypt_data+AIRPDCAP_TA_OFFSET, AIRPDCAP_GET_TK(sa->wpa.ptk));
- if (ret_value)
- return ret_value;
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
- /* remove MIC (8bytes) and ICV (4bytes) from the end of packet */
- *decrypt_len-=12;
- } else {
- /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3);
-
- ret_value=AirPDcapCcmpDecrypt(decrypt_data, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk));
- if (ret_value)
- return ret_value;
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
- /* remove MIC (8bytes) from the end of packet */
- *decrypt_len-=8;
- }
-
- /* remove protection bit */
- decrypt_data[1]&=0xBF;
-
- /* remove TKIP/CCMP header */
- offset=AIRPDCAP_HEADER_LEN(decrypt_data[1]);
- *decrypt_len-=8;
- memcpy(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset);
-
- if (fcsPresent) {
- /* calculate FCS */
- AirPDcapAlgCrc32(decrypt_data, *decrypt_len, &crc);
- *(unsigned long*)(decrypt_data+*decrypt_len)=crc;
-
- /* add FCS in packet */
- *decrypt_len+=4;
- }
-
- if (key!=NULL) {
- memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM));
-
- if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_CCMP)
- key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
- else if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
- key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
- }
-
- return AIRPDCAP_RET_SUCCESS;
- }
-
- INT AirPDcapWepMng(
- PAIRPDCAP_CONTEXT ctx,
- UCHAR *decrypt_data,
- size_t *decrypt_len,
- PAIRPDCAP_KEY_ITEM key,
- AIRPDCAP_SEC_ASSOCIATION *sa,
- INT offset,
- UINT8 fcsPresent)
- {
- UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN];
- size_t keylen;
- INT ret_value=1;
- ULONG crc;
- INT key_index;
- AIRPDCAP_KEY_ITEM *tmp_key;
- UINT8 useCache=FALSE;
-
- if (sa->key!=NULL)
- useCache=TRUE;
-
- for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
- /* use the cached one, or try all keys */
- if (!useCache) {
- tmp_key=&ctx->keys[key_index];
- } else {
- if (sa->key!=NULL && sa->key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try cached WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
- tmp_key=sa->key;
- } else {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Cached key is not valid, try another WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
- tmp_key=&ctx->keys[key_index];
- }
- }
-
- /* obviously, try only WEP keys... */
- if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP)
- {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
-
- memset(wep_key, 0, sizeof(wep_key));
-
- /* Costruct the WEP seed: copy the IV in first 3 bytes and then the WEP key (refer to 802-11i-2004, 8.2.1.4.3, pag. 36) */
- memcpy(wep_key, decrypt_data+AIRPDCAP_HEADER_LEN(decrypt_data[1]), AIRPDCAP_WEP_IVLEN);
- keylen=tmp_key->KeyData.Wep.WepKeyLen;
- memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
-
- ret_value=AirPDcapWepDecrypt(wep_key,
- keylen+AIRPDCAP_WEP_IVLEN,
- decrypt_data + (AIRPDCAP_HEADER_LEN(decrypt_data[1])+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN),
- *decrypt_len-(AIRPDCAP_HEADER_LEN(decrypt_data[1])+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN));
-
- }
-
- if (!ret_value && tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
- /* the tried key is the correct one, cached in the Security Association */
-
- sa->key=tmp_key;
-
- if (key!=NULL) {
- memcpy(key, &sa->key, sizeof(AIRPDCAP_KEY_ITEM));
- key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
- }
-
- break;
- } else {
- /* the cached key was not valid, try other keys */
-
- if (useCache==TRUE) {
- useCache=FALSE;
- key_index--;
- }
- }
- }
-
- if (ret_value)
- return ret_value;
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "WEP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
-
- /* remove ICV (4bytes) from the end of packet */
- *decrypt_len-=4;
-
- /* remove protection bit */
- decrypt_data[1]&=0xBF;
-
- /* remove IC header */
- offset=AIRPDCAP_HEADER_LEN(decrypt_data[1]);
- *decrypt_len-=4;
- memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset);
-
- if (fcsPresent) {
- /* calculate FCS and append it at the end of the decrypted packet */
- AirPDcapAlgCrc32(decrypt_data, *decrypt_len, &crc);
- *(unsigned long*)(decrypt_data+*decrypt_len)=crc;
-
- /* add FCS in packet */
- *decrypt_len += 4;
- }
-
- return AIRPDCAP_RET_SUCCESS;
- }
-
- /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
- INT AirPDcapRsna4WHandshake(
- PAIRPDCAP_CONTEXT ctx,
- const UCHAR *data,
- AIRPDCAP_SEC_ASSOCIATION *sa,
- PAIRPDCAP_KEY_ITEM key,
- INT offset)
- {
- AIRPDCAP_KEY_ITEM *tmp_key;
- INT key_index;
- INT ret_value=1;
- UCHAR useCache=FALSE;
- UCHAR eapol[AIRPDCAP_EAPOL_MAX_LEN];
- USHORT eapol_len;
-
- if (sa->key!=NULL)
- useCache=TRUE;
-
- /* a 4-way handshake packet use a Pairwise key type (IEEE 802.11i-2004, pg. 79) */
- if (AIRPDCAP_EAP_KEY(data[offset+1])!=1) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Group/STAKey message (not used)", AIRPDCAP_DEBUG_LEVEL_5);
- return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
- }
-
- /* TODO timeouts? reauthentication? */
-
- /* TODO consider key-index */
-
- /* TODO considera Deauthentications */
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake...", AIRPDCAP_DEBUG_LEVEL_5);
-
- /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
-
- /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
- if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
- AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
- AIRPDCAP_EAP_MIC(data[offset])==0)
- {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 1", AIRPDCAP_DEBUG_LEVEL_3);
-
- /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been */
- /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current */
- /* local value, the Supplicant discards the message. */
- /* -> not checked, the Authenticator will be send another Message 1 (hopefully!) */
-
- /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
- memcpy(sa->wpa.nonce, data+offset+12, 32);
-
- /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
- sa->wpa.key_ver=AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]);
-
- sa->handshake=1;
-
- return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
- }
-
- /* message 2|4: Supplicant->Authenticator (Sec=0|1, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=SNonce|0, MIC=MIC(KCK,EAPOL)) */
- if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
- AIRPDCAP_EAP_ACK(data[offset+1])==0 &&
- AIRPDCAP_EAP_MIC(data[offset])==1)
- {
- if (AIRPDCAP_EAP_SEC(data[offset])==0) {
-
- /* PATCH: some implementations set secure bit to 0 also in the 4th message */
- /* to recognize which message is this check if wep_key data lenght is 0 */
- /* in the 4th message */
- if (*(UINT16 *)(data+offset+92)!=0) {
- /* message 2 */
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 2", AIRPDCAP_DEBUG_LEVEL_3);
-
- /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
- /* outstanding Message 1. If not, it silently discards the message. */
- /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, */
- /* the Authenticator silently discards Message 2. */
- /* -> not checked; the Supplicant will send another message 2 (hopefully!) */
-
- /* now you can derive the PTK */
- for (key_index=0; key_index<(INT)ctx->keys_nr || sa->key!=NULL; key_index++) {
- /* use the cached one, or try all keys */
- if (!useCache) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
- tmp_key=&ctx->keys[key_index];
- } else {
- /* there is a cached key in the security association, if it's a WPA key try it... */
- if (sa->key!=NULL &&
- sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
- sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
- sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try cached WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
- tmp_key=sa->key;
- } else {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Cached key is of a wrong type, try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
- tmp_key=&ctx->keys[key_index];
- }
- }
-
- /* obviously, try only WPA keys... */
- if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
- tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
- tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)
- {
- /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
- AirPDcapRsnaPrfX(sa, /* authenticator nonce, bssid, station mac */
- tmp_key->KeyData.Wpa.Pmk, /* PMK */
- data+offset+12, /* supplicant nonce */
- 512,
- sa->wpa.ptk);
-
- /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK) */
- eapol_len=(USHORT)(ntohs(*(UINT16 *)(data+offset-3))+4);
- memcpy(eapol, &data[offset-5], (eapol_len<AIRPDCAP_EAPOL_MAX_LEN?eapol_len:AIRPDCAP_EAPOL_MAX_LEN));
- ret_value=AirPDcapRsnaMicCheck(eapol, /* eapol frame (header also) */
- eapol_len, /* eapol frame length */
- sa->wpa.ptk, /* Key Confirmation Key */
- AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])); /* EAPOL-Key description version */
-
- /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches */
- /* that from the (Re)Association Request message. */
- /* i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
- /* primitive to terminate the association. */
- /* ii) If they do match bit-wise, the Authenticator constructs Message 3. */
- }
-
- if (!ret_value &&
- (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
- tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
- tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK))
- {
- /* the temporary key is the correct one, cached in the Security Association */
-
- sa->key=tmp_key;
-
- if (key!=NULL) {
- memcpy(key, &tmp_key, sizeof(AIRPDCAP_KEY_ITEM));
- if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_CCMP)
- key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
- else if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
- key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
- }
-
- break;
- } else {
- /* the cached key was not valid, try other keys */
-
- if (useCache==TRUE) {
- useCache=FALSE;
- key_index--;
- }
- }
- }
-
- if (ret_value) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "handshake step failed", AIRPDCAP_DEBUG_LEVEL_3);
- return ret_value;
- }
-
- sa->handshake=2;
-
- return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
- } else {
- /* message 4 */
-
- /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
-
- /* TODO check MIC and Replay Counter */
- /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
- /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
- /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
- /* Authenticator silently discards Message 4. */
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4 (patched)", AIRPDCAP_DEBUG_LEVEL_3);
-
- sa->handshake=4;
-
- sa->validKey=TRUE;
-
- return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
- }
- /* END OF PATCH */
- /* */
- } else {
- /* message 4 */
-
- /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
-
- /* TODO check MIC and Replay Counter */
- /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
- /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
- /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
- /* Authenticator silently discards Message 4. */
-
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4", AIRPDCAP_DEBUG_LEVEL_3);
-
- sa->handshake=4;
-
- sa->validKey=TRUE;
-
- return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
- }
- }
-
- /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
- if (AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
- AIRPDCAP_EAP_MIC(data[offset])==1)
- {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 3", AIRPDCAP_DEBUG_LEVEL_3);
-
- /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field */
- /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
- /* -> not checked, the Authenticator will send another message 3 (hopefully!) */
-
- /* TODO check page 88 (RNS) */
-
- return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
- }
-
- return AIRPDCAP_RET_UNSUCCESS;
- }
-
- INT AirPDcapRsnaMicCheck(
- UCHAR *eapol,
- const USHORT eapol_len,
- const UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
- const USHORT key_ver)
- {
- UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN];
- UCHAR c_mic[20]; /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */
-
- /* copy the MIC from the EAPOL packet */
- memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN);
-
- /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
- memset(eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, 0, AIRPDCAP_WPA_MICKEY_LEN);
-
- if (key_ver==AIRPDCAP_WPA_KEY_VER_CCMP) {
- /* use HMAC-MD5 for the EAPOL-Key MIC */
- AirPDcapAlgHmacMd5((UCHAR *)KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
- } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) {
- /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
- AirPDcapAlgHmacSha1(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
- } else
- /* key descriptor version not recognized */
- return AIRPDCAP_RET_UNSUCCESS;
-
- /* compare calculated MIC with the Key MIC and return result (0 means success) */
- return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN);
- }
-
- INT AirPDcapValidateKey(
- PAIRPDCAP_KEY_ITEM key)
- {
- size_t len;
- UCHAR ret=TRUE;
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
-
- if (key==NULL) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "NULL key", AIRPDCAP_DEBUG_LEVEL_5);
- AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
- return FALSE;
- }
-
- switch (key->KeyType) {
- case AIRPDCAP_KEY_TYPE_WEP:
- /* check key size limits */
- len=key->KeyData.Wep.WepKeyLen;
- if (len<AIRPDCAP_WEP_KEY_MINLEN || len>AIRPDCAP_WEP_KEY_MAXLEN) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WEP key: key length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
- ret=FALSE;
- }
- break;
-
- case AIRPDCAP_KEY_TYPE_WEP_40:
- /* set the standard length and use a generic WEP key type */
- key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_40_KEY_LEN;
- key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
- break;
-
- case AIRPDCAP_KEY_TYPE_WEP_104:
- /* set the standard length and use a generic WEP key type */
- key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_104_KEY_LEN;
- key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
- break;
-
- case AIRPDCAP_KEY_TYPE_WPA_PWD:
- /* check passphrase and SSID size limits */
- len=strlen(key->KeyData.Wpa.UserPwd.Passphrase);
- if (len<AIRPDCAP_WPA_PASSPHRASE_MIN_LEN || len>AIRPDCAP_WPA_PASSPHRASE_MAX_LEN) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: passphrase length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
- ret=FALSE;
- }
-
- len=key->KeyData.Wpa.UserPwd.SsidLen;
- if (len<AIRPDCAP_WPA_SSID_MIN_LEN || len>AIRPDCAP_WPA_SSID_MAX_LEN) {
- AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: ssid length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
- ret=FALSE;
- }
-
- break;
-
- case AIRPDCAP_KEY_TYPE_WPA_PSK:
- break;
-
- case AIRPDCAP_KEY_TYPE_WPA_PMK:
- break;
-
- default:
- ret=FALSE;
- }
-
- AIRPDCAP_DEBUG_TRACE_END("AirPDcapValidateKey");
- return ret;
- }
-
- INT AirPDcapGetSa(
- PAIRPDCAP_CONTEXT ctx,
- AIRPDCAP_SEC_ASSOCIATION_ID *id)
- {
- INT index;
-
- if (ctx->last_stored_index!=-1) {
- /* at least one association was stored */
- /* search for the association from last_stored_index to 0 (most recent added) */
- for (index=ctx->last_stored_index; index>=0; index--) {
- if (ctx->sa[index].used) {
- if (memcmp(id, &(ctx->sa[index].saId), sizeof(AIRPDCAP_SEC_ASSOCIATION_ID))==0) {
- ctx->index=index;
- return index;
- }
- }
- }
- }
-
- return -1;
- }
-
- INT AirPDcapFreeSa(
- PAIRPDCAP_CONTEXT ctx,
- INT index) /* index of the structure to free */
- {
- /* set the structure as free (the reset will be done in AIRPDCAP_store_sta_info) */
- ctx->sa[index].used=0;
-
- /* set the first_free_index to avoid free blocks in the middle */
- if (index<ctx->first_free_index)
- ctx->first_free_index=index;
-
- /* decrement the last_stored_index if this was the last stored block */
- if (index==ctx->last_stored_index)
- ctx->last_stored_index--;
-
- /* if the list is empty, set the index */
- if (ctx->last_stored_index==-1)
- ctx->index=-1;
-
- return ctx->index;
- }
-
- INT AirPDcapStoreSa(
- PAIRPDCAP_CONTEXT ctx,
- AIRPDCAP_SEC_ASSOCIATION_ID *id)
- {
- INT last_free;
-
- if (ctx->sa[ctx->first_free_index].used) {
- /* last addition was in the middle of the array (and the first_free_index was just incremented by 1) */
- /* search for a free space from the first_free_index to AIRPDCAP_STA_INFOS_NR (to avoid free blocks in */
- /* the middle) */
- for (last_free=ctx->first_free_index; last_free<AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; last_free++)
- if (!ctx->sa[last_free].used)
- break;
-
- if (last_free>=AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR) {
- /* there is no empty space available. FAILURE */
- return -1;
- }
-
- /* store first free space index */
- ctx->first_free_index=last_free;
- }
-
- /* use this info */
- ctx->index=ctx->first_free_index;
-
- /* reset the info structure */
- memset(ctx->sa+ctx->index, 0, sizeof(AIRPDCAP_SEC_ASSOCIATION));
-
- ctx->sa[ctx->index].used=1;
-
- /* set the info structure */
- memcpy(&(ctx->sa[ctx->index].saId), id, sizeof(AIRPDCAP_SEC_ASSOCIATION_ID));
-
- /* increment by 1 the first_free_index (heuristic) */
- ctx->first_free_index++;
-
- /* set the last_stored_index if the added index is greater the the last_stored_index */
- if (ctx->index > ctx->last_stored_index)
- ctx->last_stored_index=ctx->index;
-
- return ctx->index;
- }
-
- UCHAR * AirPDcapGetStaAddress(
- PAIRPDCAP_MAC_FRAME frame)
- {
- if (AIRPDCAP_TO_DS(frame->fc[1])==0) {
- if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
- return NULL;
- else
- return frame->addr1;
- } else {
- if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
- return frame->addr2;
- else
- return NULL;
- }
- }
-
- UCHAR * AirPDcapGetBssidAddress(
- PAIRPDCAP_MAC_FRAME frame)
- {
- if (AIRPDCAP_TO_DS(frame->fc[1])==0) {
- if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
- return frame->addr3;
- else
- return frame->addr2;
- } else {
- if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
- return frame->addr1;
- else
- return NULL;
- }
- }
-
- /* Function used to derive the PTK. Refer to IEEE 802.11I-2004, pag. 74 */
- void AirPDcapRsnaPrfX(
- AIRPDCAP_SEC_ASSOCIATION *sa,
- const UCHAR pmk[32],
- const UCHAR snonce[32],
- const INT x, /* for TKIP 512, for CCMP 384 */
- UCHAR *ptk)
- {
- UINT8 i;
- UCHAR R[100];
- INT offset=sizeof("Pairwise key expansion");
-
- memset(R, 0, 100);
-
- memcpy(R, "Pairwise key expansion", offset);
-
- /* Min(AA, SPA) || Max(AA, SPA) */
- if (memcmp(sa->saId.sta, sa->saId.bssid, AIRPDCAP_MAC_LEN) < 0)
- {
- memcpy(R + offset, sa->saId.sta, AIRPDCAP_MAC_LEN);
- memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.bssid, AIRPDCAP_MAC_LEN);
- }
- else
- {
- memcpy(R + offset, sa->saId.bssid, AIRPDCAP_MAC_LEN);
- memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.sta, AIRPDCAP_MAC_LEN);
- }
-
- offset+=AIRPDCAP_MAC_LEN*2;
-
- /* Min(ANonce,SNonce) || Max(ANonce,SNonce) */
- if( memcmp(snonce, sa->wpa.nonce, 32) < 0 )
- {
- memcpy(R + offset, snonce, 32);
- memcpy(R + offset + 32, sa->wpa.nonce, 32);
- }
- else
- {
- memcpy(R + offset, sa->wpa.nonce, 32);
- memcpy(R + offset + 32, snonce, 32);
- }
-
- offset+=32*2;
-
- for(i = 0; i < (x+159)/160; i++)
- {
- R[offset] = i;
- AirPDcapAlgHmacSha1(pmk, 32, R, 100, ptk + i * 20);
- }
- }
-
- INT AirPDcapRsnaPwd2PskStep(
- const CHAR *password,
- const CHAR *ssid,
- const size_t ssidLength,
- const INT iterations,
- const INT count,
- UCHAR *output)
- {
- UCHAR digest[36], digest1[AIRPDCAP_SHA_DIGEST_LEN];
- INT i, j;
-
- /* U1 = PRF(P, S || INT(i)) */
- memcpy(digest, ssid, ssidLength);
- digest[ssidLength] = (UCHAR)((count>>24) & 0xff);
- digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff);
- digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff);
- digest[ssidLength+3] = (UCHAR)(count & 0xff);
- AirPDcapAlgHmacSha1((UCHAR *)password, strlen(password), digest, ssidLength+4, digest1);
-
- /* output = U1 */
- memcpy(output, digest1, AIRPDCAP_SHA_DIGEST_LEN);
- for (i = 1; i < iterations; i++) {
- /* Un = PRF(P, Un-1) */
- AirPDcapAlgHmacSha1((UCHAR *)password, strlen(password), digest1, AIRPDCAP_SHA_DIGEST_LEN, digest);
-
- memcpy(digest1, digest, AIRPDCAP_SHA_DIGEST_LEN);
- /* output = output xor Un */
- for (j = 0; j < AIRPDCAP_SHA_DIGEST_LEN; j++) {
- output[j] ^= digest[j];
- }
- }
-
- return AIRPDCAP_RET_SUCCESS;
- }
-
- INT AirPDcapRsnaPwd2Psk(
- const CHAR *password,
- const CHAR *ssid,
- const size_t ssidLength,
- UCHAR *output)
- {
- UCHAR m_output[AIRPDCAP_WPA_PSK_LEN];
-
- memset(m_output, 0, AIRPDCAP_WPA_PSK_LEN);
-
- memset(m_output, 0, 40);
-
- AirPDcapRsnaPwd2PskStep(password, ssid, ssidLength, 4096, 1, m_output);
- AirPDcapRsnaPwd2PskStep(password, ssid, ssidLength, 4096, 2, &m_output[AIRPDCAP_SHA_DIGEST_LEN]);
-
- memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN);
-
- return 0;
- }
-
- /**************************************************************************/
- /* The following code come from freeBSD and implements the AUTODIN II
- /* polynomial used by 802.11.
- /* It can be used to calculate multicast address hash indices.
- /* It assumes that the low order bits will be transmitted first,
- /* and consequently the low byte should be sent first when
- /* the crc computation is finished. The crc should be complemented
- /* before transmission.
- /* The variable corresponding to the macro argument "crc" should
- /* be an unsigned long and should be preset to all ones for Ethernet
- /* use. An error-free packet will leave 0xDEBB20E3 in the crc.
- /**************************************************************************/
- INT AirPDcapAlgCrc32(
- UCHAR *buf,
- size_t nr,
- ULONG *cval)
- {
- ULONG crc32_total = 0 ;
- ULONG crc = ~(ULONG)0;
- UCHAR *p ;
- size_t len;
-
- len = 0 ;
- crc32_total = ~crc32_total ;
-
- for(len += nr, p = buf; nr--; ++p)
- {
- CRC(crc, *p) ;
- CRC(crc32_total, *p) ;
- }
-
- *cval = ~crc ;
- crc32_total = ~crc32_total ;
-
- return 0;
- }
+INT AirPDcapRsnaMng(
+ UCHAR *decrypt_data,
+ size_t *decrypt_len,
+ PAIRPDCAP_KEY_ITEM key,
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ INT offset,
+ UINT8 fcsPresent)
+{
+ INT ret_value;
+ ULONG crc;
+
+ if (sa->key==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3);
+ return AIRPDCAP_RET_REQ_DATA;
+ }
+ if (sa->validKey==FALSE) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Key not yet valid", AIRPDCAP_DEBUG_LEVEL_3);
+ return AIRPDCAP_RET_UNSUCCESS;
+ }
+ if (sa->wpa.key_ver==1) {
+ /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP", AIRPDCAP_DEBUG_LEVEL_3);
+
+ ret_value=AirPDcapTkipDecrypt(decrypt_data+offset, *decrypt_len-offset, decrypt_data+AIRPDCAP_TA_OFFSET, AIRPDCAP_GET_TK(sa->wpa.ptk));
+ if (ret_value)
+ return ret_value;
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
+ /* remove MIC (8bytes) and ICV (4bytes) from the end of packet */
+ *decrypt_len-=12;
+ } else {
+ /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3);
+
+ ret_value=AirPDcapCcmpDecrypt(decrypt_data, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk));
+ if (ret_value)
+ return ret_value;
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
+ /* remove MIC (8bytes) from the end of packet */
+ *decrypt_len-=8;
+ }
+
+ /* remove protection bit */
+ decrypt_data[1]&=0xBF;
+
+ /* remove TKIP/CCMP header */
+ offset=AIRPDCAP_HEADER_LEN(decrypt_data[1]);
+ *decrypt_len-=8;
+ memcpy(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset);
+
+ if (fcsPresent) {
+ /* calculate FCS */
+ AirPDcapAlgCrc32(decrypt_data, *decrypt_len, &crc);
+ *(unsigned long*)(decrypt_data+*decrypt_len)=crc;
+
+ /* add FCS in packet */
+ *decrypt_len+=4;
+ }
+
+ if (key!=NULL) {
+ memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM));
+
+ if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_CCMP)
+ key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
+ else if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
+ key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
+ }
+
+ return AIRPDCAP_RET_SUCCESS;
+}
+
+INT AirPDcapWepMng(
+ PAIRPDCAP_CONTEXT ctx,
+ UCHAR *decrypt_data,
+ size_t *decrypt_len,
+ PAIRPDCAP_KEY_ITEM key,
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ INT offset,
+ UINT8 fcsPresent)
+{
+ UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN];
+ size_t keylen;
+ INT ret_value=1;
+ ULONG crc;
+ INT key_index;
+ AIRPDCAP_KEY_ITEM *tmp_key;
+ UINT8 useCache=FALSE;
+
+ if (sa->key!=NULL)
+ useCache=TRUE;
+
+ for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
+ /* use the cached one, or try all keys */
+ if (!useCache) {
+ tmp_key=&ctx->keys[key_index];
+ } else {
+ if (sa->key!=NULL && sa->key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try cached WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
+ tmp_key=sa->key;
+ } else {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Cached key is not valid, try another WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
+ tmp_key=&ctx->keys[key_index];
+ }
+ }
+
+ /* obviously, try only WEP keys... */
+ if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP)
+ {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
+
+ memset(wep_key, 0, sizeof(wep_key));
+
+ /* Costruct the WEP seed: copy the IV in first 3 bytes and then the WEP key (refer to 802-11i-2004, 8.2.1.4.3, pag. 36) */
+ memcpy(wep_key, decrypt_data+AIRPDCAP_HEADER_LEN(decrypt_data[1]), AIRPDCAP_WEP_IVLEN);
+ keylen=tmp_key->KeyData.Wep.WepKeyLen;
+ memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
+
+ ret_value=AirPDcapWepDecrypt(wep_key,
+ keylen+AIRPDCAP_WEP_IVLEN,
+ decrypt_data + (AIRPDCAP_HEADER_LEN(decrypt_data[1])+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN),
+ *decrypt_len-(AIRPDCAP_HEADER_LEN(decrypt_data[1])+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN));
+
+ }
+
+ if (!ret_value && tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
+ /* the tried key is the correct one, cached in the Security Association */
+
+ sa->key=tmp_key;
+
+ if (key!=NULL) {
+ memcpy(key, &sa->key, sizeof(AIRPDCAP_KEY_ITEM));
+ key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
+ }
+
+ break;
+ } else {
+ /* the cached key was not valid, try other keys */
+
+ if (useCache==TRUE) {
+ useCache=FALSE;
+ key_index--;
+ }
+ }
+ }
+
+ if (ret_value)
+ return ret_value;
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "WEP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
+
+ /* remove ICV (4bytes) from the end of packet */
+ *decrypt_len-=4;
+
+ /* remove protection bit */
+ decrypt_data[1]&=0xBF;
+
+ /* remove IC header */
+ offset=AIRPDCAP_HEADER_LEN(decrypt_data[1]);
+ *decrypt_len-=4;
+ memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset);
+
+ if (fcsPresent) {
+ /* calculate FCS and append it at the end of the decrypted packet */
+ AirPDcapAlgCrc32(decrypt_data, *decrypt_len, &crc);
+ *(unsigned long*)(decrypt_data+*decrypt_len)=crc;
+
+ /* add FCS in packet */
+ *decrypt_len += 4;
+ }
+
+ return AIRPDCAP_RET_SUCCESS;
+}
+
+/* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
+INT AirPDcapRsna4WHandshake(
+ PAIRPDCAP_CONTEXT ctx,
+ const UCHAR *data,
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ PAIRPDCAP_KEY_ITEM key,
+ INT offset)
+{
+ AIRPDCAP_KEY_ITEM *tmp_key;
+ INT key_index;
+ INT ret_value=1;
+ UCHAR useCache=FALSE;
+ UCHAR eapol[AIRPDCAP_EAPOL_MAX_LEN];
+ USHORT eapol_len;
+
+ if (sa->key!=NULL)
+ useCache=TRUE;
+
+ /* a 4-way handshake packet use a Pairwise key type (IEEE 802.11i-2004, pg. 79) */
+ if (AIRPDCAP_EAP_KEY(data[offset+1])!=1) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Group/STAKey message (not used)", AIRPDCAP_DEBUG_LEVEL_5);
+ return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
+ }
+
+ /* TODO timeouts? reauthentication? */
+
+ /* TODO consider key-index */
+
+ /* TODO considera Deauthentications */
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake...", AIRPDCAP_DEBUG_LEVEL_5);
+
+ /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
+
+ /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
+ if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
+ AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
+ AIRPDCAP_EAP_MIC(data[offset])==0)
+ {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 1", AIRPDCAP_DEBUG_LEVEL_3);
+
+ /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been */
+ /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current */
+ /* local value, the Supplicant discards the message. */
+ /* -> not checked, the Authenticator will be send another Message 1 (hopefully!) */
+
+ /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
+ memcpy(sa->wpa.nonce, data+offset+12, 32);
+
+ /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
+ sa->wpa.key_ver=AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]);
+
+ sa->handshake=1;
+
+ return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
+ }
+
+ /* message 2|4: Supplicant->Authenticator (Sec=0|1, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=SNonce|0, MIC=MIC(KCK,EAPOL)) */
+ if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
+ AIRPDCAP_EAP_ACK(data[offset+1])==0 &&
+ AIRPDCAP_EAP_MIC(data[offset])==1)
+ {
+ if (AIRPDCAP_EAP_SEC(data[offset])==0) {
+
+ /* PATCH: some implementations set secure bit to 0 also in the 4th message */
+ /* to recognize which message is this check if wep_key data lenght is 0 */
+ /* in the 4th message */
+ if (*(UINT16 *)(data+offset+92)!=0) {
+ /* message 2 */
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 2", AIRPDCAP_DEBUG_LEVEL_3);
+
+ /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
+ /* outstanding Message 1. If not, it silently discards the message. */
+ /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, */
+ /* the Authenticator silently discards Message 2. */
+ /* -> not checked; the Supplicant will send another message 2 (hopefully!) */
+
+ /* now you can derive the PTK */
+ for (key_index=0; key_index<(INT)ctx->keys_nr || sa->key!=NULL; key_index++) {
+ /* use the cached one, or try all keys */
+ if (!useCache) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
+ tmp_key=&ctx->keys[key_index];
+ } else {
+ /* there is a cached key in the security association, if it's a WPA key try it... */
+ if (sa->key!=NULL &&
+ sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
+ sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
+ sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try cached WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
+ tmp_key=sa->key;
+ } else {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Cached key is of a wrong type, try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
+ tmp_key=&ctx->keys[key_index];
+ }
+ }
+
+ /* obviously, try only WPA keys... */
+ if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
+ tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
+ tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)
+ {
+ /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
+ AirPDcapRsnaPrfX(sa, /* authenticator nonce, bssid, station mac */
+ tmp_key->KeyData.Wpa.Pmk, /* PMK */
+ data+offset+12, /* supplicant nonce */
+ 512,
+ sa->wpa.ptk);
+
+ /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK) */
+ eapol_len=(USHORT)(ntohs(*(UINT16 *)(data+offset-3))+4);
+ memcpy(eapol, &data[offset-5], (eapol_len<AIRPDCAP_EAPOL_MAX_LEN?eapol_len:AIRPDCAP_EAPOL_MAX_LEN));
+ ret_value=AirPDcapRsnaMicCheck(eapol, /* eapol frame (header also) */
+ eapol_len, /* eapol frame length */
+ sa->wpa.ptk, /* Key Confirmation Key */
+ AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])); /* EAPOL-Key description version */
+
+ /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches */
+ /* that from the (Re)Association Request message. */
+ /* i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
+ /* primitive to terminate the association. */
+ /* ii) If they do match bit-wise, the Authenticator constructs Message 3. */
+ }
+
+ if (!ret_value &&
+ (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
+ tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
+ tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK))
+ {
+ /* the temporary key is the correct one, cached in the Security Association */
+
+ sa->key=tmp_key;
+
+ if (key!=NULL) {
+ memcpy(key, &tmp_key, sizeof(AIRPDCAP_KEY_ITEM));
+ if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_CCMP)
+ key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
+ else if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
+ key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
+ }
+
+ break;
+ } else {
+ /* the cached key was not valid, try other keys */
+
+ if (useCache==TRUE) {
+ useCache=FALSE;
+ key_index--;
+ }
+ }
+ }
+
+ if (ret_value) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "handshake step failed", AIRPDCAP_DEBUG_LEVEL_3);
+ return ret_value;
+ }
+
+ sa->handshake=2;
+
+ return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
+ } else {
+ /* message 4 */
+
+ /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
+
+ /* TODO check MIC and Replay Counter */
+ /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
+ /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
+ /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
+ /* Authenticator silently discards Message 4. */
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4 (patched)", AIRPDCAP_DEBUG_LEVEL_3);
+
+ sa->handshake=4;
+
+ sa->validKey=TRUE;
+
+ return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
+ }
+ /* END OF PATCH */
+ /* */
+ } else {
+ /* message 4 */
+
+ /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
+
+ /* TODO check MIC and Replay Counter */
+ /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
+ /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
+ /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
+ /* Authenticator silently discards Message 4. */
+
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4", AIRPDCAP_DEBUG_LEVEL_3);
+
+ sa->handshake=4;
+
+ sa->validKey=TRUE;
+
+ return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
+ }
+ }
+
+ /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
+ if (AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
+ AIRPDCAP_EAP_MIC(data[offset])==1)
+ {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 3", AIRPDCAP_DEBUG_LEVEL_3);
+
+ /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field */
+ /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
+ /* -> not checked, the Authenticator will send another message 3 (hopefully!) */
+
+ /* TODO check page 88 (RNS) */
+
+ return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
+ }
+
+ return AIRPDCAP_RET_UNSUCCESS;
+}
+
+INT AirPDcapRsnaMicCheck(
+ UCHAR *eapol,
+ const USHORT eapol_len,
+ const UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
+ const USHORT key_ver)
+{
+ UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN];
+ UCHAR c_mic[20]; /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */
+
+ /* copy the MIC from the EAPOL packet */
+ memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN);
+
+ /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
+ memset(eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, 0, AIRPDCAP_WPA_MICKEY_LEN);
+
+ if (key_ver==AIRPDCAP_WPA_KEY_VER_CCMP) {
+ /* use HMAC-MD5 for the EAPOL-Key MIC */
+ AirPDcapAlgHmacMd5((UCHAR *)KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
+ } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) {
+ /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
+ AirPDcapAlgHmacSha1(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
+ } else
+ /* key descriptor version not recognized */
+ return AIRPDCAP_RET_UNSUCCESS;
+
+ /* compare calculated MIC with the Key MIC and return result (0 means success) */
+ return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN);
+}
+
+INT AirPDcapValidateKey(
+ PAIRPDCAP_KEY_ITEM key)
+{
+ size_t len;
+ UCHAR ret=TRUE;
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
+
+ if (key==NULL) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "NULL key", AIRPDCAP_DEBUG_LEVEL_5);
+ AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
+ return FALSE;
+ }
+
+ switch (key->KeyType) {
+case AIRPDCAP_KEY_TYPE_WEP:
+ /* check key size limits */
+ len=key->KeyData.Wep.WepKeyLen;
+ if (len<AIRPDCAP_WEP_KEY_MINLEN || len>AIRPDCAP_WEP_KEY_MAXLEN) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WEP key: key length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
+ ret=FALSE;
+ }
+ break;
+
+case AIRPDCAP_KEY_TYPE_WEP_40:
+ /* set the standard length and use a generic WEP key type */
+ key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_40_KEY_LEN;
+ key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
+ break;
+
+case AIRPDCAP_KEY_TYPE_WEP_104:
+ /* set the standard length and use a generic WEP key type */
+ key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_104_KEY_LEN;
+ key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
+ break;
+
+case AIRPDCAP_KEY_TYPE_WPA_PWD:
+ /* check passphrase and SSID size limits */
+ len=strlen(key->KeyData.Wpa.UserPwd.Passphrase);
+ if (len<AIRPDCAP_WPA_PASSPHRASE_MIN_LEN || len>AIRPDCAP_WPA_PASSPHRASE_MAX_LEN) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: passphrase length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
+ ret=FALSE;
+ }
+
+ len=key->KeyData.Wpa.UserPwd.SsidLen;
+ if (len<AIRPDCAP_WPA_SSID_MIN_LEN || len>AIRPDCAP_WPA_SSID_MAX_LEN) {
+ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: ssid length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
+ ret=FALSE;
+ }
+
+ break;
+
+case AIRPDCAP_KEY_TYPE_WPA_PSK:
+ break;
+
+case AIRPDCAP_KEY_TYPE_WPA_PMK:
+ break;
+
+default:
+ ret=FALSE;
+ }
+
+ AIRPDCAP_DEBUG_TRACE_END("AirPDcapValidateKey");
+ return ret;
+}
+
+INT AirPDcapGetSa(
+ PAIRPDCAP_CONTEXT ctx,
+ AIRPDCAP_SEC_ASSOCIATION_ID *id)
+{
+ INT index;
+
+ if (ctx->last_stored_index!=-1) {
+ /* at least one association was stored */
+ /* search for the association from last_stored_index to 0 (most recent added) */
+ for (index=ctx->last_stored_index; index>=0; index--) {
+ if (ctx->sa[index].used) {
+ if (memcmp(id, &(ctx->sa[index].saId), sizeof(AIRPDCAP_SEC_ASSOCIATION_ID))==0) {
+ ctx->index=index;
+ return index;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+INT AirPDcapFreeSa(
+ PAIRPDCAP_CONTEXT ctx,
+ INT index) /* index of the structure to free */
+{
+ /* set the structure as free (the reset will be done in AIRPDCAP_store_sta_info) */
+ ctx->sa[index].used=0;
+
+ /* set the first_free_index to avoid free blocks in the middle */
+ if (index<ctx->first_free_index)
+ ctx->first_free_index=index;
+
+ /* decrement the last_stored_index if this was the last stored block */
+ if (index==ctx->last_stored_index)
+ ctx->last_stored_index--;
+
+ /* if the list is empty, set the index */
+ if (ctx->last_stored_index==-1)
+ ctx->index=-1;
+
+ return ctx->index;
+}
+
+INT AirPDcapStoreSa(
+ PAIRPDCAP_CONTEXT ctx,
+ AIRPDCAP_SEC_ASSOCIATION_ID *id)
+{
+ INT last_free;
+
+ if (ctx->sa[ctx->first_free_index].used) {
+ /* last addition was in the middle of the array (and the first_free_index was just incremented by 1) */
+ /* search for a free space from the first_free_index to AIRPDCAP_STA_INFOS_NR (to avoid free blocks in */
+ /* the middle) */
+ for (last_free=ctx->first_free_index; last_free<AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; last_free++)
+ if (!ctx->sa[last_free].used)
+ break;
+
+ if (last_free>=AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR) {
+ /* there is no empty space available. FAILURE */
+ return -1;
+ }
+
+ /* store first free space index */
+ ctx->first_free_index=last_free;
+ }
+
+ /* use this info */
+ ctx->index=ctx->first_free_index;
+
+ /* reset the info structure */
+ memset(ctx->sa+ctx->index, 0, sizeof(AIRPDCAP_SEC_ASSOCIATION));
+
+ ctx->sa[ctx->index].used=1;
+
+ /* set the info structure */
+ memcpy(&(ctx->sa[ctx->index].saId), id, sizeof(AIRPDCAP_SEC_ASSOCIATION_ID));
+
+ /* increment by 1 the first_free_index (heuristic) */
+ ctx->first_free_index++;
+
+ /* set the last_stored_index if the added index is greater the the last_stored_index */
+ if (ctx->index > ctx->last_stored_index)
+ ctx->last_stored_index=ctx->index;
+
+ return ctx->index;
+}
+
+UCHAR * AirPDcapGetStaAddress(
+ PAIRPDCAP_MAC_FRAME frame)
+{
+ if (AIRPDCAP_TO_DS(frame->fc[1])==0) {
+ if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
+ return NULL;
+ else
+ return frame->addr1;
+ } else {
+ if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
+ return frame->addr2;
+ else
+ return NULL;
+ }
+}
+
+UCHAR * AirPDcapGetBssidAddress(
+ PAIRPDCAP_MAC_FRAME frame)
+{
+ if (AIRPDCAP_TO_DS(frame->fc[1])==0) {
+ if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
+ return frame->addr3;
+ else
+ return frame->addr2;
+ } else {
+ if (AIRPDCAP_FROM_DS(frame->fc[1])==0)
+ return frame->addr1;
+ else
+ return NULL;
+ }
+}
+
+/* Function used to derive the PTK. Refer to IEEE 802.11I-2004, pag. 74 */
+void AirPDcapRsnaPrfX(
+ AIRPDCAP_SEC_ASSOCIATION *sa,
+ const UCHAR pmk[32],
+ const UCHAR snonce[32],
+ const INT x, /* for TKIP 512, for CCMP 384 */
+ UCHAR *ptk)
+{
+ UINT8 i;
+ UCHAR R[100];
+ INT offset=sizeof("Pairwise key expansion");
+
+ memset(R, 0, 100);
+
+ memcpy(R, "Pairwise key expansion", offset);
+
+ /* Min(AA, SPA) || Max(AA, SPA) */
+ if (memcmp(sa->saId.sta, sa->saId.bssid, AIRPDCAP_MAC_LEN) < 0)
+ {
+ memcpy(R + offset, sa->saId.sta, AIRPDCAP_MAC_LEN);
+ memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.bssid, AIRPDCAP_MAC_LEN);
+ }
+ else
+ {
+ memcpy(R + offset, sa->saId.bssid, AIRPDCAP_MAC_LEN);
+ memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.sta, AIRPDCAP_MAC_LEN);
+ }
+
+ offset+=AIRPDCAP_MAC_LEN*2;
+
+ /* Min(ANonce,SNonce) || Max(ANonce,SNonce) */
+ if( memcmp(snonce, sa->wpa.nonce, 32) < 0 )
+ {
+ memcpy(R + offset, snonce, 32);
+ memcpy(R + offset + 32, sa->wpa.nonce, 32);
+ }
+ else
+ {
+ memcpy(R + offset, sa->wpa.nonce, 32);
+ memcpy(R + offset + 32, snonce, 32);
+ }
+
+ offset+=32*2;
+
+ for(i = 0; i < (x+159)/160; i++)
+ {
+ R[offset] = i;
+ AirPDcapAlgHmacSha1(pmk, 32, R, 100, ptk + i * 20);
+ }
+}
+
+INT AirPDcapRsnaPwd2PskStep(
+ const CHAR *password,
+ const CHAR *ssid,
+ const size_t ssidLength,
+ const INT iterations,
+ const INT count,
+ UCHAR *output)
+{
+ UCHAR digest[36], digest1[AIRPDCAP_SHA_DIGEST_LEN];
+ INT i, j;
+
+ /* U1 = PRF(P, S || INT(i)) */
+ memcpy(digest, ssid, ssidLength);
+ digest[ssidLength] = (UCHAR)((count>>24) & 0xff);
+ digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff);
+ digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff);
+ digest[ssidLength+3] = (UCHAR)(count & 0xff);
+ AirPDcapAlgHmacSha1((UCHAR *)password, strlen(password), digest, ssidLength+4, digest1);
+
+ /* output = U1 */
+ memcpy(output, digest1, AIRPDCAP_SHA_DIGEST_LEN);
+ for (i = 1; i < iterations; i++) {
+ /* Un = PRF(P, Un-1) */
+ AirPDcapAlgHmacSha1((UCHAR *)password, strlen(password), digest1, AIRPDCAP_SHA_DIGEST_LEN, digest);
+
+ memcpy(digest1, digest, AIRPDCAP_SHA_DIGEST_LEN);
+ /* output = output xor Un */
+ for (j = 0; j < AIRPDCAP_SHA_DIGEST_LEN; j++) {
+ output[j] ^= digest[j];
+ }
+ }
+
+ return AIRPDCAP_RET_SUCCESS;
+}
+
+INT AirPDcapRsnaPwd2Psk(
+ const CHAR *password,
+ const CHAR *ssid,
+ const size_t ssidLength,
+ UCHAR *output)
+{
+ UCHAR m_output[AIRPDCAP_WPA_PSK_LEN];
+
+ memset(m_output, 0, AIRPDCAP_WPA_PSK_LEN);
+
+ memset(m_output, 0, 40);
+
+ AirPDcapRsnaPwd2PskStep(password, ssid, ssidLength, 4096, 1, m_output);
+ AirPDcapRsnaPwd2PskStep(password, ssid, ssidLength, 4096, 2, &m_output[AIRPDCAP_SHA_DIGEST_LEN]);
+
+ memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN);
+
+ return 0;
+}
+
+/***************************************************************************/
+/* The following code come from freeBSD and implements the AUTODIN II */
+/* polynomial used by 802.11. */
+/* It can be used to calculate multicast address hash indices. */
+/* It assumes that the low order bits will be transmitted first, */
+/* and consequently the low byte should be sent first when */
+/* the crc computation is finished. The crc should be complemented */
+/* before transmission. */
+/* The variable corresponding to the macro argument "crc" should */
+/* be an unsigned long and should be preset to all ones for Ethernet */
+/* use. An error-free packet will leave 0xDEBB20E3 in the crc. */
+/***************************************************************************/
+INT AirPDcapAlgCrc32(
+ UCHAR *buf,
+ size_t nr,
+ ULONG *cval)
+{
+ ULONG crc32_total = 0 ;
+ ULONG crc = ~(ULONG)0;
+ UCHAR *p ;
+ size_t len;
+
+ len = 0 ;
+ crc32_total = ~crc32_total ;
+
+ for(len += nr, p = buf; nr--; ++p)
+ {
+ CRC(crc, *p) ;
+ CRC(crc32_total, *p) ;
+ }
+
+ *cval = ~crc ;
+ crc32_total = ~crc32_total ;
+
+ return 0;
+}
#ifdef __cplusplus
}
diff --git a/airpdcap/airpdcap_ccmp.c b/airpdcap/airpdcap_ccmp.c
index b3cc2a77bb..5dfa85a8f6 100644
--- a/airpdcap/airpdcap_ccmp.c
+++ b/airpdcap/airpdcap_ccmp.c
@@ -4,10 +4,9 @@
#include "airpdcap_system.h"
#include "airpdcap_int.h"
-#include "airpdcap_ccmp.h"
#include "airpdcap_rijndael.h"
-#include "airpdcap_debug.h"
+#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -37,14 +36,14 @@
/* Internal macros */
/* */
#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len) { \
- /* Decrypt, with counter */ \
- _b0[14] = (UINT8)((_i >> 8) & 0xff); \
- _b0[15] = (UINT8)(_i & 0xff); \
- rijndael_encrypt(&key, _b0, _b); \
- xor_block(_pos, _b, _len); \
- /* Authentication */ \
- xor_block(_a, _pos, _len); \
- rijndael_encrypt(&key, _a, _a); \
+ /* Decrypt, with counter */ \
+ _b0[14] = (UINT8)((_i >> 8) & 0xff); \
+ _b0[15] = (UINT8)(_i & 0xff); \
+ rijndael_encrypt(&key, _b0, _b); \
+ xor_block(_pos, _b, _len); \
+ /* Authentication */ \
+ xor_block(_a, _pos, _len); \
+ rijndael_encrypt(&key, _a, _a); \
}
#define AIRPDCAP_ADDR_COPY(dst,src) memcpy(dst,src,AIRPDCAP_MAC_LEN)
@@ -55,8 +54,8 @@
/* Internal function prototypes declarations */
/* */
static void ccmp_init_blocks(
- rijndael_ctx *ctx,
-PAIRPDCAP_MAC_FRAME wh,
+ rijndael_ctx *ctx,
+ PAIRPDCAP_MAC_FRAME wh,
UINT64 pn,
size_t dlen,
UINT8 b0[AES_BLOCK_LEN],
@@ -71,12 +70,12 @@ PAIRPDCAP_MAC_FRAME wh,
/* Function definitions */
/* */
static __inline UINT64 READ_6(
- UINT8 b0,
- UINT8 b1,
- UINT8 b2,
- UINT8 b3,
- UINT8 b4,
- UINT8 b5)
+ UINT8 b0,
+ UINT8 b1,
+ UINT8 b2,
+ UINT8 b3,
+ UINT8 b4,
+ UINT8 b5)
{
UINT32 iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
UINT16 iv16 = (UINT16)((b4 << 0) | (b5 << 8));
@@ -84,8 +83,8 @@ static __inline UINT64 READ_6(
}
static void ccmp_init_blocks(
- rijndael_ctx *ctx,
-PAIRPDCAP_MAC_FRAME wh,
+ rijndael_ctx *ctx,
+ PAIRPDCAP_MAC_FRAME wh,
UINT64 pn,
size_t dlen,
UINT8 b0[AES_BLOCK_LEN],
@@ -189,9 +188,9 @@ PAIRPDCAP_MAC_FRAME wh,
}
INT AirPDcapCcmpDecrypt(
- UINT8 *m,
- INT len,
- UCHAR TK1[16])
+ UINT8 *m,
+ INT len,
+ UCHAR TK1[16])
{
PAIRPDCAP_MAC_FRAME wh;
UINT8 aad[2 * AES_BLOCK_LEN];
diff --git a/airpdcap/airpdcap_ccmp.h b/airpdcap/airpdcap_ccmp.h
index 1a5f50ae65..e69de29bb2 100644
--- a/airpdcap/airpdcap_ccmp.h
+++ b/airpdcap/airpdcap_ccmp.h
@@ -1,23 +0,0 @@
-#ifndef _AIRPDCAP_CCMP
-#define _AIRPDCAP_CCMP
-
-/******************************************************************************/
-/* File includes */
-/* */
-#include "airpdcap_interop.h"
-/* */
-/* */
-/******************************************************************************/
-
-/******************************************************************************/
-/* External function prototypes declarations */
-/* */
-INT AirPDcapCcmpDecrypt(
- UINT8 *m,
- INT len,
- UCHAR TK1[16])
- ;
-/* */
-/******************************************************************************/
-
-#endif \ No newline at end of file
diff --git a/airpdcap/airpdcap_debug.c b/airpdcap/airpdcap_debug.c
index 21edadcfd8..6b6125ef5c 100644
--- a/airpdcap/airpdcap_debug.c
+++ b/airpdcap/airpdcap_debug.c
@@ -1,7 +1,7 @@
/******************************************************************************/
/* File includes */
/* */
-#include "airpdcap_debug.h"
+#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -18,4 +18,4 @@ extern "C" {
}
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/airpdcap/airpdcap_debug.h b/airpdcap/airpdcap_debug.h
index 1ff582c6ab..c41caaeef7 100644
--- a/airpdcap/airpdcap_debug.h
+++ b/airpdcap/airpdcap_debug.h
@@ -67,4 +67,4 @@ void print_debug_line(CHAR *function, CHAR *msg, INT level);
#endif /* ?defined _DEBUG */
-#endif /* ?defined _AIRPDCAP_DEBUG_H */ \ No newline at end of file
+#endif /* ?defined _AIRPDCAP_DEBUG_H */
diff --git a/airpdcap/airpdcap_int.h b/airpdcap/airpdcap_int.h
index dd52a98532..6424be6731 100644
--- a/airpdcap/airpdcap_int.h
+++ b/airpdcap/airpdcap_int.h
@@ -15,7 +15,7 @@
/* IEEE 802.11 packet type values */
#define AIRPDCAP_TYPE_MANAGEMENT 0
#define AIRPDCAP_TYPE_CONTROL 1
-#define AIRPDCAP_TYPE_DATA 2
+#define AIRPDCAP_TYPE_DATA 2
/* Min length of encrypted data (TKIP=25bytes, CCMP=21bytes) */
#define AIRPDCAP_CRYPTED_DATA_MINLEN 21
@@ -110,4 +110,4 @@ typedef struct _AIRPDCAP_MAC_FRAME_ADDR4_QOS {
/* */
/******************************************************************************/
-#endif \ No newline at end of file
+#endif
diff --git a/airpdcap/airpdcap_interop.h b/airpdcap/airpdcap_interop.h
index e596b3a580..e398bf21bf 100644
--- a/airpdcap/airpdcap_interop.h
+++ b/airpdcap/airpdcap_interop.h
@@ -1,40 +1,64 @@
#ifndef _AIRPDCAP_INTEROP_H
#define _AIRPDCAP_INTEROP_H
-#ifdef HAVE_WIRESHARK
-/* built with Wireshark */
+/**
+ * Cast data types commonly used in Windows (e.g. UINT16) to theirf
+ * GLib equivalents.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#ifndef INT
+typedef gint INT;
+#endif
+
+#ifndef UINT
+typedef guint UINT;
+#endif
#ifndef UINT8
-typedef unsigned char UINT8;
+typedef guint8 UINT8;
#endif
#ifndef UINT16
-typedef unsigned short UINT16;
+typedef guint16 UINT16;
#endif
-#ifdef _WIN32
-/* built with Win32 */
-
-#include <windows.h>
+#ifndef UINT32
+typedef guint32 UINT32;
+#endif
-#else
-/* build without Win32 */
+#ifndef UINT64
+typedef guint64 UINT64;
+#endif
-#endif /* ? _WIN32 */
+#ifndef USHORT
+typedef gushort USHORT;
+#endif
-#else
-/* built without Wireshark */
+#ifndef ULONG
+typedef gulong ULONG;
+#endif
-#ifdef _WIN32
-/* built with Win32 */
+#ifndef ULONGLONG
+typedef guint64 ULONGLONG;
+#endif
-#include <windows.h>
+#ifndef CHAR
+typedef gchar CHAR;
+#endif
-#else
-/* build without Win32 */
+#ifndef UCHAR
+typedef guchar UCHAR;
+#endif
-#endif /* ? _WIN32 */
+#ifndef size_t
+typedef gsize size_t;
+#endif
-#endif /* ? _WIRESHARK */
+#ifndef ntohs
+#define ntohs(value) g_ntohs(value)
+#endif
-#endif /* ? _AIRPDCAP_INTEROP_H */ \ No newline at end of file
+#endif /* _AIRPDCAP_INTEROP_H */
diff --git a/airpdcap/airpdcap_md5.c b/airpdcap/airpdcap_md5.c
index 182bc6a50e..aa7a6727ac 100644
--- a/airpdcap/airpdcap_md5.c
+++ b/airpdcap/airpdcap_md5.c
@@ -4,8 +4,6 @@
#include "airpdcap_system.h"
#include "airpdcap_int.h"
-#include "airpdcap_md5.h"
-
#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -101,37 +99,37 @@ static UCHAR PADDING[64] = {
/* Internal function prototypes declarations */
/* */
void MD5Final(
- UCHAR digest[16],
- MD5_CTX *context)
- ;
+ UCHAR digest[16],
+ MD5_CTX *context)
+ ;
void MD5Update(
- MD5_CTX *context,
- UCHAR *input,
- UINT inputLen)
- ;
+ MD5_CTX *context,
+ UCHAR *input,
+ UINT inputLen)
+ ;
void MD5Init(
- MD5_CTX *context)
- ;
+ MD5_CTX *context)
+ ;
static void MD5_memset(
- UCHAR *output,
- INT value,
- UINT len)
- ;
+ UCHAR *output,
+ INT value,
+ UINT len)
+ ;
static void MD5_memcpy(
- UCHAR *output,
- UCHAR *input,
- UINT len)
- ;
+ UCHAR *output,
+ UCHAR *input,
+ UINT len)
+ ;
static void Decode(
- ULONG *output,
- UCHAR *input,
- UINT len)
- ;
+ ULONG *output,
+ UCHAR *input,
+ UINT len)
+ ;
static void Encode(
- UCHAR *output,
- ULONG *input,
- UINT len)
- ;
+ UCHAR *output,
+ ULONG *input,
+ UINT len)
+ ;
/* */
/******************************************************************************/
@@ -142,9 +140,9 @@ static void Encode(
a multiple of 4.
*/
static void Encode(
- UCHAR *output,
- ULONG *input,
- UINT len)
+ UCHAR *output,
+ ULONG *input,
+ UINT len)
{
UINT i, j;
@@ -160,9 +158,9 @@ static void Encode(
a multiple of 4.
*/
static void Decode(
- ULONG *output,
- UCHAR *input,
- UINT len)
+ ULONG *output,
+ UCHAR *input,
+ UINT len)
{
UINT i, j;
@@ -175,9 +173,9 @@ static void Decode(
*/
static void MD5_memcpy(
- UCHAR *output,
- UCHAR *input,
- UINT len)
+ UCHAR *output,
+ UCHAR *input,
+ UINT len)
{
UINT i;
@@ -188,9 +186,9 @@ static void MD5_memcpy(
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset(
- UCHAR *output,
- INT value,
- UINT len)
+ UCHAR *output,
+ INT value,
+ UINT len)
{
UINT i;
@@ -201,8 +199,8 @@ static void MD5_memset(
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform(
- ULONG state[4],
- UCHAR block[64])
+ ULONG state[4],
+ UCHAR block[64])
{
ULONG a = state[0], b = state[1], c = state[2], d = state[3], x[16];
@@ -293,7 +291,7 @@ static void MD5Transform(
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init(
- MD5_CTX *context)
+ MD5_CTX *context)
{
memset(context, 0, sizeof(context));
@@ -311,9 +309,9 @@ operation, processing another message block, and updating the
context.
*/
void MD5Update(
- MD5_CTX *context,
- UCHAR *input,
- UINT inputLen)
+ MD5_CTX *context,
+ UCHAR *input,
+ UINT inputLen)
{
UINT i, index, partLen;
@@ -353,8 +351,8 @@ void MD5Update(
the message digest and zeroizing the context.
*/
void MD5Final(
- UCHAR digest[16],
- MD5_CTX *context)
+ UCHAR digest[16],
+ MD5_CTX *context)
{
UCHAR bits[8];
UINT index, padLen;
@@ -380,11 +378,11 @@ void MD5Final(
}
void AirPDcapAlgHmacMd5(
- UCHAR *key, /* pointer to authentication key */
- INT key_len, /* length of authentication key */
- const UCHAR *text, /* pointer to data stream */
- const INT text_len, /* length of data stream */
- UCHAR *digest) /* caller digest to be filled in */
+ UCHAR *key, /* pointer to authentication key */
+ INT key_len, /* length of authentication key */
+ const UCHAR *text, /* pointer to data stream */
+ const INT text_len, /* length of data stream */
+ UCHAR *digest) /* caller digest to be filled in */
{
MD5_CTX context;
UCHAR k_ipad[65]; /* inner padding -
diff --git a/airpdcap/airpdcap_md5.h b/airpdcap/airpdcap_md5.h
index 0a58e31cca..e69de29bb2 100644
--- a/airpdcap/airpdcap_md5.h
+++ b/airpdcap/airpdcap_md5.h
@@ -1,25 +0,0 @@
-#ifndef _AIRPDCAP_MD5
-#define _AIRPDCAP_MD5
-
-/******************************************************************************/
-/* File includes */
-/* */
-#include "airpdcap_interop.h"
-/* */
-/* */
-/******************************************************************************/
-
-/******************************************************************************/
-/* External function prototypes declarations */
-/* */
-void AirPDcapAlgHmacMd5(
- UCHAR *key, /* pointer to authentication key */
- INT key_len, /* length of authentication key */
- const UCHAR *text, /* pointer to data stream */
- const INT text_len, /* length of data stream */
- UCHAR *digest) /* caller digest to be filled in */
- ;
-/* */
-/******************************************************************************/
-
-#endif \ No newline at end of file
diff --git a/airpdcap/airpdcap_rijndael.c b/airpdcap/airpdcap_rijndael.c
index cb5755961b..c024a2da35 100644
--- a/airpdcap/airpdcap_rijndael.c
+++ b/airpdcap/airpdcap_rijndael.c
@@ -33,23 +33,23 @@
/* Internal function prototypes declarations */
/* */
INT rijndaelKeySetupEnc(
- UINT32 rk[/*4*(Nr + 1)*/],
- const UINT8 cipherKey[],
- INT keyBits)
- ;
+ UINT32 rk[/*4*(Nr + 1)*/],
+ const UINT8 cipherKey[],
+ INT keyBits)
+ ;
INT rijndaelKeySetupDec(
- UINT32 rk[/*4*(Nr + 1)*/],
- const UINT8 cipherKey[],
- INT keyBits)
- ;
+ UINT32 rk[/*4*(Nr + 1)*/],
+ const UINT8 cipherKey[],
+ INT keyBits)
+ ;
void rijndaelEncrypt(
- const UINT32 rk[/*4*(Nr + 1)*/],
- INT Nr,
- const UINT8 pt[16],
- UINT8 ct[16])
- ;
+ const UINT32 rk[/*4*(Nr + 1)*/],
+ INT Nr,
+ const UINT8 pt[16],
+ UINT8 ct[16])
+ ;
/* */
/******************************************************************************/
@@ -741,9 +741,9 @@ static const UINT32 rcon[] = {
/* Fuction definitions */
/* */
INT rijndaelKeySetupEnc(
- UINT32 rk[/*4*(Nr + 1)*/],
- const UINT8 cipherKey[],
- INT keyBits)
+ UINT32 rk[/*4*(Nr + 1)*/],
+ const UINT8 cipherKey[],
+ INT keyBits)
{
INT i = 0;
UINT32 temp;
@@ -829,9 +829,9 @@ INT rijndaelKeySetupEnc(
}
INT rijndaelKeySetupDec(
- UINT32 rk[/*4*(Nr + 1)*/],
- const UINT8 cipherKey[],
- INT keyBits)
+ UINT32 rk[/*4*(Nr + 1)*/],
+ const UINT8 cipherKey[],
+ INT keyBits)
{
INT Nr, i, j;
UINT32 temp;
@@ -873,9 +873,9 @@ INT rijndaelKeySetupDec(
}
void rijndael_set_key(
- rijndael_ctx *ctx,
- const u_char *key,
- INT bits)
+ rijndael_ctx *ctx,
+ const UCHAR *key,
+ INT bits)
{
ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits);
@@ -883,10 +883,10 @@ void rijndael_set_key(
}
void rijndaelEncrypt(
- const UINT32 rk[/*4*(Nr + 1)*/],
- INT Nr,
- const UINT8 pt[16],
- UINT8 ct[16])
+ const UINT32 rk[/*4*(Nr + 1)*/],
+ INT Nr,
+ const UINT8 pt[16],
+ UINT8 ct[16])
{
UINT32 s0, s1, s2, s3, t0, t1, t2, t3;
#ifndef FULL_UNROLL
@@ -1069,12 +1069,12 @@ void rijndaelEncrypt(
}
void rijndael_encrypt(
- const rijndael_ctx *ctx,
- const UCHAR *src,
- UCHAR *dst)
+ const rijndael_ctx *ctx,
+ const UCHAR *src,
+ UCHAR *dst)
{
rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst);
}
/* */
-/******************************************************************************/ \ No newline at end of file
+/******************************************************************************/
diff --git a/airpdcap/airpdcap_rijndael.h b/airpdcap/airpdcap_rijndael.h
index 7219fcda9f..b113c84643 100644
--- a/airpdcap/airpdcap_rijndael.h
+++ b/airpdcap/airpdcap_rijndael.h
@@ -36,17 +36,17 @@ typedef struct s_rijndael_ctx {
/* External function prototypes declarations */
/* */
void rijndael_encrypt(
- const rijndael_ctx *ctx,
- const UCHAR *src,
- UCHAR *dst)
- ;
+ const rijndael_ctx *ctx,
+ const UCHAR *src,
+ UCHAR *dst)
+ ;
void rijndael_set_key(
- rijndael_ctx *ctx,
- const u_char *key,
- INT bits)
- ;
+ rijndael_ctx *ctx,
+ const UCHAR *key,
+ INT bits)
+ ;
/* */
/******************************************************************************/
@@ -54,9 +54,9 @@ void rijndael_set_key(
/* External function definition */
/* */
static __inline void xor_block(
- UINT8 *b,
- const UINT8 *a,
- size_t len)
+ UINT8 *b,
+ const UINT8 *a,
+ size_t len)
{
INT i;
for (i = 0; i < (INT)len; i++)
@@ -65,4 +65,4 @@ static __inline void xor_block(
/* */
/******************************************************************************/
-#endif \ No newline at end of file
+#endif
diff --git a/airpdcap/airpdcap_sha1.c b/airpdcap/airpdcap_sha1.c
index d280e0b2c8..b49fe0d0a8 100644
--- a/airpdcap/airpdcap_sha1.c
+++ b/airpdcap/airpdcap_sha1.c
@@ -3,7 +3,7 @@
/* */
#include "airpdcap_sha1.h"
-#include "airpdcap_debug.h"
+#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -66,12 +66,12 @@ static UINT32 _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
-#define PUTPAD(x) { \
+#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
- COUNT++; \
- COUNT %= 64; \
- if (COUNT % 64 == 0) \
- sha1_step(ctxt); \
+ COUNT++; \
+ COUNT %= 64; \
+ if (COUNT % 64 == 0) \
+ sha1_step(ctxt); \
}
/* */
/******************************************************************************/
@@ -80,19 +80,19 @@ static UINT32 _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
/* Function prototypes used internally */
/* */
void sha1_init(
- SHA1_CONTEXT *ctxt)
- ;
+ SHA1_CONTEXT *ctxt)
+ ;
void sha1_result(
- SHA1_CONTEXT *ctxt,
- UCHAR *digest0)
- ;
+ SHA1_CONTEXT *ctxt,
+ UCHAR *digest0)
+ ;
void sha1_pad(
- SHA1_CONTEXT *ctxt)
- ;
+ SHA1_CONTEXT *ctxt)
+ ;
static void sha1_step(
- SHA1_CONTEXT *ctxt)
- ;
+ SHA1_CONTEXT *ctxt)
+ ;
/* */
/******************************************************************************/
@@ -104,7 +104,7 @@ static void sha1_step(
/* */
/* Note: copied from FreeBSD source code, RELENG 6, sys/crypto/sha1.c, 176 */
void sha1_init(
- SHA1_CONTEXT *ctxt)
+ SHA1_CONTEXT *ctxt)
{
memset(ctxt, 0, sizeof(SHA1_CONTEXT));
H(0) = 0x67452301;
@@ -116,9 +116,9 @@ void sha1_init(
/* Note: copied from FreeBSD source code, RELENG 6, sys/crypto/sha1.c, 223 */
void sha1_loop(
- SHA1_CONTEXT *ctxt,
- const UCHAR *input,
- size_t len)
+ SHA1_CONTEXT *ctxt,
+ const UCHAR *input,
+ size_t len)
{
size_t gaplen;
size_t gapstart;
@@ -143,7 +143,7 @@ void sha1_loop(
/* Note: copied from FreeBSD source code, RELENG 6, sys/crypto/sha1.c, 91 */
static void sha1_step(
- SHA1_CONTEXT *ctxt)
+ SHA1_CONTEXT *ctxt)
{
UINT32 a, b, c, d, e;
size_t t, s;
@@ -224,7 +224,7 @@ static void sha1_step(
/* Note: copied from FreeBSD source code, RELENG 6, sys/crypto/sha1.c, 188 */
void sha1_pad(
- SHA1_CONTEXT *ctxt)
+ SHA1_CONTEXT *ctxt)
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
@@ -253,8 +253,8 @@ void sha1_pad(
/* Note: copied from FreeBSD source code, RELENG 6, sys/crypto/sha1.c, 251 */
void sha1_result(
- SHA1_CONTEXT *ctxt,
- UCHAR *digest0)
+ SHA1_CONTEXT *ctxt,
+ UCHAR *digest0)
{
UINT8 *digest;
@@ -274,11 +274,11 @@ void sha1_result(
}
void AirPDcapAlgHmacSha1(
- const UCHAR *key_len,
- const size_t keylen,
- UCHAR *buffer,
- const size_t digest_len,
- UCHAR digest[20])
+ const UCHAR *key_len,
+ const size_t keylen,
+ UCHAR *buffer,
+ const size_t digest_len,
+ UCHAR digest[20])
{
//INT i;
//SHA1_CONTEXT ictx;
@@ -338,33 +338,6 @@ void AirPDcapAlgHmacSha1(
sha1_loop(&octx, tmp, 20);
sha1_result(&octx, digest);
- //INT i;
- //SHA1_CONTEXT sha1ctx;
- //UCHAR k_ipad[64];
- //UCHAR k_opad[64];
- //UCHAR tmp[20];
-
- //memset(k_ipad, 0, sizeof(k_ipad));
- //memset(k_opad, 0, sizeof(k_opad));
-
- //memcpy(k_ipad, key_len, keylen);
- //memcpy(k_opad, key_len, keylen);
-
- //for(i = 0; i<64; i++)
- //{
- // k_ipad[i] ^= HMAC_IPAD_VAL;
- // k_opad[i] ^= HMAC_OPAD_VAL;
- //}
-
- //sha1_init(&sha1ctx);
- //sha1_loop(&sha1ctx, k_ipad, 64);
- //sha1_loop(&sha1ctx, buffer, digest_len);
- //sha1_result(&sha1ctx, tmp);
-
- //sha1_init(&sha1ctx);
- //sha1_loop(&sha1ctx, k_opad, 64);
- //sha1_loop(&sha1ctx, tmp, 20);
- //sha1_result(&sha1ctx, digest);
}
/* */
-/******************************************************************************/ \ No newline at end of file
+/******************************************************************************/
diff --git a/airpdcap/airpdcap_sha1.h b/airpdcap/airpdcap_sha1.h
index c696a0b698..87ebfb643d 100644
--- a/airpdcap/airpdcap_sha1.h
+++ b/airpdcap/airpdcap_sha1.h
@@ -22,14 +22,7 @@
/******************************************************************************/
/* External function prototypes declarations */
/* */
-void AirPDcapAlgHmacSha1(
- const UCHAR *key_len,
- const size_t keylen,
- UCHAR *buffer,
- const size_t digest_len,
- UCHAR digest[20])
- ;
/* */
/******************************************************************************/
-#endif \ No newline at end of file
+#endif
diff --git a/airpdcap/airpdcap_system.h b/airpdcap/airpdcap_system.h
index 28a7c2cf69..4c8d42bc59 100644
--- a/airpdcap/airpdcap_system.h
+++ b/airpdcap/airpdcap_system.h
@@ -21,41 +21,43 @@
#define FALSE 0
#endif
-#define AIRPDCAP_RET_SUCCESS 0
-#define AIRPDCAP_RET_UNSUCCESS 1
+#define AIRPDCAP_RET_SUCCESS 0
+#define AIRPDCAP_RET_UNSUCCESS 1
-#define AIRPDCAP_RET_NO_DATA 1
-#define AIRPDCAP_RET_WRONG_DATA_SIZE 2
-#define AIRPDCAP_RET_REQ_DATA 3
-#define AIRPDCAP_RET_NO_VALID_HANDSHAKE 4
-#define AIRPDCAP_RET_NO_DATA_ENCRYPTED 5
+#define AIRPDCAP_RET_NO_DATA 1
+#define AIRPDCAP_RET_WRONG_DATA_SIZE 2
+#define AIRPDCAP_RET_REQ_DATA 3
+#define AIRPDCAP_RET_NO_VALID_HANDSHAKE 4
+#define AIRPDCAP_RET_NO_DATA_ENCRYPTED 5
-#define AIRPDCAP_RET_SUCCESS_HANDSHAKE -1
+#define AIRPDCAP_RET_SUCCESS_HANDSHAKE -1
-#define AIRPDCAP_MAX_KEYS_NR 64
+#define AIRPDCAP_MAX_KEYS_NR 64
#define AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR 256
/* Decryption algorithms fields size definition (bytes) */
-#define AIRPDCAP_WPA_NONCE_LEN 32
-#define AIRPDCAP_WPA_PTK_LEN 64 /* TKIP uses 48 bytes, CCMP uses 64 bytes */
-#define AIRPDCAP_WPA_MICKEY_LEN 16
+#define AIRPDCAP_WPA_NONCE_LEN 32
+#define AIRPDCAP_WPA_PTK_LEN 64 /* TKIP uses 48 bytes, CCMP uses 64 bytes */
+#define AIRPDCAP_WPA_MICKEY_LEN 16
-#define AIRPDCAP_WEP_128_KEY_LEN 16 /* 128 bits */
+#define AIRPDCAP_WEP_128_KEY_LEN 16 /* 128 bits */
/* General 802.11 constants */
-#define AIRPDCAP_MAC_LEN 6
-#define AIRPDCAP_RADIOTAP_HEADER_LEN 24
+#define AIRPDCAP_MAC_LEN 6
+#define AIRPDCAP_RADIOTAP_HEADER_LEN 24
#define AIRPDCAP_EAPOL_MAX_LEN 1024
+#define AIRPDCAP_TK_LEN 16
+
/* Max length of capture data */
-#define AIRPDCAP_MAX_CAPLEN 8192
+#define AIRPDCAP_MAX_CAPLEN 8192
-#define AIRPDCAP_WEP_IVLEN 3 /* 24bit */
-#define AIRPDCAP_WEP_KIDLEN 1 /* 1 octet */
-#define AIRPDCAP_WEP_ICV 4
-#define AIRPDCAP_WEP_HEADER AIRPDCAP_WEP_IVLEN + AIRPDCAP_WEP_KIDLEN
-#define AIRPDCAP_WEP_TRAILER AIRPDCAP_WEP_ICV
+#define AIRPDCAP_WEP_IVLEN 3 /* 24bit */
+#define AIRPDCAP_WEP_KIDLEN 1 /* 1 octet */
+#define AIRPDCAP_WEP_ICV 4
+#define AIRPDCAP_WEP_HEADER AIRPDCAP_WEP_IVLEN + AIRPDCAP_WEP_KIDLEN
+#define AIRPDCAP_WEP_TRAILER AIRPDCAP_WEP_ICV
/*
* 802.11i defines an extended IV for use with non-WEP ciphers.
@@ -64,19 +66,19 @@
* EXTIV bit is likewise set but the 8 bytes represent the
* CCMP header rather than IV+extended-IV.
*/
-#define AIRPDCAP_RSNA_EXTIV 0x20
-#define AIRPDCAP_RSNA_EXTIVLEN 4 /* extended IV length */
-#define AIRPDCAP_RSNA_MICLEN 8 /* trailing MIC */
+#define AIRPDCAP_RSNA_EXTIV 0x20
+#define AIRPDCAP_RSNA_EXTIVLEN 4 /* extended IV length */
+#define AIRPDCAP_RSNA_MICLEN 8 /* trailing MIC */
-#define AIRPDCAP_RSNA_HEADER AIRPDCAP_WEP_HEADER + AIRPDCAP_RSNA_EXTIVLEN
+#define AIRPDCAP_RSNA_HEADER AIRPDCAP_WEP_HEADER + AIRPDCAP_RSNA_EXTIVLEN
-#define AIRPDCAP_CCMP_HEADER AIRPDCAP_RSNA_HEADER
-#define AIRPDCAP_CCMP_TRAILER AIRPDCAP_RSNA_MICLEN
+#define AIRPDCAP_CCMP_HEADER AIRPDCAP_RSNA_HEADER
+#define AIRPDCAP_CCMP_TRAILER AIRPDCAP_RSNA_MICLEN
-#define AIRPDCAP_TKIP_HEADER AIRPDCAP_RSNA_HEADER
-#define AIRPDCAP_TKIP_TRAILER AIRPDCAP_RSNA_MICLEN + AIRPDCAP_WEP_ICV
+#define AIRPDCAP_TKIP_HEADER AIRPDCAP_RSNA_HEADER
+#define AIRPDCAP_TKIP_TRAILER AIRPDCAP_RSNA_MICLEN + AIRPDCAP_WEP_ICV
-#define AIRPDCAP_CRC_LEN 4
+#define AIRPDCAP_CRC_LEN 4
/* */
/* */
/******************************************************************************/
@@ -138,193 +140,205 @@ typedef struct _AIRPDCAP_CONTEXT {
extern "C" {
#endif
- /*!
- /brief
- it processes a packet and if necessary it tries to decrypt encrypted data.
- The packet received in input should be an 802.11 frame (composed by the MAC header, the frame body and the FCS -if specified-). If the data will be decrypted the FCS will be recomputed. The packet received could start with a RadioTap header.
-
- /param ctx
- [IN] pointer to the current context
-
- /param data
- [IN] pointer to a buffer with packet data
-
- /param len
- [IN] packet data length; this should be the capture packet length (to avoid errors in processing)
-
- /param decrypt_data
- [OUT] pointer to a buffer that will contain decrypted data
-
- /param decrypt_len
- [OUT] length of decrypted data
-
- /param key
- [OUT] pointer to a preallocated key structure containing the key used during the decryption process (if done). If this parameter is set to NULL, the key will be not returned.
-
- /param fcsPresent
- [IN] flag that specifies if the FCS is present in the packet or not (0 when the FCS is not present, 1 when it is).
-
- /param radioTapPresent
- [IN] flag that specifies if a RadioTap header is present or not (0 when the header is no present, 1 when it is).
-
- /param mngHandshake
- [IN] if TRUE this function will manage the 4-way handshake for WPA/WPA2
-
- /param mngDecrypt
- [IN] if TRUE this function will manage the WEP or WPA/WPA2 decryption
-
- /return
- - AIRPDCAP_RET_SUCCESS: decryption has been done (decrypt_data and decrypt_length will contain the packet data decrypted and the lenght of the new packet)
- - AIRPDCAP_RET_SUCCESS_HANDSHAKE: a step of the 4-way handshake for WPA key has been successfully done
- - AIRPDCAP_RET_NO_DATA: the packet is not a data packet
- - AIRPDCAP_RET_WRONG_DATA_SIZE: the size of the packet is below the accepted minimum
- - AIRPDCAP_RET_REQ_DATA: required data is not available and the processing must be interrupted
- - AIRPDCAP_RET_NO_VALID_HANDSHAKE: the authentication is not for WPA or RSNA
- - AIRPDCAP_RET_NO_DATA_ENCRYPTED: no encrypted data
- - AIRPDCAP_RET_UNSUCCESS: no decryption has been done (decrypt_data and decrypt_length will be not modified).
- Some other errors could be:
- data not correct
- data not encrypted
- key handshake, not encryption
- decryption not successful
- key handshake not correct
- replay check not successful
-
- /note
- The decrypted buffer should be allocated for a size equal or greater than the packet data buffer size. Before decryption process original data is copied in the buffer pointed by decrypt_data not to modify the original packet.
-
- /note
- The length of decrypted data will consider the entire 802.11 frame (thus the MAC header, the frame body and the recalculated FCS -if initially present-)
-
- /note
- This function is not thread-safe when used in parallel with context management functions on the same context.
- */
- INT AirPDcapPacketProcess(
+/**
+ * It processes a packet and if necessary it tries to decrypt
+ * encrypted data.
+ * The packet received in input should be an 802.11 frame (composed by the
+ * MAC header, the frame body and the FCS -if specified-). If the data will
+ * be decrypted the FCS will be recomputed. The packet received could start
+ * with a RadioTap header.
+ * @param ctx [IN] pointer to the current context
+ * @param data [IN] pointer to a buffer with packet data
+ * @param len [IN] packet data length; this should be the capture packet
+ * length (to avoid errors in processing)
+ * @param decrypt_data [OUT] pointer to a buffer that will contain
+ * decrypted data
+ * @param decrypt_len [OUT] length of decrypted data
+ * @param key [OUT] pointer to a preallocated key structure containing
+ * the key used during the decryption process (if done). If this parameter
+ * is set to NULL, the key will be not returned.
+ * @param fcsPresent [IN] flag that specifies if the FCS is present in
+ * the packet or not (0 when the FCS is not present, 1 when it is).
+ * @param radioTapPresent [IN] flag that specifies if a RadioTap header
+ * is present or not (0 when the header is no present, 1 when it is).
+ * @param mngHandshake [IN] if TRUE this function will manage the 4-way
+ * handshake for WPA/WPA2
+ * @param mngDecrypt [IN] if TRUE this function will manage the WEP or
+ * WPA/WPA2 decryption
+ * @return
+ * - AIRPDCAP_RET_SUCCESS: decryption has been done (decrypt_data and
+ * decrypt_length will contain the packet data decrypted and the lenght of
+ * the new packet)
+ * - AIRPDCAP_RET_SUCCESS_HANDSHAKE: a step of the 4-way handshake for
+ * WPA key has been successfully done
+ * - AIRPDCAP_RET_NO_DATA: the packet is not a data packet
+ * - AIRPDCAP_RET_WRONG_DATA_SIZE: the size of the packet is below the
+ * accepted minimum
+ * - AIRPDCAP_RET_REQ_DATA: required data is not available and the
+ * processing must be interrupted
+ * - AIRPDCAP_RET_NO_VALID_HANDSHAKE: the authentication is not for WPA or RSNA
+ * - AIRPDCAP_RET_NO_DATA_ENCRYPTED: no encrypted data
+ * - AIRPDCAP_RET_UNSUCCESS: no decryption has been done (decrypt_data
+ * and decrypt_length will be not modified).
+ * Some other errors could be:
+ * data not correct
+ * data not encrypted
+ * key handshake, not encryption
+ * decryption not successful
+ * key handshake not correct
+ * replay check not successful
+ * @note
+ * The decrypted buffer should be allocated for a size equal or greater
+ * than the packet data buffer size. Before decryption process original
+ * data is copied in the buffer pointed by decrypt_data not to modify the
+ * original packet.
+ * @note
+ * The length of decrypted data will consider the entire 802.11 frame
+ * (thus the MAC header, the frame body and the recalculated FCS -if
+ * initially present-)
+ * @note
+ * This function is not thread-safe when used in parallel with context
+ * management functions on the same context.
+ */
+extern INT AirPDcapPacketProcess(
PAIRPDCAP_CONTEXT ctx,
- const UCHAR *data,
- const size_t len,
- UCHAR *decrypt_data,
- size_t *decrypt_len,
+ const UCHAR *data,
+ const size_t len,
+ UCHAR *decrypt_data,
+ size_t *decrypt_len,
PAIRPDCAP_KEY_ITEM key,
- UINT8 fcsPresent,
- UINT8 radioTapPresent,
- UINT8 mngHandshake,
- UINT8 mngDecrypt)
- ;
-
- /*!
- /brief
- It sets a new keys collection to use during packet processing.
- Any key should be well-formed, thus: it should have a defined key type and the specified length should be conforming WEP or WPA/WPA2 standards. A general WEP keys could be of any length (in the range defined in AIRPDCAP_KEY_ITEM), if a specific WEP key is used, the length of the key will be the one specified in 802.11i-2004 (40 bits or 104 bits).
- For WPA/WPA2 the password (passphrase and SSID), the PSK and the PMK are in alternative, as explain in the AIRPDCAP_KEY_ITEM structure description.
-
- /param ctx
- [IN] pointer to the current context
-
- /param keys
- [IN] an array of keys to set.
-
- /param keys_nr
- [IN] the size of the keys array
-
- /return
- The number of keys correctly inserted in the current database.
-
- /note
- Before inserting new keys, the current database will be cleaned.
-
- /note
- This function is not thread-safe when used in parallel with context management functions and the packet process function on the same context.
- */
- INT AirPDcapSetKeys(
+ UINT8 fcsPresent,
+ UINT8 radioTapPresent,
+ UINT8 mngHandshake,
+ UINT8 mngDecrypt)
+ ;
+
+/**
+ * It sets a new keys collection to use during packet processing.
+ * Any key should be well-formed, thus: it should have a defined key
+ * type and the specified length should be conforming WEP or WPA/WPA2
+ * standards. A general WEP keys could be of any length (in the range
+ * defined in AIRPDCAP_KEY_ITEM), if a specific WEP key is used, the
+ * length of the key will be the one specified in 802.11i-2004 (40 bits or
+ * 104 bits).
+ * For WPA/WPA2 the password (passphrase and SSID), the PSK and the PMK
+ * are in alternative, as explain in the AIRPDCAP_KEY_ITEM structure
+ * description.
+ * @param ctx [IN] pointer to the current context
+ * @param keys [IN] an array of keys to set.
+ * @param keys_nr [IN] the size of the keys array
+ * @return The number of keys correctly inserted in the current database.
+ * @note Before inserting new keys, the current database will be cleaned.
+ * @note
+ * This function is not thread-safe when used in parallel with context
+ * management functions and the packet process function on the same
+ * context.
+ */
+extern INT AirPDcapSetKeys(
PAIRPDCAP_CONTEXT ctx,
AIRPDCAP_KEY_ITEM keys[],
- const size_t keys_nr)
- ;
-
- /*!
- /brief
- it removes all keys from the active database
-
- /param ctx
- [IN] pointer to the current context
-
- /return
- The number of keys correctly removed.
-
- /note
- This function is not thread-safe when used in parallel with context management functions and the packet process function on the same context.
- */
- INT AirPDcapCleanKeys(
+ const size_t keys_nr)
+ ;
+
+/**
+ * Remove all keys from the active database
+ * @param ctx [IN] pointer to the current context
+ * @return The number of keys correctly removed.
+ *
+ * @note
+ * This function is not thread-safe when used in parallel with context
+ * management functions and the packet process function on the same
+ * context.
+ */
+INT AirPDcapCleanKeys(
PAIRPDCAP_CONTEXT ctx)
- ;
-
- /*!
- /brief
- It gets the keys collection fom the specified context.
-
- /param ctx
- [IN] pointer to the current context
-
- /param key
- [IN] a preallocated array of keys to be returned
-
- /param keys_nr
- [IN] the number of keys to return (the key array must be able to contain at least keys_nr keys)
-
- /return
- The number of keys returned
-
- /note
- Any key could be modified, as stated in the AIRPDCAP_KEY_ITEM description.
-
- /note
- This function is not thread-safe when used in parallel with context management functions and the packet process function on the same context.
- */
- INT AirPDcapGetKeys(
- const PAIRPDCAP_CONTEXT ctx,
+ ;
+
+/**
+ * It gets the keys collection fom the specified context.
+ * @param ctx [IN] pointer to the current context
+ * @param key [IN] a preallocated array of keys to be returned
+ * @param keys_nr [IN] the number of keys to return (the key array must
+ * be able to contain at least keys_nr keys)
+ * @return The number of keys returned
+ * @note
+ * Any key could be modified, as stated in the AIRPDCAP_KEY_ITEM description.
+ * @note
+ * This function is not thread-safe when used in parallel with context
+ * management functions and the packet process function on the same
+ * context.
+ */
+INT AirPDcapGetKeys(
+ const PAIRPDCAP_CONTEXT ctx,
AIRPDCAP_KEY_ITEM keys[],
- const size_t keys_nr)
- ;
- /*!
- /brief
- it initializes a context used to manage decryption and keys collection.
-
- /param ctx
- [IN|OUT] pointer to a preallocated context structure
-
- /return
- AIRPDCAP_RET_SUCCESS: the context has been successfully initialized
- AIRPDCAP_RET_UNSUCCESS: the context has not been initialized
-
- /note
- Only a correctly initialized context can be used to manage decryption processes and keys.
-
- /note
- This function is not thread-safe when used in parallel with context
- management functions and the packet process function on the same context.
- */
- INT AirPDcapInitContext(
+ const size_t keys_nr)
+ ;
+/**
+ * Initialize a context used to manage decryption and keys collection.
+ * @param ctx [IN|OUT] pointer to a preallocated context structure
+ * @return
+ * AIRPDCAP_RET_SUCCESS: the context has been successfully initialized
+ * AIRPDCAP_RET_UNSUCCESS: the context has not been initialized
+ * @note
+ * Only a correctly initialized context can be used to manage decryption
+ * processes and keys.
+ * @note
+ * This function is not thread-safe when used in parallel with context
+ * management functions and the packet process function on the same context.
+ */
+INT AirPDcapInitContext(
+ PAIRPDCAP_CONTEXT ctx)
+ ;
+
+/**
+ * Clean up the specified context. After the cleanup the pointer should
+ * not be used anymore.
+ * @param ctx [IN|OUT] pointer to the current context structure
+ * @return
+ * AIRPDCAP_RET_SUCCESS: the context has been successfully initialized
+ * AIRPDCAP_RET_UNSUCCESS: the context has not been initialized
+ * @note
+ * This function is not thread-safe when used in parallel with context
+ * management functions and the packet process function on the same
+ * context.
+ */
+INT AirPDcapDestroyContext(
PAIRPDCAP_CONTEXT ctx)
- ;
+ ;
+
+
+extern INT AirPDcapWepDecrypt(
+ const UCHAR *seed,
+ const size_t seed_len, /* max AIRPDCAP_KEYBUF_SIZE */
+ UCHAR *cypher_text,
+ const size_t data_len)
+ ;
+extern INT AirPDcapCcmpDecrypt(
+ UINT8 *m,
+ INT len,
+ UCHAR TK1[16])
+ ;
+extern INT AirPDcapTkipDecrypt(
+ UCHAR *tkip_mpdu,
+ size_t mpdu_len,
+ UCHAR TA[AIRPDCAP_MAC_LEN],
+ UCHAR TK[AIRPDCAP_TK_LEN])
+ ;
+extern void AirPDcapAlgHmacMd5(
+ UCHAR *key, /* pointer to authentication key */
+ INT key_len, /* length of authentication key */
+ const UCHAR *text, /* pointer to data stream */
+ const INT text_len, /* length of data stream */
+ UCHAR *digest) /* caller digest to be filled in */
+ ;
+extern void AirPDcapAlgHmacSha1(
+ const UCHAR *key_len,
+ const size_t keylen,
+ UCHAR *buffer,
+ const size_t digest_len,
+ UCHAR digest[20])
+ ;
- /*!
- /brief
- it cleanup the specified context. After the cleanup the pointer should not be used anymore.
-
- /param ctx
- [IN|OUT] pointer to the current context structure
-
- /return
- AIRPDCAP_RET_SUCCESS: the context has been successfully initialized
- AIRPDCAP_RET_UNSUCCESS: the context has not been initialized
-
- /note
- This function is not thread-safe when used in parallel with context management functions and the packet process function on the same context.
- */
- INT AirPDcapDestroyContext(
- PAIRPDCAP_CONTEXT ctx)
- ;
#ifdef __cplusplus
}
@@ -333,4 +347,4 @@ extern "C" {
/* */
/******************************************************************************/
-#endif \ No newline at end of file
+#endif /* _AIRPDCAP_SYSTEM_H */
diff --git a/airpdcap/airpdcap_tkip.c b/airpdcap/airpdcap_tkip.c
index d9fb2bdd9c..886540e6c9 100644
--- a/airpdcap/airpdcap_tkip.c
+++ b/airpdcap/airpdcap_tkip.c
@@ -4,10 +4,9 @@
#include "airpdcap_system.h"
#include "airpdcap_int.h"
-#include "airpdcap_tkip.h"
#include "airpdcap_wep.h"
-#include "airpdcap_debug.h"
+#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -24,18 +23,18 @@
/* Internal function prototypes declarations */
/* */
void AirPDcapTkipMixingPhase1(
- UINT16 *TTAK,
- const UINT8 *TK,
- const UINT8 *TA,
- UINT32 TSC)
- ;
+ UINT16 *TTAK,
+ const UINT8 *TK,
+ const UINT8 *TA,
+ UINT32 TSC)
+ ;
static void AirPDcapTkipMixingPhase2(
- UINT8 *wep_seed,
- const UINT8 *TK,
- UINT16 *PPK,
- UINT16 TSC16)
- ;
+ UINT8 *wep_seed,
+ const UINT8 *TK,
+ UINT16 *PPK,
+ UINT16 TSC16)
+ ;
/* */
/******************************************************************************/
@@ -90,38 +89,38 @@ static const UINT16 Sbox[256] = {
/* Note: any functions were copied from FreeBSD source code, RELENG 6, */
/* sys/net80211/ieee80211_crypto_tkip.c */
static __inline UINT16 RotR1(
- UINT16 val)
+ UINT16 val)
{
return (UINT16)((val >> 1) | (val << 15));
}
static __inline UINT8 Lo8(
- UINT16 val)
+ UINT16 val)
{
return (UINT8)(val & 0xff);
}
static __inline UINT8 Hi8(
- UINT16 val)
+ UINT16 val)
{
return (UINT8)(val >> 8);
}
static __inline UINT16 Lo16(
- UINT32 val)
+ UINT32 val)
{
return (UINT16)(val & 0xffff);
}
static __inline UINT16 Hi16(
- UINT32 val)
+ UINT32 val)
{
return (UINT16)(val >> 16);
}
static __inline UINT16 Mk16(
- UINT8 hi,
- UINT8 lo)
+ UINT8 hi,
+ UINT8 lo)
{
return (UINT16)(lo | (((UINT16) hi) << 8));
}
@@ -132,19 +131,19 @@ static __inline UINT16 Mk16_le(const UINT16 *v)
}
static __inline UINT16 _S_(
- UINT16 v)
+ UINT16 v)
{
UINT16 t = Sbox[Hi8(v)];
return (UINT16)(Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)));
}
static __inline UINT64 READ_6(
- UINT8 b0,
- UINT8 b1,
- UINT8 b2,
- UINT8 b3,
- UINT8 b4,
- UINT8 b5)
+ UINT8 b0,
+ UINT8 b1,
+ UINT8 b2,
+ UINT8 b3,
+ UINT8 b4,
+ UINT8 b5)
{
UINT32 iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
UINT16 iv16 = (UINT16)((b4 << 0) | (b5 << 8));
@@ -152,10 +151,10 @@ static __inline UINT64 READ_6(
}
void AirPDcapTkipMixingPhase1(
- UINT16 *TTAK,
- const UINT8 *TK,
- const UINT8 *TA,
- UINT32 TSC)
+ UINT16 *TTAK,
+ const UINT8 *TK,
+ const UINT8 *TA,
+ UINT32 TSC)
{
UINT16 i, j;
@@ -177,10 +176,10 @@ void AirPDcapTkipMixingPhase1(
}
static void AirPDcapTkipMixingPhase2(
- UINT8 *wep_seed,
- const UINT8 *TK,
- UINT16 *TTAK,
- UINT16 TSC16)
+ UINT8 *wep_seed,
+ const UINT8 *TK,
+ UINT16 *TTAK,
+ UINT16 TSC16)
{
INT i;
TTAK[5] = (UINT16)(TTAK[4] + TSC16);
@@ -217,10 +216,10 @@ static void AirPDcapTkipMixingPhase2(
/* Note: taken from FreeBSD source code, RELENG 6, */
/* sys/net80211/ieee80211_crypto_tkip.c, 936 */
INT AirPDcapTkipDecrypt(
- UCHAR *tkip_mpdu,
- size_t mpdu_len,
- UCHAR TA[AIRPDCAP_MAC_LEN],
- UCHAR TK[AIRPDCAP_TK_LEN])
+ UCHAR *tkip_mpdu,
+ size_t mpdu_len,
+ UCHAR TA[AIRPDCAP_MAC_LEN],
+ UCHAR TK[AIRPDCAP_TK_LEN])
{
UINT32 TSC;
UINT16 TSC16;
diff --git a/airpdcap/airpdcap_tkip.h b/airpdcap/airpdcap_tkip.h
index 4b7b2c49be..e69de29bb2 100644
--- a/airpdcap/airpdcap_tkip.h
+++ b/airpdcap/airpdcap_tkip.h
@@ -1,27 +0,0 @@
-#ifndef _AIRPDCAP_TKIP_H
-#define _AIRPDCAP_TKIP_H
-
-/******************************************************************************/
-/* File includes */
-/* */
-#include "airpdcap_interop.h"
-/* */
-/* */
-/******************************************************************************/
-
-#define AIRPDCAP_TK_LEN 16
-
-/******************************************************************************/
-/* External function prototypes declarations */
-/* */
-/* Note: copied and modified from net80211/ieee80211_airpdcap_tkip.c */
-INT AirPDcapTkipDecrypt(
- UCHAR *tkip_mpdu,
- size_t mpdu_len,
- UCHAR TA[AIRPDCAP_MAC_LEN],
- UCHAR TK[AIRPDCAP_TK_LEN])
- ;
-/* */
-/******************************************************************************/
-
-#endif \ No newline at end of file
diff --git a/airpdcap/airpdcap_user.h b/airpdcap/airpdcap_user.h
index b872b931f5..b637ea90b8 100644
--- a/airpdcap/airpdcap_user.h
+++ b/airpdcap/airpdcap_user.h
@@ -32,8 +32,8 @@
#define AIRPDCAP_WPA_PASSPHRASE_MAX_LEN 63 /* null-terminated string, the actual length of the storage is 64 */
#define AIRPDCAP_WPA_SSID_MIN_LEN 0
#define AIRPDCAP_WPA_SSID_MAX_LEN 32
-#define AIRPDCAP_WPA_PSK_LEN 64
-#define AIRPDCAP_WPA_PMK_LEN 32
+#define AIRPDCAP_WPA_PSK_LEN 64
+#define AIRPDCAP_WPA_PMK_LEN 32
/* */
/* */
/******************************************************************************/
@@ -47,67 +47,89 @@
/******************************************************************************/
/* Type definitions */
/* */
-/*!
-/brief
-It represent a key item used during the decryption process.
-*/
-typedef struct _AIRPDCAP_KEY_ITEM {
- /*!
- /brief
- Type of key. The type will remain unchanged during the processing, even if some fields could be changed (e.g., WPA fields).
+/**
+ * Struct to store info about a specific decryption key.
+ */
+typedef struct {
+ GString *key;
+ GString *ssid;
+ guint bits;
+ guint type;
+} decryption_key_t;
- /note
- You can use constants AIRPDCAP_KEY_TYPE_xxx to indicate the key type.
- */
+/**
+ * Key item used during the decryption process.
+ */
+typedef struct _AIRPDCAP_KEY_ITEM {
+ /**
+ * Type of key. The type will remain unchanged during the
+ * processing, even if some fields could be changed (e.g., WPA
+ * fields).
+ * @note
+ * You can use constants AIRPDCAP_KEY_TYPE_xxx to indicate the
+ * key type.
+ */
UINT8 KeyType;
- /*!
- /brief
- Key data.
- This field can be used for the following decryptographic algorithms: WEP-40, with a key of 40 bits (10 hex-digits); WEP-104, with a key of 104 bits (or 26 hex-digits); WPA or WPA2.
- /note
- For WPA/WPA2, the PMK is calculated from the PSK, and the PSK is calculated from the passphrase-SSID pair. You can enter one of these 3 values and subsequent fields will be automatically calculated.
- /note
- For WPA and WPA2 this implementation will use standards as defined in 802.11i (2004) and 802.1X (2004).
- */
+ /**
+ * Key data.
+ * This field can be used for the following decryptographic
+ * algorithms: WEP-40, with a key of 40 bits (10 hex-digits);
+ * WEP-104, with a key of 104 bits (or 26 hex-digits); WPA or
+ * WPA2.
+ * @note
+ * For WPA/WPA2, the PMK is calculated from the PSK, and the PSK
+ * is calculated from the passphrase-SSID pair. You can enter one
+ * of these 3 values and subsequent fields will be automatically
+ * calculated.
+ * @note
+ * For WPA and WPA2 this implementation will use standards as
+ * defined in 802.11i (2004) and 802.1X (2004).
+ */
union AIRPDCAP_KEY_ITEMDATA {
struct AIRPDCAP_KEY_ITEMDATA_WEP {
- /*!
- /brief
- The binary value of the WEP key.
- /note
- It is accepted a key of lenght between AIRPDCAP_WEP_KEY_MINLEN and AIRPDCAP_WEP_KEY_MAXLEN. A WEP key standard-compliante should be either 40 bits (10 hex-digits, 5 bytes) for WEP-40 or 104 bits (26 hex-digits, 13 bytes) for WEP-104.
- */
+ /**
+ * The binary value of the WEP key.
+ * @note
+ * It is accepted a key of lenght between
+ * AIRPDCAP_WEP_KEY_MINLEN and
+ * AIRPDCAP_WEP_KEY_MAXLEN. A WEP key
+ * standard-compliante should be either 40 bits
+ * (10 hex-digits, 5 bytes) for WEP-40 or 104 bits
+ * (26 hex-digits, 13 bytes) for WEP-104.
+ */
UCHAR WepKey[AIRPDCAP_WEP_KEY_MAXLEN];
- /*!
- /brief
- The length of the WEP key. Acceptable range is [AIRPDCAP_WEP_KEY_MINLEN;AIRPDCAP_WEP_KEY_MAXLEN].
- */
+ /**
+ * The length of the WEP key. Acceptable range
+ * is [AIRPDCAP_WEP_KEY_MINLEN;AIRPDCAP_WEP_KEY_MAXLEN].
+ */
size_t WepKeyLen;
} Wep;
- /*!
- /brief
- WPA/WPA2 key data. Note that the decryption process will use the PMK (equal to PSK), that is calculated from passphrase-SSID pair. You can define one of these three fields and necessary fields will be automatically calculated.
- */
+ /**
+ * WPA/WPA2 key data. Note that the decryption process
+ * will use the PMK (equal to PSK), that is calculated
+ * from passphrase-SSID pair. You can define one of these
+ * three fields and necessary fields will be automatically
+ * calculated.
+ */
union AIRPDCAP_KEY_ITEMDATA_WPA {
struct AIRPDCAP_KEY_ITEMDATA_PWD {
- /*!
- /brief
- The string (null-terminated) value of the passphrase.
- */
+ /**
+ * The string (null-terminated) value of
+ * the passphrase.
+ */
CHAR Passphrase[AIRPDCAP_WPA_PASSPHRASE_MAX_LEN+1];
- /*!
- /brief
- The value of the SSID (up to AIRPDCAP_WPA_SSID_MAX_LEN octets).
- /note
- A zero-length SSID indicates broadcast.
- */
+ /**
+ * The value of the SSID (up to
+ * AIRPDCAP_WPA_SSID_MAX_LEN octets).
+ * @note
+ * A zero-length SSID indicates broadcast.
+ */
CHAR Ssid[AIRPDCAP_WPA_SSID_MAX_LEN];
- /*!
- /brief
- The length of the SSID
- */
+ /**
+ *The length of the SSID
+ */
size_t SsidLen;
} UserPwd;
@@ -118,21 +140,18 @@ typedef struct _AIRPDCAP_KEY_ITEM {
} KeyData;
} AIRPDCAP_KEY_ITEM, *PAIRPDCAP_KEY_ITEM;
-/*!
-/brief
-Collection of keys to use to decrypt packets
-*/
+/**
+ * Collection of keys to use to decrypt packets
+ */
typedef struct _AIRPDCAP_KEYS_COLLECTION {
- /*!
- /brief
- Number of stored keys
- */
+ /**
+ * Number of stored keys
+ */
size_t nKeys;
- /*!
- /brief
- Array of nKeys keys
- */
+ /**
+ * Array of nKeys keys
+ */
AIRPDCAP_KEY_ITEM Keys[256];
} AIRPDCAP_KEYS_COLLECTION, *PAIRPDCAP_KEYS_COLLECTION;
/* */
@@ -145,4 +164,4 @@ typedef struct _AIRPDCAP_KEYS_COLLECTION {
/* */
/******************************************************************************/
-#endif \ No newline at end of file
+#endif /* _AIRPDCAP_USER_H */
diff --git a/airpdcap/airpdcap_wep.c b/airpdcap/airpdcap_wep.c
index f4dc72cb30..1501d61155 100644
--- a/airpdcap/airpdcap_wep.c
+++ b/airpdcap/airpdcap_wep.c
@@ -6,7 +6,7 @@
#include "airpdcap_wep.h"
-#include "airpdcap_debug.h"
+#include "airpdcap_debug.h"
/* */
/******************************************************************************/
@@ -15,10 +15,10 @@ extern const UINT32 crc32_table[256];
/* Note: copied from FreeBSD source code, RELENG 6, */
/* sys/net80211/ieee80211_crypto_wep.c, 391 */
INT AirPDcapWepDecrypt(
- const UCHAR *seed,
- const size_t seed_len,
- UCHAR *cypher_text,
- const size_t data_len)
+ const UCHAR *seed,
+ const size_t seed_len,
+ UCHAR *cypher_text,
+ const size_t data_len)
{
UINT32 i, j, k, crc;
UINT8 S[256];
@@ -64,4 +64,4 @@ INT AirPDcapWepDecrypt(
}
return AIRPDCAP_RET_SUCCESS;
-} \ No newline at end of file
+}
diff --git a/airpdcap/airpdcap_wep.h b/airpdcap/airpdcap_wep.h
index 1534e2d564..a7885c18f6 100644
--- a/airpdcap/airpdcap_wep.h
+++ b/airpdcap/airpdcap_wep.h
@@ -72,13 +72,7 @@ static const UINT32 crc32_table[256] = {
/******************************************************************************/
/* External function prototypes declarations */
/* */
-INT AirPDcapWepDecrypt(
- const UCHAR *seed,
- const size_t seed_len, /* max AIRPDCAP_KEYBUF_SIZE */
- UCHAR *cypher_text,
- const size_t data_len)
- ;
/* */
/******************************************************************************/
-#endif \ No newline at end of file
+#endif /* _AIRPDCAP_WEP */
diff --git a/airpdcap/airpdcap_ws.h b/airpdcap/airpdcap_ws.h
index 1811bd1288..6eec4d0ff6 100644
--- a/airpdcap/airpdcap_ws.h
+++ b/airpdcap/airpdcap_ws.h
@@ -1,9 +1,7 @@
#ifndef _AIRPDCAP_WS_H
#define _AIRPDCAP_WS_H
-#define HAVE_WIRESHARK
-
#include "airpdcap_system.h"
WS_VAR_IMPORT AIRPDCAP_CONTEXT airpdcap_ctx;
-#endif \ No newline at end of file
+#endif /* _AIRPDCAP_WS_H */
diff --git a/configure.in b/configure.in
index b03164a3ed..67f58cd9ef 100644
--- a/configure.in
+++ b/configure.in
@@ -1047,6 +1047,12 @@ AC_SUBST(ADNS_LIBS)
#
AC_DEFINE(WS_VAR_IMPORT, extern, [Define as the string to precede external variable declarations in dynamically-linked libraries])
+#
+# Define HAVE_AIRPDCAP
+# We'll want to remove this eventually.
+#
+AC_DEFINE(HAVE_AIRPDCAP, 1, [Enable AirPDcap (WPA/WPA2 decryption)])
+
dnl Checks for typedefs, structures, and compiler characteristics.
# AC_C_CONST
@@ -1313,6 +1319,7 @@ AC_CONFIG_SUBDIRS(wiretap)
AC_OUTPUT(
Makefile
doxygen.cfg
+ airpdcap/Makefile
asn1/Makefile
doc/Makefile
epan/Makefile
diff --git a/epan/Makefile.am b/epan/Makefile.am
index 966a29a612..4443d77105 100644
--- a/epan/Makefile.am
+++ b/epan/Makefile.am
@@ -100,8 +100,8 @@ MAINTAINERCLEANFILES = \
#
# Add the object files for missing routines, if any.
#
-libwireshark_la_LIBADD = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la $(wslua_lib) @ADNS_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @KRB5_LIBS@ @SNMP_LIBS@ @SSL_LIBS@ -lm
-libwireshark_la_DEPENDENCIES = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la $(wslua_lib)
+libwireshark_la_LIBADD = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la ../airpdcap/libairpdcap.a $(wslua_lib) @ADNS_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @KRB5_LIBS@ @SNMP_LIBS@ @SSL_LIBS@ -lm
+libwireshark_la_DEPENDENCIES = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la ../airpdcap/libairpdcap.a $(wslua_lib)
tvbtest: tvbtest.o tvbuff.o except.o strutil.o emem.o
$(LINK) $^ $(GLIB_LIBS) -lz
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index b40b11b48c..9285be48a0 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -70,6 +70,7 @@
#include <epan/crc32.h>
#include <epan/tap.h>
#include <epan/emem.h>
+#include <epan/crypt/wep-wpadefs.h>
#include <ctype.h>
#include "isprint.h"
@@ -791,14 +792,15 @@ static dissector_handle_t data_handle;
static int wlan_tap = -1;
-/* Davide Schiera (2006-11-22): including AirPDcap project */
-#ifdef HAVE_AIRPDCAP
-#include "..\..\airpdcap\airpdcap_ws.h"
+/* Davide Schiera (2006-11-22): including AirPDcap project */
+#ifdef HAVE_AIRPDCAP
+#include "airpdcap/airpdcap_ws.h"
AIRPDCAP_CONTEXT airpdcap_ctx;
#else
int airpdcap_ctx;
#endif
-/* Davide Schiera (2006-11-22) ---------------------------------------------- */
+/* Davide Schiera (2006-11-22) ---------------------------------------------- */
+
/* ************************************************************************* */
/* Return the length of the current header (in bytes) */
@@ -5454,7 +5456,7 @@ void set_airpdcap_keys()
gboolean res;
gchar* tmpk = NULL;
- keys=(PAIRPDCAP_KEYS_COLLECTION)malloc(sizeof(AIRPDCAP_KEYS_COLLECTION));
+ keys=(PAIRPDCAP_KEYS_COLLECTION)g_malloc(sizeof(AIRPDCAP_KEYS_COLLECTION));
keys->nKeys = 0;
for(i = 0; i < MAX_ENCRYPTION_KEYS; i++)
@@ -5526,12 +5528,13 @@ void set_airpdcap_keys()
keys->nKeys++;
}
}
+ if(tmpk != NULL) g_free(tmpk);
}
/* Now set the keys */
AirPDcapSetKeys(&airpdcap_ctx,keys->Keys,keys->nKeys);
+ g_free(keys);
- if(tmpk != NULL) g_free(tmpk);
}
#endif
diff --git a/gtk/main.c b/gtk/main.c
index 150f7eb5d4..3c139ea71f 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -174,7 +174,7 @@
#ifdef HAVE_AIRPDCAP
/* Davide Schiera (2006-11-22): including AirPDcap project */
-#include "..\airpdcap\airpdcap_ws.h"
+#include "../airpdcap/airpdcap_ws.h"
/* Davide Schiera (2006-11-22) ---------------------------------------------- */
#endif