Prepare to move the airpdcap code to epan/crypt (SVN won't let me actually
authorGerald Combs <gerald@wireshark.org>
Wed, 27 Dec 2006 23:05:55 +0000 (23:05 -0000)
committerGerald Combs <gerald@wireshark.org>
Wed, 27 Dec 2006 23:05:55 +0000 (23:05 -0000)
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

30 files changed:
Makefile.am
airpcap.h
airpcap_loader.c
airpcap_loader.h
airpdcap/Makefile.am
airpdcap/Makefile.nmake
airpdcap/airpdcap.c
airpdcap/airpdcap_ccmp.c
airpdcap/airpdcap_ccmp.h
airpdcap/airpdcap_debug.c
airpdcap/airpdcap_debug.h
airpdcap/airpdcap_int.h
airpdcap/airpdcap_interop.h
airpdcap/airpdcap_md5.c
airpdcap/airpdcap_md5.h
airpdcap/airpdcap_rijndael.c
airpdcap/airpdcap_rijndael.h
airpdcap/airpdcap_sha1.c
airpdcap/airpdcap_sha1.h
airpdcap/airpdcap_system.h
airpdcap/airpdcap_tkip.c
airpdcap/airpdcap_tkip.h
airpdcap/airpdcap_user.h
airpdcap/airpdcap_wep.c
airpdcap/airpdcap_wep.h
airpdcap/airpdcap_ws.h
configure.in
epan/Makefile.am
epan/dissectors/packet-ieee80211.c
gtk/main.c

index 8bf2a6b243aaed8e198e78f307e913aae34459f5..974de3205c1d4948bbdf78b35839f378f9a7027d 100644 (file)
@@ -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
index 1a7aeb28d44802cf70655325de2277951be45f2a..13f1155cac9edbbc29b206262cfcd284d4d853ad 100644 (file)
--- 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)
index bd5c9c1d9f9d41b451710fe8b21cac5b2997b448..cf3f1e80f8157ff02480cb6598a8584db21008af 100644 (file)
 #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);
index 70a28465dc734409aa8437de910647eb09d290e0..84766c90e3d9eee86d1cfab9223d1404e0b29984 100644 (file)
 
 #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
@@ -151,16 +101,6 @@ typedef struct {
        gint                                    tag;                            /* int for the gtk blinking callback */
 } 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
  */
@@ -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
index 5d7d27bc48c6c9bc4ce223430276d07008147274..fc50901c83e33a49faabfff51ce894acc9ae6659 100644 (file)
 # 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 
index 10cadce94fbe26b9b7c673a8b0975518a0dd5e2a..e2f5f4bd54ff2af7d3d033dd029db651081b67f2 100644 (file)
@@ -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 $<
index 7f7d8dd3d0f09e35d1dc905857d9caaa2db9e20e..ce220ac47280a372b7e81ee9e777968c4f1b281c 100644 (file)
@@ -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"
 /*                                                                                                                                                                                                             */
 /******************************************************************************/
 
 #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
 }
index b3cc2a77bb0cec810274150a40d6bf04b5352864..5dfa85a8f62ef39aac505d3788308b8aa20aaa1b 100644 (file)
@@ -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"
 /*                                                                                                                                                                                                             */
 /******************************************************************************/
 
 /*     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];
index 1a5f50ae6591a2215f978e680597c836d15bca64..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -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
index 21edadcfd8793c6c5534cdd931f7deb74abb7d52..6b6125ef5c5802ea1e875ff77c931ace960b5a8f 100644 (file)
@@ -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
index 1ff582c6ab551260f821b832f313dfa2a956dea1..c41caaeef78618875aba9c3938d2fc0431120869 100644 (file)
@@ -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   */
index dd52a98532c125da32230964e29291d2fe7e2cae..6424be67313df64741d9a7d00f1e8b7558a96f55 100644 (file)
@@ -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
index e596b3a58031374afc0aee4b120c62c88c0d0b52..e398bf21bfa799910edc89efa31b14010a0f9764 100644 (file)
@@ -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 */
index 182bc6a50e31e18de4f33feca63280684c50c3a6..aa7a6727acdd62b5a2b699bf66f1db86dc191f86 100644 (file)
@@ -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 -
index 0a58e31ccadf7f97c30c47e266a68f4f16de31ed..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -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
index cb5755961b0af861ff60c262ea1a14ac89ad4917..c024a2da358d262e9c98805824fae2828841172c 100644 (file)
 /*     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
+/******************************************************************************/
index 7219fcda9f4242ef275fce97034f176f2aaa347f..b113c84643b39cd52f437691ec682ddab047bee2 100644 (file)
@@ -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
index d280e0b2c8348454d8a00c5ca6e61cb3b6ab478e..b49fe0d0a889df9e4fee5319c1863b81ddf97c0c 100644 (file)
@@ -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
+/******************************************************************************/
index c696a0b698cf6b5ee0a0fe2335a41190eebc2329..87ebfb643d7fe2e36b564e7af28075d9d2f2380d 100644 (file)
 /******************************************************************************/
 /*     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
index 28a7c2cf69dae6cc16159099e2fbb8abe218028a..4c8d42bc593c34ea5e42a9d14091163808f0db93 100644 (file)
 #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.
 * 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 */
index d9fb2bdd9c89113d1b38bffbeb273a9391da4ce0..886540e6c956f84fe43a5c5e996d922724561b5d 100644 (file)
@@ -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"
 /*                                                                                                                                                                                                             */
 /******************************************************************************/
 
 /*     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;
index 4b7b2c49be1ebeb7ba7a6aa14bdd9d3b04197e01..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -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
index b872b931f54fb77d535f06b7208055a780faa035..b637ea90b89a0c3d82b2a8d1fd4895b1f6bcca9b 100644 (file)
@@ -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
 /*                                                                                                                                                                                                             */
 /*                                                                                                                                                                                                             */
 /******************************************************************************/
 /******************************************************************************/
 /*     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 */
index f4dc72cb3034287464c954b06275fe0ca41116c1..1501d611555b4a71d81ad0e8622a84f901685ece 100644 (file)
@@ -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
+}
index 1534e2d564ea40c31fe7b3b95074b738f9bb1502..a7885c18f689c84bda99355b214e862ba810c75d 100644 (file)
@@ -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 */
index 1811bd1288d27e9236cd73f7d345ec517ae95dcb..6eec4d0ff6e1ce9916bc92b517c32e1b0f81fc28 100644 (file)
@@ -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 */
index b03164a3edb9e33b776dca18f59d900bcd8e9389..67f58cd9effc993e82ed1fc3f8c1cd755499fd2c 100644 (file)
@@ -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
index 966a29a6128ba72a217fc35784815a892d69b1c7..4443d771059307b0103dbff27cd2759ea6e0cdd5 100644 (file)
@@ -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
index b40b11b48c1e76276f10ec5649fa7236d7341b1b..9285be48a0e74549a16ddf9f3a2e5c994a029d67 100644 (file)
@@ -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
 
index 150f7eb5d459d67c480cac0aced283167071de1b..3c139ea71f907cc74aa2b2c0b452bd6af3d5e1d8 100644 (file)
 
 #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