Removed a "statement not reached" warning.
[metze/wireshark/wip.git] / epan / crypt / airpdcap.c
1 /* airpdcap.c
2  *
3  * $Id$
4  * Copyright (c) 2006 CACE Technologies, Davis (California)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * Alternatively, this software may be distributed under the terms of the
20  * GNU General Public License ("GPL") version 2 as published by the Free
21  * Software Foundation.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36 /****************************************************************************/
37 /*      File includes                                                           */
38
39 #ifdef HAVE_CONFIG_H
40 # include "config.h"
41 #endif
42
43 #include <epan/tvbuff.h>
44 #include <epan/crc32.h>
45 #include <epan/strutil.h>
46 #include <epan/emem.h>
47 #include <epan/pint.h>
48 #include <epan/crypt/crypt-rc4.h>
49 #include <epan/crypt/airpdcap_rijndael.h>
50
51 #include "airpdcap_system.h"
52 #include "airpdcap_int.h"
53
54 #include "crypt-sha1.h"
55 #include "crypt-md5.h"
56
57 #include "airpdcap_debug.h"
58
59 #include "wep-wpadefs.h"
60
61
62 /****************************************************************************/
63
64 /****************************************************************************/
65 /*      Constant definitions                                                    */
66
67 #define AIRPDCAP_SHA_DIGEST_LEN 20
68
69 /*      EAPOL definitions                                                       */
70 /**
71  * Length of the EAPOL-Key key confirmation key (KCK) used to calculate
72  * MIC over EAPOL frame and validate an EAPOL packet (128 bits)
73  */
74 #define AIRPDCAP_WPA_KCK_LEN    16
75 /**
76  *Offset of the Key MIC in the EAPOL packet body
77  */
78 #define AIRPDCAP_WPA_MICKEY_OFFSET      77
79 /**
80  * Maximum length of the EAPOL packet (it depends on the maximum MAC
81  * frame size)
82  */
83 #define AIRPDCAP_WPA_MAX_EAPOL_LEN      4095
84 /**
85  * EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and
86  * from a STA when neither the group nor pairwise ciphers are CCMP for
87  * Key Descriptor 1.
88  * @note
89  * Defined in 802.11i-2004, page 78
90  */
91 #define AIRPDCAP_WPA_KEY_VER_NOT_CCMP   1
92 /**
93  * EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and
94  * from a STA when either the pairwise or the group cipher is AES-CCMP
95  * for Key Descriptor 2.
96  * /note
97  * Defined in 802.11i-2004, page 78
98  */
99 #define AIRPDCAP_WPA_KEY_VER_AES_CCMP   2
100
101 /** Define EAPOL Key Descriptor type values:  use 254 for WPA and 2 for WPA2 **/
102 #define AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR 254
103 #define AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR 2
104
105 /****************************************************************************/
106
107
108
109 /****************************************************************************/
110 /*      Macro definitions                                                       */
111
112 extern const UINT32 crc32_table[256];
113 #define CRC(crc, ch)     (crc = (crc >> 8) ^ crc32_table[(crc ^ (ch)) & 0xff])
114
115 #define AIRPDCAP_GET_TK(ptk)    (ptk + 32)
116
117 /****************************************************************************/
118
119 /****************************************************************************/
120 /*      Type definitions                                                        */
121
122 /*      Internal function prototype declarations                                */
123
124 #ifdef  __cplusplus
125 extern "C" {
126 #endif
127
128 /**
129  * It is a step of the PBKDF2 (specifically the PKCS #5 v2.0) defined in
130  * the RFC 2898 to derive a key (used as PMK in WPA)
131  * @param password [IN] pointer to a password (sequence of between 8 and
132  * 63 ASCII encoded characters)
133  * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
134  * encoded characters
135  * @param iterations [IN] times to hash the password (4096 for WPA)
136  * @param count [IN] ???
137  * @param output [OUT] pointer to a preallocated buffer of
138  * AIRPDCAP_SHA_DIGEST_LEN characters that will contain a part of the key
139  */
140 static INT AirPDcapRsnaPwd2PskStep(
141     const guint8 *ppbytes,
142     const guint passLength,
143     const CHAR *ssid,
144     const size_t ssidLength,
145     const INT iterations,
146     const INT count,
147     UCHAR *output)
148     ;
149
150 /**
151  * It calculates the passphrase-to-PSK mapping reccomanded for use with
152  * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
153  * 2898.
154  * @param password [IN] pointer to a password (sequence of between 8 and
155  * 63 ASCII encoded characters)
156  * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
157  * encoded characters
158  * @param output [OUT] calculated PSK (to use as PMK in WPA)
159  * @note
160  * Described in 802.11i-2004, page 165
161  */
162 static INT AirPDcapRsnaPwd2Psk(
163     const CHAR *passphrase,
164     const CHAR *ssid,
165     const size_t ssidLength,
166     UCHAR *output)
167     ;
168
169 static INT AirPDcapRsnaMng(
170     UCHAR *decrypt_data,
171     guint mac_header_len,
172     guint *decrypt_len,
173     PAIRPDCAP_KEY_ITEM key,
174     AIRPDCAP_SEC_ASSOCIATION *sa,
175     INT offset)
176     ;
177
178 static INT AirPDcapWepMng(
179     PAIRPDCAP_CONTEXT ctx,
180     UCHAR *decrypt_data,
181     guint mac_header_len,
182     guint *decrypt_len,
183     PAIRPDCAP_KEY_ITEM key,
184     AIRPDCAP_SEC_ASSOCIATION *sa,
185     INT offset)
186     ;
187
188 static INT AirPDcapRsna4WHandshake(
189     PAIRPDCAP_CONTEXT ctx,
190     const UCHAR *data,
191     AIRPDCAP_SEC_ASSOCIATION *sa,
192     PAIRPDCAP_KEY_ITEM key,
193     INT offset)
194     ;
195 /**
196  * It checks whether the specified key is corrected or not.
197  * @note
198  * For a standard WEP key the length will be changed to the standard
199  * length, and the type changed in a generic WEP key.
200  * @param key [IN] pointer to the key to validate
201  * @return
202  * - TRUE: the key contains valid fields and values
203  * - FALSE: the key has some invalid field or value
204  */
205 static INT AirPDcapValidateKey(
206     PAIRPDCAP_KEY_ITEM key)
207     ;
208
209 static INT AirPDcapRsnaMicCheck(
210     UCHAR *eapol,
211     USHORT eapol_len,
212     UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
213     USHORT key_ver)
214     ;
215
216 /**
217  * @param ctx [IN] pointer to the current context
218  * @param id [IN] id of the association (composed by BSSID and MAC of
219  * the station)
220  * @return
221  * - index of the Security Association structure if found
222  * - -1, if the specified addresses pair BSSID-STA MAC has not been found
223  */
224 static INT AirPDcapGetSa(
225     PAIRPDCAP_CONTEXT ctx,
226     AIRPDCAP_SEC_ASSOCIATION_ID *id)
227     ;
228
229 static INT AirPDcapStoreSa(
230     PAIRPDCAP_CONTEXT ctx,
231     AIRPDCAP_SEC_ASSOCIATION_ID *id)
232     ;
233
234 static const UCHAR * AirPDcapGetStaAddress(
235     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
236     ;
237
238 static const UCHAR * AirPDcapGetBssidAddress(
239     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
240     ;
241
242 static void AirPDcapRsnaPrfX(
243     AIRPDCAP_SEC_ASSOCIATION *sa,
244     const UCHAR pmk[32],
245     const UCHAR snonce[32],
246     const INT x,        /*      for TKIP 512, for CCMP 384      */
247     UCHAR *ptk)
248     ;
249
250 #ifdef  __cplusplus
251 }
252 #endif
253
254 /****************************************************************************/
255
256 /****************************************************************************/
257 /* Exported function definitions                                                */
258
259 #ifdef  __cplusplus
260 extern "C" {
261 #endif
262
263 const guint8 broadcast_mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
264
265
266 /* NOTE : this assumes the WPA RSN IE format.  If it were to be a generic RSN IE, then
267    we would need to change the structure since it could be variable length depending on the number
268    of unicast OUI and auth OUI. */
269 typedef struct {
270         guint8 bElementID;
271         guint8 bLength;
272         guint8  OUI[4];
273         guint16 iVersion;
274         guint8  multicastOUI[4];
275         guint16 iUnicastCount;  /* this should always be 1 for WPA client */
276         guint8  unicastOUI[4];
277         guint16 iAuthCount;             /* this should always be 1 for WPA client */
278         guint8  authOUI[4];
279         guint16 iWPAcap;
280 } RSN_IE;
281
282 #define EAPKEY_MIC_LEN  16  /* length of the MIC key for EAPoL_Key packet's MIC using MD5 */
283 #define NONCE_LEN 32
284
285 typedef struct {
286         guint8                  type;
287         guint8                  key_information[2];  /* Make this an array to avoid alignment issues */
288         guint8                  key_length[2];  /* Make this an array to avoid alignment issues */
289         guint8                  replay_counter[8];
290         guint8                  key_nonce[NONCE_LEN];
291         guint8                  key_iv[16];
292         guint8                  key_sequence_counter[8];  /* also called the RSC */
293         guint8                  key_id[8];
294         guint8                  key_mic[EAPKEY_MIC_LEN];
295         guint8                  key_data_len[2];  /* Make this an array rather than a U16 to avoid alignment shifting */
296         guint8                  ie[sizeof(RSN_IE)]; /* Make this an array to avoid alignment issues */
297 } EAPOL_RSN_KEY,  * P_EAPOL_RSN_KEY;
298
299
300
301 /* A note about some limitations with the WPA decryption:
302
303 Unless someone takes the time to restructure the current method used for maintaining decryption keys, there
304 will be some anomalies observed when using the decryption feature.
305
306 Currently, there is only one pairwise (unicast) key and one group (broadcast) key saved for each security association
307 (SA).  As a result, if a wireless sniffer session captures the traffic of a station (STA) associating with an AP
308 more than once, or captures a STA roaming, then you will not be able to arbitrarilly click on different encrypted
309 packets in the trace and observe their internal decrypted structure.  This is because when you click on a packet,
310 Wireshark immediately performs the decryption routine with whatever the last key used was.  It does not maintain a
311 cache of all the keys that were used by this STA/AP pairing.
312
313 However, if you are just looking at the summary lines of a capture, it will appear that everything was decrypted properly.
314 This is because when first performing a capture or initially reading a capture file, Wireshark will first
315 process the packets in order. As it encounters new EAPOL packets, it will update its internal key list with the
316 newfound key. Then it will use that key for decrypting subsequent packets. Each time a new key is found, the old key
317 is overwritten. So, if you then click on a packet that was previously decrypted properly, it might suddenly no longer
318 be decrypted because a later EAPOL key had caused the internal decryption key to be updated.
319
320 For broadcast packets, there is a clunky work-around. If the AP is using group-key rotation, you simply have to find the appropriate
321 EAPOL group key packet (usually size is 211 bytes and will have a protocol type of EAPOL and Info field of Key). If you click on it
322 and then click on the broadcast packet you are trying to decrypt, the packet will be decrypted properly. By first
323 clicking on the EAPOL packet for the group-key, you will force Wireshark to parse that packet and load the group-key it
324 contains.  That group key will then be used for decrypting all subsequent broadcast packets you click on.
325
326 Ideally, it would be best to maintain an expanding list of SA keys. Perhaps we could associate packet number ranges
327 that they apply to.  Then, whenever we need to decrypt a packet, we can determine which key to use based on whether
328 it is broadcast or unicast and within what packet number range it falls.
329
330 Either that, or store two versions of encrypted packets - the orginal packet and it's successfully
331 decrypted version.  Then Wireshark wouldn't have to decrypt packets on the fly if they were already successfully decrypted.
332
333 */
334
335
336 static void
337 AirPDcapDecryptWPABroadcastKey(P_EAPOL_RSN_KEY pEAPKey, guint8  *decryption_key, PAIRPDCAP_SEC_ASSOCIATION sa)
338 {
339         guint8  new_key[32];
340         guint8 key_version;
341         guint8  *szEncryptedKey;
342         guint16 key_len = 0;
343         static AIRPDCAP_KEY_ITEM dummy_key; /* needed in case AirPDcapRsnaMng() wants the key structure */
344
345         /* We skip verifying the MIC of the key. If we were implementing a WPA supplicant we'd want to verify, but for a sniffer it's not needed. */
346
347         /* Preparation for decrypting the group key -  determine group key data length */
348         /* depending on whether it's a TKIP or AES encryption key */
349         key_version = AIRPDCAP_EAP_KEY_DESCR_VER(pEAPKey->key_information[1]);
350         if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
351                 /* TKIP */
352                 key_len = pntohs(pEAPKey->key_length);
353         }else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
354                 /* AES */
355                 key_len = pntohs(pEAPKey->key_data_len);
356         }
357     if (key_len > sizeof(RSN_IE) || key_len == 0) { /* Don't read past the end of pEAPKey->ie */
358         return;
359     }
360
361         /* Encrypted key is in the information element field of the EAPOL key packet */
362         szEncryptedKey = g_memdup(pEAPKey->ie, key_len);
363
364         DEBUG_DUMP("Encrypted Broadcast key:", szEncryptedKey, key_len);
365         DEBUG_DUMP("KeyIV:", pEAPKey->key_iv, 16);
366         DEBUG_DUMP("decryption_key:", decryption_key, 16);
367
368         /* Build the full decryption key based on the IV and part of the pairwise key */
369         memcpy(new_key, pEAPKey->key_iv, 16);
370         memcpy(new_key+16, decryption_key, 16);
371         DEBUG_DUMP("FullDecrKey:", new_key, 32);
372
373         if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
374                 guint8 dummy[256];
375                 /* TKIP key */
376                 /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
377                 /* group key is decrypted using RC4.  Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
378
379                 rc4_state_struct rc4_state;
380                 crypt_rc4_init(&rc4_state, new_key, sizeof(new_key));
381
382                 /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
383                 crypt_rc4(&rc4_state, dummy, 256);
384                 crypt_rc4(&rc4_state, szEncryptedKey, key_len);
385
386         } else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
387                 /* AES CCMP key */
388
389                 guint8 key_found;
390                 guint16 key_index;
391                 guint8 *decrypted_data;
392
393                 /* This storage is needed for the AES_unwrap function */
394                 decrypted_data = (guint8 *) g_malloc(key_len);
395
396                 AES_unwrap(decryption_key, 16, szEncryptedKey,  key_len, decrypted_data);
397
398                 /* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure.
399                    The key itself is stored as a GTK KDE
400                    WPA2 IE (1 byte) id = 0xdd, length (1 byte), GTK OUI (4 bytes), key index (1 byte) and 1 reserved byte. Thus we have to
401                    pass pointer to the actual key with 8 bytes offset */
402
403                 key_found = FALSE;
404                 key_index = 0;
405                 while(key_index < key_len && !key_found){
406                         guint8 rsn_id;
407
408                         /* Get RSN ID */
409                         rsn_id = decrypted_data[key_index];
410
411                         if (rsn_id != 0xdd){
412                                 key_index += decrypted_data[key_index+1]+2;
413                         }else{
414                                 key_found = TRUE;
415                         }
416                 }
417
418                 if (key_found){
419                         /* Skip over the GTK header info, and don't copy past the end of the encrypted data */
420                         memcpy(szEncryptedKey, decrypted_data+key_index+8, key_len-key_index-8);
421                 }
422
423                 g_free(decrypted_data);
424         }
425
426         /* Decrypted key is now in szEncryptedKey with len of key_len */
427         DEBUG_DUMP("Broadcast key:", szEncryptedKey, key_len);
428
429         /* Load the proper key material info into the SA */
430         sa->key = &dummy_key;  /* we just need key to be not null because it is checked in AirPDcapRsnaMng().  The WPA key materials are actually in the .wpa structure */
431         sa->validKey = TRUE;
432         sa->wpa.key_ver = key_version;
433
434         /* Since this is a GTK and it's size is only 32 bytes (vs. the 64 byte size of a PTK), we fake it and put it in at a 32-byte offset so the  */
435         /* AirPDcapRsnaMng() function will extract the right piece of the GTK for decryption. (The first 16 bytes of the GTK are used for decryption.) */
436         memset(sa->wpa.ptk, 0, sizeof(sa->wpa.ptk));
437         memcpy(sa->wpa.ptk+32, szEncryptedKey, key_len);
438         g_free(szEncryptedKey);
439 }
440
441
442 /* Return a pointer the the requested SA. If it doesn't exist create it. */
443 PAIRPDCAP_SEC_ASSOCIATION
444 AirPDcapGetSaPtr(
445         PAIRPDCAP_CONTEXT ctx,
446     AIRPDCAP_SEC_ASSOCIATION_ID *id)
447 {
448     int sa_index;
449
450         /* search for a cached Security Association for supplied BSSID and STA MAC      */
451         if ((sa_index=AirPDcapGetSa(ctx, id))==-1) {
452                 /* create a new Security Association if it doesn't currently exist      */
453                 if ((sa_index=AirPDcapStoreSa(ctx, id))==-1) {
454                         return NULL;
455                 }
456         }
457         /* get the Security Association structure       */
458         return &ctx->sa[sa_index];
459 }
460
461 #define GROUP_KEY_PAYLOAD_LEN (8+4+sizeof(EAPOL_RSN_KEY))
462 INT AirPDcapScanForGroupKey(
463     PAIRPDCAP_CONTEXT ctx,
464     const guint8 *data,
465     const guint mac_header_len,
466     const guint tot_len
467 )
468 {
469     const UCHAR *address;
470     AIRPDCAP_SEC_ASSOCIATION_ID id;
471     guint bodyLength;
472     PAIRPDCAP_SEC_ASSOCIATION sta_sa;
473     PAIRPDCAP_SEC_ASSOCIATION sa;
474     int offset = 0;
475     const guint8 dot1x_header[] = {
476         0xAA,             /* DSAP=SNAP */
477         0xAA,             /* SSAP=SNAP */
478         0x03,             /* Control field=Unnumbered frame */
479         0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
480         0x88, 0x8E        /* Type: 802.1X authentication */
481     };
482
483         P_EAPOL_RSN_KEY pEAPKey;
484 #ifdef _DEBUG
485     CHAR msgbuf[255];
486 #endif
487
488         AIRPDCAP_DEBUG_TRACE_START("AirPDcapScanForGroupKey");
489
490         if (mac_header_len + GROUP_KEY_PAYLOAD_LEN < tot_len) {
491             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Message too short", AIRPDCAP_DEBUG_LEVEL_3);
492             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
493         }
494
495         /* cache offset in the packet data */
496         offset = mac_header_len;
497
498     /* check if the packet has an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
499     if (memcmp(data+offset, dot1x_header, 8) == 0) {
500
501                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
502
503         /* skip LLC header      */
504         offset+=8;
505
506
507        /*       check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25)    */
508         if (data[offset+1]!=3) {
509             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_3);
510             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
511         }
512
513         /* get and check the body length (IEEE 802.1X-2004, pg. 25)     */
514         bodyLength=pntohs(data+offset+2);
515         if ((tot_len-offset-4) < bodyLength) {
516             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_3);
517             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
518         }
519
520         /* skip EAPOL MPDU and go to the first byte of the body */
521         offset+=4;
522
523                 pEAPKey = (P_EAPOL_RSN_KEY) (data+offset);
524
525         /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
526         if (/*pEAPKey->type!=0x1 &&*/   /* RC4 Key Descriptor Type (deprecated) */
527             pEAPKey->type != AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR &&                /* IEEE 802.11 Key Descriptor Type       (WPA2)         */
528             pEAPKey->type != AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR)           /* 254 = RSN_KEY_DESCRIPTOR - WPA,                                      */
529         {
530             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_3);
531             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
532         }
533
534         /* start with descriptor body   */
535         offset+=1;
536
537                 /* Verify the bitfields: Key = 0(groupwise) Mic = 1 Ack = 1 Secure = 1 */
538                 if (AIRPDCAP_EAP_KEY(data[offset+1])!=0 ||
539                         AIRPDCAP_EAP_ACK(data[offset+1])!=1 ||
540                         AIRPDCAP_EAP_MIC(data[offset]) != 1 ||
541                         AIRPDCAP_EAP_SEC(data[offset]) != 1){
542
543             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Key bitfields not correct", AIRPDCAP_DEBUG_LEVEL_3);
544             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
545                 }
546
547                 /* get BSSID */
548                 if ( (address=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
549                         memcpy(id.bssid, address, AIRPDCAP_MAC_LEN);
550 #ifdef _DEBUG
551                         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]);
552 #endif
553                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
554                 } else {
555                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
556                         return AIRPDCAP_RET_REQ_DATA;
557                 }
558
559                 /* force STA address to be the broadcast MAC so we create an SA for the groupkey        */
560                 memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
561
562                 /* get the Security Association structure for the broadcast MAC and AP */
563                 sa = AirPDcapGetSaPtr(ctx, &id);
564                 if (sa == NULL){
565                         return AIRPDCAP_RET_UNSUCCESS;
566                 }
567
568                 /* Get the SA for the STA, since we need its pairwise key to decrpyt the group key */
569
570                 /* get STA address      */
571                 if ( (address=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
572                         memcpy(id.sta, address, AIRPDCAP_MAC_LEN);
573 #ifdef _DEBUG
574                         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]);
575 #endif
576                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
577                 } else {
578                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
579                         return AIRPDCAP_RET_REQ_DATA;
580                 }
581
582                 sta_sa = AirPDcapGetSaPtr(ctx, &id);
583                 if (sta_sa == NULL){
584                         return AIRPDCAP_RET_UNSUCCESS;
585                 }
586
587                 /* Extract the group key and install it in the SA */
588                 AirPDcapDecryptWPABroadcastKey(pEAPKey, sta_sa->wpa.ptk+16, sa);
589
590         }else{
591                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Skipping: not an EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
592         }
593
594         AIRPDCAP_DEBUG_TRACE_END("AirPDcapScanForGroupKey");
595         return 0;
596 }
597
598
599 INT AirPDcapPacketProcess(
600     PAIRPDCAP_CONTEXT ctx,
601     const guint8 *data,
602     const guint mac_header_len,
603     const guint tot_len,
604     UCHAR *decrypt_data,
605     guint *decrypt_len,
606     PAIRPDCAP_KEY_ITEM key,
607     gboolean mngHandshake,
608     gboolean mngDecrypt)
609 {
610     const UCHAR *address;
611     AIRPDCAP_SEC_ASSOCIATION_ID id;
612     PAIRPDCAP_SEC_ASSOCIATION sa;
613     int offset = 0;
614     guint bodyLength;
615     const guint8 dot1x_header[] = {
616         0xAA,             /* DSAP=SNAP */
617         0xAA,             /* SSAP=SNAP */
618         0x03,             /* Control field=Unnumbered frame */
619         0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
620         0x88, 0x8E        /* Type: 802.1X authentication */
621     };
622
623 #ifdef _DEBUG
624     CHAR msgbuf[255];
625 #endif
626
627     AIRPDCAP_DEBUG_TRACE_START("AirPDcapPacketProcess");
628
629     if (ctx==NULL) {
630         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
631         AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
632         return AIRPDCAP_RET_UNSUCCESS;
633     }
634     if (data==NULL || tot_len==0) {
635         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5);
636         AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
637         return AIRPDCAP_RET_UNSUCCESS;
638     }
639
640     /* check if the packet is of data type      */
641     if (AIRPDCAP_TYPE(data[0])!=AIRPDCAP_TYPE_DATA) {
642         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
643         return AIRPDCAP_RET_NO_DATA;
644     }
645
646     /* check correct packet size, to avoid wrong elaboration of encryption algorithms   */
647     if (tot_len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) {
648         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5);
649         return AIRPDCAP_RET_WRONG_DATA_SIZE;
650     }
651
652     /* get BSSID */
653     if ( (address=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
654         memcpy(id.bssid, address, AIRPDCAP_MAC_LEN);
655 #ifdef _DEBUG
656         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]);
657 #endif
658         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
659     } else {
660         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
661         return AIRPDCAP_RET_REQ_DATA;
662     }
663
664     /* get STA address  */
665     if ( (address=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
666         memcpy(id.sta, address, AIRPDCAP_MAC_LEN);
667 #ifdef _DEBUG
668         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]);
669 #endif
670         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
671     } else {
672         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
673         return AIRPDCAP_RET_REQ_DATA;
674     }
675
676         /* get the Security Association structure for the STA and AP */
677         sa = AirPDcapGetSaPtr(ctx, &id);
678         if (sa == NULL){
679                 return AIRPDCAP_RET_UNSUCCESS;
680         }
681
682     /* cache offset in the packet data (to scan encryption data)        */
683     offset = mac_header_len;
684
685     /*  check if data is encrypted (use the WEP bit in the Frame Control field) */
686     if (AIRPDCAP_WEP(data[1])==0)
687     {
688         if (mngHandshake) {
689             /* data is sent in cleartext, check if is an authentication message or end the process      */
690             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Unencrypted data", AIRPDCAP_DEBUG_LEVEL_3);
691
692             /* check if the packet as an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24)  */
693             if (memcmp(data+offset, dot1x_header, 8) == 0) {
694                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
695
696                 /* skip LLC header      */
697                 offset+=8;
698
699                 /* check the version of the EAPOL protocol used (IEEE 802.1X-2004, pg. 24)      */
700                 /* TODO EAPOL protocol version to check?        */
701                 /*if (data[offset]!=2) {
702                     AIRPDCAP_DEBUG_PRINT_LINE("EAPOL protocol version not recognized", AIRPDCAP_DEBUG_LEVEL_5);
703                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
704                 }*/
705
706                 /*      check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25)    */
707                 if (data[offset+1]!=3) {
708                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_5);
709                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
710                 }
711
712                 /* get and check the body length (IEEE 802.1X-2004, pg. 25)     */
713                 bodyLength=pntohs(data+offset+2);
714                 if ((tot_len-offset-4) < bodyLength) {
715                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_5);
716                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
717                 }
718
719                 /* skip EAPOL MPDU and go to the first byte of the body */
720                 offset+=4;
721
722                 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
723                 if (/*data[offset]!=0x1 &&*/    /* RC4 Key Descriptor Type (deprecated) */
724                     data[offset]!=0x2 &&                /* IEEE 802.11 Key Descriptor Type                      */
725                     data[offset]!=0xFE)         /* TODO what's this value???                                    */
726                 {
727                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_5);
728                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
729                 }
730
731                 /* start with descriptor body   */
732                 offset+=1;
733
734                 /* manage the 4-way handshake to define the key */
735                 return AirPDcapRsna4WHandshake(ctx, data, sa, key, offset);
736             } else {
737                 /* cleartext message, not authentication */
738                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "No authentication data", AIRPDCAP_DEBUG_LEVEL_5);
739                 return AIRPDCAP_RET_NO_DATA_ENCRYPTED;
740             }
741         }
742     } else {
743         if (mngDecrypt) {
744
745             if (decrypt_data==NULL)
746                 return AIRPDCAP_RET_UNSUCCESS;
747
748             /*  create new header and data to modify    */
749             *decrypt_len = tot_len;
750             memcpy(decrypt_data, data, *decrypt_len);
751
752             /* encrypted data   */
753             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3);
754
755             /* check the Extension IV to distinguish between WEP encryption and WPA encryption  */
756             /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP,     */
757             /*          IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP,           */
758             /*          IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP                    */
759             if (AIRPDCAP_EXTIV(data[offset+3])==0) {
760                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3);
761                 return AirPDcapWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
762             } else {
763                                 INT status;
764                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3);
765
766                                 /* If index >= 1, then use the group key.  This will not work if the AP is using
767                                    more than one group key simultaneously.  I've not seen this in practice, however. Usually an AP
768                                    will rotate between the two key index values of 1 and 2 whenever it needs to change the group key to be used. */
769                                 if (AIRPDCAP_KEY_INDEX(data[offset+3])>=1){
770
771                                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "The key index = 1. This is encrypted with a group key.", AIRPDCAP_DEBUG_LEVEL_3);
772
773                                         /* force STA address to broadcast MAC so we load the SA for the groupkey        */
774                                         memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
775
776 #ifdef _DEBUG
777                                         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]);
778                                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
779 #endif
780
781                                         /* search for a cached Security Association for current BSSID and broadcast MAC */
782                                         sa = AirPDcapGetSaPtr(ctx, &id);
783                                         if (sa == NULL){
784                                                 return AIRPDCAP_RET_UNSUCCESS;
785                                         }
786                                 }
787
788                                 /* Decrypt the packet using the appropriate SA */
789                 status = AirPDcapRsnaMng(decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
790
791                                  /* If we successfully decrypted a packet, scan it to see if it contains a group key handshake.
792                                    The group key handshake could be sent at any time the AP wants to change the key (such as when
793                                    it is using key rotation) so we must scan every packet. */
794                                 if (status == AIRPDCAP_RET_SUCCESS)
795                                         AirPDcapScanForGroupKey(ctx, decrypt_data, mac_header_len, *decrypt_len);
796                                 return status;
797             }
798         }
799     }
800
801     return AIRPDCAP_RET_UNSUCCESS;
802 }
803
804 INT AirPDcapSetKeys(
805     PAIRPDCAP_CONTEXT ctx,
806     AIRPDCAP_KEY_ITEM keys[],
807     const size_t keys_nr)
808 {
809     INT i;
810     INT success;
811     AIRPDCAP_DEBUG_TRACE_START("AirPDcapSetKeys");
812
813     if (ctx==NULL || keys==NULL) {
814         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "NULL context or NULL keys array", AIRPDCAP_DEBUG_LEVEL_3);
815         AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
816         return 0;
817     }
818
819     if (keys_nr>AIRPDCAP_MAX_KEYS_NR) {
820         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Keys number greater than maximum", AIRPDCAP_DEBUG_LEVEL_3);
821         AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
822         return 0;
823     }
824
825     /* clean key and SA collections before setting new ones     */
826     AirPDcapInitContext(ctx);
827
828     /* check and insert keys    */
829     for (i=0, success=0; i<(INT)keys_nr; i++) {
830         if (AirPDcapValidateKey(keys+i)==TRUE) {
831             if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD) {
832                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PWD key", AIRPDCAP_DEBUG_LEVEL_4);
833                 AirPDcapRsnaPwd2Psk(keys[i].UserPwd.Passphrase, keys[i].UserPwd.Ssid, keys[i].UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
834             }
835 #ifdef  _DEBUG
836             else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
837                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PMK key", AIRPDCAP_DEBUG_LEVEL_4);
838             } else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WEP) {
839                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WEP key", AIRPDCAP_DEBUG_LEVEL_4);
840             } else {
841                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a key", AIRPDCAP_DEBUG_LEVEL_4);
842             }
843 #endif
844             memcpy(&ctx->keys[success], &keys[i], sizeof(keys[i]));
845             success++;
846         }
847     }
848
849     ctx->keys_nr=success;
850
851     AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
852     return success;
853 }
854
855 static void
856 AirPDcapCleanKeys(
857     PAIRPDCAP_CONTEXT ctx)
858 {
859     AIRPDCAP_DEBUG_TRACE_START("AirPDcapCleanKeys");
860
861     if (ctx==NULL) {
862         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
863         AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
864         return;
865     }
866
867     memset(ctx->keys, 0, sizeof(AIRPDCAP_KEY_ITEM) * AIRPDCAP_MAX_KEYS_NR);
868
869     ctx->keys_nr=0;
870
871     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "Keys collection cleaned!", AIRPDCAP_DEBUG_LEVEL_5);
872     AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
873 }
874
875 INT AirPDcapGetKeys(
876     const PAIRPDCAP_CONTEXT ctx,
877     AIRPDCAP_KEY_ITEM keys[],
878     const size_t keys_nr)
879 {
880     UINT i;
881     UINT j;
882     AIRPDCAP_DEBUG_TRACE_START("AirPDcapGetKeys");
883
884     if (ctx==NULL) {
885         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
886         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
887         return 0;
888     } else if (keys==NULL) {
889         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL keys array", AIRPDCAP_DEBUG_LEVEL_5);
890         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
891         return (INT)ctx->keys_nr;
892     } else {
893         for (i=0, j=0; i<ctx->keys_nr && i<keys_nr && i<AIRPDCAP_MAX_KEYS_NR; i++) {
894             memcpy(&keys[j], &ctx->keys[i], sizeof(keys[j]));
895             j++;
896             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "Got a key", AIRPDCAP_DEBUG_LEVEL_5);
897         }
898
899         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
900         return j;
901     }
902 }
903
904 /*
905  * XXX - This won't be reliable if a packet containing SSID "B" shows
906  * up in the middle of a 4-way handshake for SSID "A".
907  * We should probably use a small array or hash table to keep multiple
908  * SSIDs.
909  */
910 INT AirPDcapSetLastSSID(
911     PAIRPDCAP_CONTEXT ctx,
912     CHAR *pkt_ssid,
913     size_t pkt_ssid_len)
914 {
915     if (!ctx || !pkt_ssid || pkt_ssid_len < 1 || pkt_ssid_len > WPA_SSID_MAX_SIZE)
916         return AIRPDCAP_RET_UNSUCCESS;
917
918     memcpy(ctx->pkt_ssid, pkt_ssid, pkt_ssid_len);
919     ctx->pkt_ssid_len = pkt_ssid_len;
920
921     return AIRPDCAP_RET_SUCCESS;
922 }
923
924 INT AirPDcapInitContext(
925     PAIRPDCAP_CONTEXT ctx)
926 {
927     AIRPDCAP_DEBUG_TRACE_START("AirPDcapInitContext");
928
929     if (ctx==NULL) {
930         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
931         AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
932         return AIRPDCAP_RET_UNSUCCESS;
933     }
934
935     AirPDcapCleanKeys(ctx);
936
937     ctx->first_free_index=0;
938     ctx->index=-1;
939     ctx->sa_index=-1;
940     ctx->pkt_ssid_len = 0;
941
942     memset(ctx->sa, 0, AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR * sizeof(AIRPDCAP_SEC_ASSOCIATION));
943
944     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "Context initialized!", AIRPDCAP_DEBUG_LEVEL_5);
945     AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
946     return AIRPDCAP_RET_SUCCESS;
947 }
948
949 INT AirPDcapDestroyContext(
950     PAIRPDCAP_CONTEXT ctx)
951 {
952     AIRPDCAP_DEBUG_TRACE_START("AirPDcapDestroyContext");
953
954     if (ctx==NULL) {
955         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
956         AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
957         return AIRPDCAP_RET_UNSUCCESS;
958     }
959
960     AirPDcapCleanKeys(ctx);
961
962     ctx->first_free_index=0;
963     ctx->index=-1;
964     ctx->sa_index=-1;
965
966     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "Context destroyed!", AIRPDCAP_DEBUG_LEVEL_5);
967     AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
968     return AIRPDCAP_RET_SUCCESS;
969 }
970
971 #ifdef  __cplusplus
972 }
973 #endif
974
975 /****************************************************************************/
976
977 /****************************************************************************/
978 /* Internal function definitions                                                */
979
980 #ifdef  __cplusplus
981 extern "C" {
982 #endif
983
984 static INT
985 AirPDcapRsnaMng(
986     UCHAR *decrypt_data,
987     guint mac_header_len,
988     guint *decrypt_len,
989     PAIRPDCAP_KEY_ITEM key,
990     AIRPDCAP_SEC_ASSOCIATION *sa,
991     INT offset)
992 {
993     INT ret_value;
994
995     if (sa->key==NULL) {
996         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3);
997         return AIRPDCAP_RET_REQ_DATA;
998     }
999     if (sa->validKey==FALSE) {
1000         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Key not yet valid", AIRPDCAP_DEBUG_LEVEL_3);
1001         return AIRPDCAP_RET_UNSUCCESS;
1002     }
1003     if (sa->wpa.key_ver==1) {
1004         /*      CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm        */
1005         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP", AIRPDCAP_DEBUG_LEVEL_3);
1006
1007                 DEBUG_DUMP("ptk", sa->wpa.ptk, 64);
1008                 DEBUG_DUMP("ptk portion used", AIRPDCAP_GET_TK(sa->wpa.ptk), 16);
1009
1010         ret_value=AirPDcapTkipDecrypt(decrypt_data+offset, *decrypt_len-offset, decrypt_data+AIRPDCAP_TA_OFFSET, AIRPDCAP_GET_TK(sa->wpa.ptk));
1011                 if (ret_value){
1012                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP failed!", AIRPDCAP_DEBUG_LEVEL_3);
1013             return ret_value;
1014                 }
1015
1016         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1017         /* remove MIC (8bytes) and ICV (4bytes) from the end of packet  */
1018         *decrypt_len-=12;
1019     } else {
1020         /*      AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm  */
1021         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3);
1022
1023         ret_value=AirPDcapCcmpDecrypt(decrypt_data, mac_header_len, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk));
1024         if (ret_value)
1025             return ret_value;
1026
1027         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1028         /* remove MIC (8bytes) from the end of packet   */
1029         *decrypt_len-=8;
1030     }
1031
1032     /* remove protection bit    */
1033     decrypt_data[1]&=0xBF;
1034
1035     /* remove TKIP/CCMP header  */
1036     offset = mac_header_len;
1037     *decrypt_len-=8;
1038     memcpy(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset);
1039
1040     if (key!=NULL) {
1041         memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1042
1043         if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1044             key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1045         else if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1046             key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1047     }
1048
1049     return AIRPDCAP_RET_SUCCESS;
1050 }
1051
1052 static INT
1053 AirPDcapWepMng(
1054     PAIRPDCAP_CONTEXT ctx,
1055     UCHAR *decrypt_data,
1056     guint mac_header_len,
1057     guint *decrypt_len,
1058     PAIRPDCAP_KEY_ITEM key,
1059     AIRPDCAP_SEC_ASSOCIATION *sa,
1060     INT offset)
1061 {
1062     UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN];
1063     size_t keylen;
1064     INT ret_value=1;
1065     INT key_index;
1066     AIRPDCAP_KEY_ITEM *tmp_key;
1067     UINT8 useCache=FALSE;
1068     UCHAR *try_data = ep_alloc(*decrypt_len);
1069
1070     if (sa->key!=NULL)
1071         useCache=TRUE;
1072
1073     for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
1074         /* use the cached one, or try all keys  */
1075         if (!useCache) {
1076             tmp_key=&ctx->keys[key_index];
1077         } else {
1078             if (sa->key!=NULL && sa->key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1079                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try cached WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1080                 tmp_key=sa->key;
1081             } else {
1082                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Cached key is not valid, try another WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1083                 tmp_key=&ctx->keys[key_index];
1084             }
1085         }
1086
1087         /* obviously, try only WEP keys...      */
1088         if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP)
1089         {
1090             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1091
1092             memset(wep_key, 0, sizeof(wep_key));
1093             memcpy(try_data, decrypt_data, *decrypt_len);
1094
1095             /* 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)     */
1096             memcpy(wep_key, try_data+mac_header_len, AIRPDCAP_WEP_IVLEN);
1097             keylen=tmp_key->KeyData.Wep.WepKeyLen;
1098             memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
1099
1100             ret_value=AirPDcapWepDecrypt(wep_key,
1101                 keylen+AIRPDCAP_WEP_IVLEN,
1102                 try_data + (mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN),
1103                 *decrypt_len-(mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN));
1104
1105             if (ret_value == AIRPDCAP_RET_SUCCESS)
1106                 memcpy(decrypt_data, try_data, *decrypt_len);
1107         }
1108
1109         if (!ret_value && tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1110             /* the tried key is the correct one, cached in the Security Association     */
1111
1112             sa->key=tmp_key;
1113
1114             if (key!=NULL) {
1115                 memcpy(key, &sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1116                 key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1117             }
1118
1119             break;
1120         } else {
1121             /* the cached key was not valid, try other keys     */
1122
1123             if (useCache==TRUE) {
1124                 useCache=FALSE;
1125                 key_index--;
1126             }
1127         }
1128     }
1129
1130     if (ret_value)
1131         return ret_value;
1132
1133     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "WEP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1134
1135     /* remove ICV (4bytes) from the end of packet       */
1136     *decrypt_len-=4;
1137
1138     /* remove protection bit    */
1139     decrypt_data[1]&=0xBF;
1140
1141     /* remove IC header */
1142     offset = mac_header_len;
1143     *decrypt_len-=4;
1144     memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset);
1145
1146     return AIRPDCAP_RET_SUCCESS;
1147 }
1148
1149 /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85   */
1150 static INT
1151 AirPDcapRsna4WHandshake(
1152     PAIRPDCAP_CONTEXT ctx,
1153     const UCHAR *data,
1154     AIRPDCAP_SEC_ASSOCIATION *sa,
1155     PAIRPDCAP_KEY_ITEM key,
1156     INT offset)
1157 {
1158     AIRPDCAP_KEY_ITEM *tmp_key, pkt_key;
1159     INT key_index;
1160     INT ret_value=1;
1161     UCHAR useCache=FALSE;
1162     UCHAR eapol[AIRPDCAP_EAPOL_MAX_LEN];
1163     USHORT eapol_len;
1164
1165     if (sa->key!=NULL)
1166         useCache=TRUE;
1167
1168     /* a 4-way handshake packet use a Pairwise key type (IEEE 802.11i-2004, pg. 79)     */
1169     if (AIRPDCAP_EAP_KEY(data[offset+1])!=1) {
1170         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Group/STAKey message (not used)", AIRPDCAP_DEBUG_LEVEL_5);
1171         return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1172     }
1173
1174     /* TODO timeouts? reauthentication? */
1175
1176     /* TODO consider key-index  */
1177
1178     /* TODO considera Deauthentications */
1179
1180     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake...", AIRPDCAP_DEBUG_LEVEL_5);
1181
1182     /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85)       */
1183
1184     /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0)       */
1185     if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1186         AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1187         AIRPDCAP_EAP_MIC(data[offset])==0)
1188     {
1189         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 1", AIRPDCAP_DEBUG_LEVEL_3);
1190
1191         /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been                     */
1192         /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current       */
1193         /* local value, the Supplicant discards the message.                                                                                                                                                                    */
1194         /* -> not checked, the Authenticator will be send another Message 1 (hopefully!)                                                                                                */
1195
1196         /* save ANonce (from authenticator)     to derive the PTK with the SNonce (from the 2 message)  */
1197         memcpy(sa->wpa.nonce, data+offset+12, 32);
1198
1199         /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-)       */
1200         sa->wpa.key_ver=AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]);
1201
1202         sa->handshake=1;
1203
1204         return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1205     }
1206
1207     /* 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))    */
1208     if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1209         AIRPDCAP_EAP_ACK(data[offset+1])==0 &&
1210         AIRPDCAP_EAP_MIC(data[offset])==1)
1211     {
1212         if (AIRPDCAP_EAP_SEC(data[offset])==0) {
1213
1214             /* PATCH:   some implementations set secure bit to 0 also in the 4th message                */
1215             /*          to recognize which message is this check if wep_key data length is 0            */
1216             /*          in the 4th message                                                              */
1217             if (data[offset+92]!=0 || data[offset+93]!=0) {
1218                 /* message 2    */
1219                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 2", AIRPDCAP_DEBUG_LEVEL_3);
1220
1221                 /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the   */
1222                 /* outstanding Message 1. If not, it silently discards the message.                                                                                             */
1223                 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame,    */
1224                 /* the Authenticator silently discards Message 2.                                                                                                                                               */
1225                 /* -> not checked; the Supplicant will send another message 2 (hopefully!)                                                                              */
1226
1227                 /* now you can derive the PTK   */
1228                 for (key_index=0; key_index<(INT)ctx->keys_nr || useCache; key_index++) {
1229                     /* use the cached one, or try all keys      */
1230                     if (!useCache) {
1231                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1232                         tmp_key=&ctx->keys[key_index];
1233                     } else {
1234                         /* there is a cached key in the security association, if it's a WPA key try it...       */
1235                         if (sa->key!=NULL &&
1236                             (sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1237                              sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1238                              sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)) {
1239                                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try cached WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1240                                 tmp_key=sa->key;
1241                         } else {
1242                             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Cached key is of a wrong type, try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1243                             tmp_key=&ctx->keys[key_index];
1244                         }
1245                     }
1246
1247                     /* obviously, try only WPA keys...  */
1248                     if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1249                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1250                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)
1251                     {
1252                         if (tmp_key->KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD && tmp_key->UserPwd.SsidLen == 0 && ctx->pkt_ssid_len > 0 && ctx->pkt_ssid_len <= AIRPDCAP_WPA_SSID_MAX_LEN) {
1253                             /* We have a "wildcard" SSID.  Use the one from the packet. */
1254                             memcpy(&pkt_key, tmp_key, sizeof(pkt_key));
1255                             memcpy(&pkt_key.UserPwd.Ssid, ctx->pkt_ssid, ctx->pkt_ssid_len);
1256                              pkt_key.UserPwd.SsidLen = ctx->pkt_ssid_len;
1257                             AirPDcapRsnaPwd2Psk(pkt_key.UserPwd.Passphrase, pkt_key.UserPwd.Ssid,
1258                                 pkt_key.UserPwd.SsidLen, pkt_key.KeyData.Wpa.Psk);
1259                             tmp_key = &pkt_key;
1260                         }
1261
1262                         /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce  */
1263                         AirPDcapRsnaPrfX(sa,                    /* authenticator nonce, bssid, station mac      */
1264                             tmp_key->KeyData.Wpa.Pmk,   /* PMK  */
1265                             data+offset+12,             /* supplicant nonce     */
1266                             512,
1267                             sa->wpa.ptk);
1268
1269                         /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK)   */
1270                         eapol_len=pntohs(data+offset-3)+4;
1271                         memcpy(eapol, &data[offset-5], (eapol_len<AIRPDCAP_EAPOL_MAX_LEN?eapol_len:AIRPDCAP_EAPOL_MAX_LEN));
1272                         ret_value=AirPDcapRsnaMicCheck(eapol,                                           /*      eapol frame (header also)               */
1273                             eapol_len,                                                                                                  /*      eapol frame length                              */
1274                             sa->wpa.ptk,                                                                                                /*      Key Confirmation Key                            */
1275                             AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]));                /*      EAPOL-Key description version   */
1276
1277                         /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches              */
1278                         /* that from the (Re)Association Request message.                                                                                                                                               */
1279                         /*              i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request   */
1280                         /* primitive to terminate the association.                                                                                                                                                              */
1281                         /*              ii) If they do match bit-wise, the Authenticator constructs Message 3.                                                                  */
1282                     }
1283
1284                     if (!ret_value &&
1285                         (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1286                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1287                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK))
1288                     {
1289                         /* the temporary key is the correct one, cached in the Security Association     */
1290
1291                         sa->key=tmp_key;
1292
1293                         if (key!=NULL) {
1294                             memcpy(key, &tmp_key, sizeof(AIRPDCAP_KEY_ITEM));
1295                             if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1296                                 key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1297                             else if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1298                                 key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1299                         }
1300
1301                         break;
1302                     } else {
1303                         /* the cached key was not valid, try other keys */
1304
1305                         if (useCache==TRUE) {
1306                             useCache=FALSE;
1307                             key_index--;
1308                         }
1309                     }
1310                 }
1311
1312                 if (ret_value) {
1313                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "handshake step failed", AIRPDCAP_DEBUG_LEVEL_3);
1314                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1315                 }
1316
1317                 sa->handshake=2;
1318
1319                 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1320             } else {
1321                 /* message 4    */
1322
1323                 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear."      */
1324
1325                 /* TODO check MIC and Replay Counter                                                                                                                                                                                    */
1326                 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
1327                 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                                                */
1328                 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the        */
1329                 /* Authenticator silently discards Message 4.                                                                                                                                                           */
1330
1331                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4 (patched)", AIRPDCAP_DEBUG_LEVEL_3);
1332
1333                 sa->handshake=4;
1334
1335                 sa->validKey=TRUE;
1336
1337                 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1338             }
1339             /* END OF PATCH                                                                                                                                                                     */
1340             /*                                                                                                                                                                                                          */
1341         } else {
1342             /* message 4        */
1343
1344             /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear."  */
1345
1346             /* TODO check MIC and Replay Counter                                                                                                                                                                                        */
1347             /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one     */
1348             /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                                            */
1349             /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the    */
1350             /* Authenticator silently discards Message 4.                                                                                                                                                               */
1351
1352             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4", AIRPDCAP_DEBUG_LEVEL_3);
1353
1354             sa->handshake=4;
1355
1356             sa->validKey=TRUE;
1357
1358             return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1359         }
1360     }
1361
1362     /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1)   */
1363     if (AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1364         AIRPDCAP_EAP_MIC(data[offset])==1)
1365     {
1366                 P_EAPOL_RSN_KEY pEAPKey;
1367         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 3", AIRPDCAP_DEBUG_LEVEL_3);
1368
1369         /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field              */
1370         /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1.  */
1371         /* -> not checked, the Authenticator will send another message 3 (hopefully!)                                                                                           */
1372
1373         /*      TODO check page 88 (RNS)        */
1374
1375                 /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1376                                  In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key.*/
1377                 pEAPKey = (P_EAPOL_RSN_KEY)(&(data[offset-1]));
1378                 if (pEAPKey->type == AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR){
1379                         PAIRPDCAP_SEC_ASSOCIATION broadcast_sa;
1380                         AIRPDCAP_SEC_ASSOCIATION_ID id;
1381
1382                         /* Get broadcacst SA for the current BSSID */
1383                         memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
1384                         memcpy(id.bssid, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1385                         broadcast_sa = AirPDcapGetSaPtr(ctx, &id);
1386
1387                         if (broadcast_sa == NULL){
1388                                 return AIRPDCAP_RET_UNSUCCESS;
1389                         }
1390                         AirPDcapDecryptWPABroadcastKey(pEAPKey, sa->wpa.ptk+16, broadcast_sa);
1391                 }
1392
1393         return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1394     }
1395
1396     return AIRPDCAP_RET_UNSUCCESS;
1397 }
1398
1399 static INT
1400 AirPDcapRsnaMicCheck(
1401     UCHAR *eapol,
1402     USHORT eapol_len,
1403     UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
1404     USHORT key_ver)
1405 {
1406     UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN];
1407     UCHAR c_mic[20];    /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */
1408
1409     /* copy the MIC from the EAPOL packet       */
1410     memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN);
1411
1412     /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
1413     memset(eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, 0, AIRPDCAP_WPA_MICKEY_LEN);
1414
1415     if (key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP) {
1416         /* use HMAC-MD5 for the EAPOL-Key MIC   */
1417         md5_hmac(eapol, eapol_len, KCK, AIRPDCAP_WPA_KCK_LEN, c_mic);
1418     } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) {
1419         /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
1420         sha1_hmac(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
1421     } else
1422         /* key descriptor version not recognized */
1423         return AIRPDCAP_RET_UNSUCCESS;
1424
1425     /* compare calculated MIC with the Key MIC and return result (0 means success) */
1426     return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN);
1427 }
1428
1429 static INT
1430 AirPDcapValidateKey(
1431     PAIRPDCAP_KEY_ITEM key)
1432 {
1433     size_t len;
1434     UCHAR ret=TRUE;
1435     AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1436
1437     if (key==NULL) {
1438         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "NULL key", AIRPDCAP_DEBUG_LEVEL_5);
1439         AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1440         return FALSE;
1441     }
1442
1443     switch (key->KeyType) {
1444         case AIRPDCAP_KEY_TYPE_WEP:
1445             /* check key size limits    */
1446             len=key->KeyData.Wep.WepKeyLen;
1447             if (len<AIRPDCAP_WEP_KEY_MINLEN || len>AIRPDCAP_WEP_KEY_MAXLEN) {
1448                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WEP key: key length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1449                 ret=FALSE;
1450             }
1451             break;
1452
1453         case AIRPDCAP_KEY_TYPE_WEP_40:
1454             /* set the standard length  and use a generic WEP key type  */
1455             key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_40_KEY_LEN;
1456             key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1457             break;
1458
1459         case AIRPDCAP_KEY_TYPE_WEP_104:
1460             /* set the standard length  and use a generic WEP key type  */
1461             key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_104_KEY_LEN;
1462             key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1463             break;
1464
1465         case AIRPDCAP_KEY_TYPE_WPA_PWD:
1466             /* check passphrase and SSID size limits    */
1467             len=strlen(key->UserPwd.Passphrase);
1468             if (len<AIRPDCAP_WPA_PASSPHRASE_MIN_LEN || len>AIRPDCAP_WPA_PASSPHRASE_MAX_LEN) {
1469                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: passphrase length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1470                 ret=FALSE;
1471             }
1472
1473             len=key->UserPwd.SsidLen;
1474             if (len>AIRPDCAP_WPA_SSID_MAX_LEN) {
1475                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: ssid length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1476                 ret=FALSE;
1477             }
1478
1479             break;
1480
1481         case AIRPDCAP_KEY_TYPE_WPA_PSK:
1482             break;
1483
1484         case AIRPDCAP_KEY_TYPE_WPA_PMK:
1485             break;
1486
1487         default:
1488             ret=FALSE;
1489     }
1490
1491     AIRPDCAP_DEBUG_TRACE_END("AirPDcapValidateKey");
1492     return ret;
1493 }
1494
1495 static INT
1496 AirPDcapGetSa(
1497     PAIRPDCAP_CONTEXT ctx,
1498     AIRPDCAP_SEC_ASSOCIATION_ID *id)
1499 {
1500     INT sa_index;
1501
1502     if (ctx->sa_index!=-1) {
1503         /* at least one association was stored                                                                                                          */
1504         /* search for the association from sa_index to 0 (most recent added)    */
1505         for (sa_index=ctx->sa_index; sa_index>=0; sa_index--) {
1506             if (ctx->sa[sa_index].used) {
1507                 if (memcmp(id, &(ctx->sa[sa_index].saId), sizeof(AIRPDCAP_SEC_ASSOCIATION_ID))==0) {
1508                     ctx->index=sa_index;
1509                     return sa_index;
1510                 }
1511             }
1512         }
1513     }
1514
1515     return -1;
1516 }
1517
1518 static INT
1519 AirPDcapStoreSa(
1520     PAIRPDCAP_CONTEXT ctx,
1521     AIRPDCAP_SEC_ASSOCIATION_ID *id)
1522 {
1523     INT last_free;
1524
1525     if (ctx->sa[ctx->first_free_index].used) {
1526         /* last addition was in the middle of the array (and the first_free_index was just incremented by 1)    */
1527         /* search for a free space from the first_free_index to AIRPDCAP_STA_INFOS_NR (to avoid free blocks in  */
1528         /*              the middle)                                                                                                                                                                                                                                     */
1529         for (last_free=ctx->first_free_index; last_free<AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; last_free++)
1530             if (!ctx->sa[last_free].used)
1531                 break;
1532
1533         if (last_free>=AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR) {
1534             /* there is no empty space available. FAILURE       */
1535             return -1;
1536         }
1537
1538         /* store first free space index */
1539         ctx->first_free_index=last_free;
1540     }
1541
1542     /* use this info    */
1543     ctx->index=ctx->first_free_index;
1544
1545     /* reset the info structure */
1546     memset(ctx->sa+ctx->index, 0, sizeof(AIRPDCAP_SEC_ASSOCIATION));
1547
1548     ctx->sa[ctx->index].used=1;
1549
1550     /* set the info structure   */
1551     memcpy(&(ctx->sa[ctx->index].saId), id, sizeof(AIRPDCAP_SEC_ASSOCIATION_ID));
1552
1553     /* increment by 1 the first_free_index (heuristic)  */
1554     ctx->first_free_index++;
1555
1556     /* set the sa_index if the added index is greater the the sa_index  */
1557     if (ctx->index > ctx->sa_index)
1558         ctx->sa_index=ctx->index;
1559
1560     return ctx->index;
1561 }
1562
1563 /*
1564  * AirPDcapGetBssidAddress() and AirPDcapGetBssidAddress() are used for
1565  * key caching.  In each case, it's more important to return a value than
1566  * to return a _correct_ value, so we fudge addresses in some cases, e.g.
1567  * the BSSID in bridged connections.
1568  * FromDS    ToDS    Sta    BSSID
1569  * 0         0       addr2  addr3
1570  * 0         1       addr2  addr1
1571  * 1         0       addr1  addr2
1572  * 1         1       addr2  addr1
1573  */
1574
1575 static const UCHAR *
1576 AirPDcapGetStaAddress(
1577     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1578 {
1579     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1580         case 0:
1581         case 1:
1582         case 3:
1583             return frame->addr2;
1584         case 2:
1585             return frame->addr1;
1586         default:
1587             return NULL;
1588     }
1589 }
1590
1591 static const UCHAR *
1592 AirPDcapGetBssidAddress(
1593     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1594 {
1595     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1596         case 0:
1597             return frame->addr3;
1598         case 1:
1599         case 3:
1600             return frame->addr1;
1601         case 2:
1602             return frame->addr2;
1603         default:
1604             return NULL;
1605     }
1606 }
1607
1608 /* Function used to derive the PTK. Refer to IEEE 802.11I-2004, pag. 74 */
1609 static void
1610 AirPDcapRsnaPrfX(
1611     AIRPDCAP_SEC_ASSOCIATION *sa,
1612     const UCHAR pmk[32],
1613     const UCHAR snonce[32],
1614     const INT x,        /*      for TKIP 512, for CCMP 384      */
1615     UCHAR *ptk)
1616 {
1617     UINT8 i;
1618     UCHAR R[100];
1619     INT offset=sizeof("Pairwise key expansion");
1620
1621     memset(R, 0, 100);
1622
1623     memcpy(R, "Pairwise key expansion", offset);
1624
1625     /*  Min(AA, SPA) || Max(AA, SPA)    */
1626     if (memcmp(sa->saId.sta, sa->saId.bssid, AIRPDCAP_MAC_LEN) < 0)
1627     {
1628         memcpy(R + offset, sa->saId.sta, AIRPDCAP_MAC_LEN);
1629         memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1630     }
1631     else
1632     {
1633         memcpy(R + offset, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1634         memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.sta, AIRPDCAP_MAC_LEN);
1635     }
1636
1637     offset+=AIRPDCAP_MAC_LEN*2;
1638
1639     /*  Min(ANonce,SNonce) || Max(ANonce,SNonce)        */
1640     if( memcmp(snonce, sa->wpa.nonce, 32) < 0 )
1641     {
1642         memcpy(R + offset, snonce, 32);
1643         memcpy(R + offset + 32, sa->wpa.nonce, 32);
1644     }
1645     else
1646     {
1647         memcpy(R + offset, sa->wpa.nonce, 32);
1648         memcpy(R + offset + 32, snonce, 32);
1649     }
1650
1651     offset+=32*2;
1652
1653     for(i = 0; i < (x+159)/160; i++)
1654     {
1655         R[offset] = i;
1656         sha1_hmac(pmk, 32, R, 100, ptk + i * 20);
1657     }
1658 }
1659
1660 static INT
1661 AirPDcapRsnaPwd2PskStep(
1662     const guint8 *ppBytes,
1663     const guint ppLength,
1664     const CHAR *ssid,
1665     const size_t ssidLength,
1666     const INT iterations,
1667     const INT count,
1668     UCHAR *output)
1669 {
1670     UCHAR digest[36], digest1[AIRPDCAP_SHA_DIGEST_LEN];
1671     INT i, j;
1672
1673     /* U1 = PRF(P, S || INT(i)) */
1674     memcpy(digest, ssid, ssidLength);
1675     digest[ssidLength] = (UCHAR)((count>>24) & 0xff);
1676     digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff);
1677     digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff);
1678     digest[ssidLength+3] = (UCHAR)(count & 0xff);
1679     sha1_hmac(ppBytes, ppLength, digest, ssidLength+4, digest1);
1680
1681     /* output = U1 */
1682     memcpy(output, digest1, AIRPDCAP_SHA_DIGEST_LEN);
1683     for (i = 1; i < iterations; i++) {
1684         /* Un = PRF(P, Un-1) */
1685         sha1_hmac(ppBytes, ppLength, digest1, AIRPDCAP_SHA_DIGEST_LEN, digest);
1686
1687         memcpy(digest1, digest, AIRPDCAP_SHA_DIGEST_LEN);
1688         /* output = output xor Un */
1689         for (j = 0; j < AIRPDCAP_SHA_DIGEST_LEN; j++) {
1690             output[j] ^= digest[j];
1691         }
1692     }
1693
1694     return AIRPDCAP_RET_SUCCESS;
1695 }
1696
1697 static INT
1698 AirPDcapRsnaPwd2Psk(
1699     const CHAR *passphrase,
1700     const CHAR *ssid,
1701     const size_t ssidLength,
1702     UCHAR *output)
1703 {
1704     UCHAR m_output[AIRPDCAP_WPA_PSK_LEN];
1705     GByteArray *pp_ba = g_byte_array_new();
1706
1707     memset(m_output, 0, AIRPDCAP_WPA_PSK_LEN);
1708
1709     if (!uri_str_to_bytes(passphrase, pp_ba)) {
1710         g_byte_array_free(pp_ba, TRUE);
1711         return 0;
1712     }
1713
1714     AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 1, m_output);
1715     AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[AIRPDCAP_SHA_DIGEST_LEN]);
1716
1717     memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN);
1718     g_byte_array_free(pp_ba, TRUE);
1719
1720     return 0;
1721 }
1722
1723 /*
1724  * Returns the decryption_key_t struct given a string describing the key.
1725  * Returns NULL if the key_string cannot be parsed.
1726  */
1727 decryption_key_t*
1728 parse_key_string(gchar* input_string)
1729 {
1730     gchar *type;
1731     gchar *key;
1732     gchar *ssid;
1733
1734     GString    *key_string = NULL;
1735     GByteArray *ssid_ba = NULL, *key_ba;
1736     gboolean    res;
1737
1738     gchar **tokens;
1739     guint n = 0;
1740     decryption_key_t *dk;
1741     gchar *first_nibble = input_string;
1742
1743     if(input_string == NULL)
1744         return NULL;
1745
1746     /*
1747      * Parse the input_string. It should be in the form
1748      * <key type>:<key data>[:<ssid>]
1749      * XXX - For backward compatibility, the a WEP key can be just a string
1750      * of hexadecimal characters (if WEP key is wrong, null will be
1751      * returned...).
1752      */
1753
1754     /* First, check for a WEP string */
1755     /* XXX - This duplicates code in packet-ieee80211.c */
1756     if (g_ascii_strncasecmp(input_string, STRING_KEY_TYPE_WEP ":", 4) == 0) {
1757         first_nibble += 4;
1758     }
1759
1760     key_ba = g_byte_array_new();
1761     res = hex_str_to_bytes(first_nibble, key_ba, FALSE);
1762
1763     if (res && key_ba->len > 0) {
1764         /* Key is correct! It was probably an 'old style' WEP key */
1765         /* Create the decryption_key_t structure, fill it and return it*/
1766         dk = g_malloc(sizeof(decryption_key_t));
1767
1768         dk->type = AIRPDCAP_KEY_TYPE_WEP;
1769         /* XXX - The current key handling code in the GUI requires
1770          * no separators and lower case */
1771         dk->key  = g_string_new(bytes_to_str(key_ba->data, key_ba->len));
1772         g_string_down(dk->key);
1773         dk->bits = key_ba->len * 8;
1774         dk->ssid = NULL;
1775
1776         g_byte_array_free(key_ba, TRUE);
1777         return dk;
1778     }
1779     g_byte_array_free(key_ba, TRUE);
1780
1781
1782     tokens = g_strsplit(input_string,":",0);
1783
1784     /* Tokens is a null termiated array of strings ... */
1785     while(tokens[n] != NULL)
1786         n++;
1787
1788     if(n < 2)
1789     {
1790         /* Free the array of strings */
1791         g_strfreev(tokens);
1792         return NULL;
1793     }
1794
1795     type = g_strdup(tokens[0]);
1796
1797     /*
1798      * The second token is the key (right now it doesn't matter
1799      * if it is a passphrase[+ssid] or an hexadecimal one)
1800      */
1801     key = g_strdup(tokens[1]);
1802
1803     ssid = NULL;
1804     /* Maybe there is a third token (an ssid, if everything else is ok) */
1805     if(n >= 3)
1806     {
1807         ssid = g_strdup(tokens[2]);
1808     }
1809
1810     if (g_ascii_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
1811     {
1812         /* Create a new string */
1813         key_string = g_string_new(key);
1814
1815         key_ba = g_byte_array_new();
1816         res = hex_str_to_bytes(key, key_ba, FALSE);
1817
1818         /* Two tokens means that the user should have entered a WPA-BIN key ... */
1819         if(!res || ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
1820         {
1821             g_string_free(key_string, TRUE);
1822             g_byte_array_free(key_ba, TRUE);
1823
1824             g_free(type);
1825             g_free(key);
1826             /* No ssid has been created ... */
1827             /* Free the array of strings */
1828             g_strfreev(tokens);
1829             return NULL;
1830         }
1831
1832         /* Key was correct!!! Create the new decryption_key_t ... */
1833         dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1834
1835         dk->type = AIRPDCAP_KEY_TYPE_WPA_PMK;
1836         dk->key  = g_string_new(key);
1837         dk->bits = dk->key->len * 4;
1838         dk->ssid = NULL;
1839
1840         g_string_free(key_string, TRUE);
1841         g_byte_array_free(key_ba, TRUE);
1842         g_free(key);
1843         g_free(type);
1844
1845         /* Free the array of strings */
1846         g_strfreev(tokens);
1847         return dk;
1848     }
1849     else if(g_ascii_strcasecmp(type,STRING_KEY_TYPE_WPA_PWD) == 0) /* WPA key *//* If the number of tokens is more than three, we accept the string... if the first three tokens are correct... */
1850     {
1851         /* Create a new string */
1852         key_string = g_string_new(key);
1853         ssid_ba = NULL;
1854
1855         /* Three (or more) tokens mean that the user entered a WPA-PWD key ... */
1856         if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
1857         {
1858             g_string_free(key_string, TRUE);
1859
1860             g_free(type);
1861             g_free(key);
1862             g_free(ssid);
1863
1864             /* Free the array of strings */
1865             g_strfreev(tokens);
1866             return NULL;
1867         }
1868
1869         if(ssid != NULL) /* more than three tokens found, means that the user specified the ssid */
1870         {
1871             ssid_ba = g_byte_array_new();
1872             if (! uri_str_to_bytes(ssid, ssid_ba)) {
1873                 g_string_free(key_string, TRUE);
1874                 g_byte_array_free(ssid_ba, TRUE);
1875                 g_free(type);
1876                 g_free(key);
1877                 g_free(ssid);
1878                 /* Free the array of strings */
1879                 g_strfreev(tokens);
1880                 return NULL;
1881             }
1882
1883             if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
1884             {
1885                 g_string_free(key_string, TRUE);
1886                 g_byte_array_free(ssid_ba, TRUE);
1887
1888                 g_free(type);
1889                 g_free(key);
1890                 g_free(ssid);
1891
1892                 /* Free the array of strings */
1893                 g_strfreev(tokens);
1894                 return NULL;
1895             }
1896         }
1897
1898         /* Key was correct!!! Create the new decryption_key_t ... */
1899         dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1900
1901         dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
1902         dk->key  = g_string_new(key);
1903         dk->bits = 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
1904         dk->ssid = byte_array_dup(ssid_ba); /* NULL if ssid_ba is NULL */
1905
1906         g_string_free(key_string, TRUE);
1907         if (ssid_ba != NULL)
1908             g_byte_array_free(ssid_ba, TRUE);
1909
1910         g_free(type);
1911         g_free(key);
1912         if(ssid != NULL)
1913             g_free(ssid);
1914
1915         /* Free the array of strings */
1916         g_strfreev(tokens);
1917         return dk;
1918     }
1919
1920     /* Something was wrong ... free everything */
1921
1922     g_free(type);
1923     g_free(key);
1924     if(ssid != NULL)
1925         g_free(ssid); /* It is not always present */
1926     if (ssid_ba != NULL)
1927         g_byte_array_free(ssid_ba, TRUE);
1928
1929     /* Free the array of strings */
1930     g_strfreev(tokens);
1931
1932     return NULL;
1933 }
1934
1935 /*
1936  * Returns a newly allocated string representing the given decryption_key_t
1937  * struct, or NULL if something is wrong...
1938  */
1939 gchar*
1940 get_key_string(decryption_key_t* dk)
1941 {
1942     gchar* output_string = NULL;
1943
1944     if(dk == NULL || dk->key == NULL)
1945         return NULL;
1946
1947     switch(dk->type) {
1948         case AIRPDCAP_KEY_TYPE_WEP:
1949             output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WEP,dk->key->str);
1950             break;
1951         case AIRPDCAP_KEY_TYPE_WPA_PWD:
1952             if(dk->ssid == NULL)
1953                 output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PWD,dk->key->str);
1954             else
1955                 output_string = g_strdup_printf("%s:%s:%s",
1956                     STRING_KEY_TYPE_WPA_PWD, dk->key->str,
1957                     format_uri(dk->ssid, ":"));
1958             break;
1959         case AIRPDCAP_KEY_TYPE_WPA_PMK:
1960             output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PSK,dk->key->str);
1961             break;
1962         default:
1963             return NULL;
1964     }
1965
1966     return output_string;
1967 }
1968
1969 #ifdef  __cplusplus
1970 }
1971 #endif
1972
1973 /****************************************************************************/
1974
1975 /*
1976  * Editor modelines
1977  *
1978  * Local Variables:
1979  * c-basic-offset: 4
1980  * tab-width: 8
1981  * indent-tabs-mode: nil
1982  * End:
1983  *
1984  * ex: set shiftwidth=4 tabstop=8 expandtab
1985  * :indentSize=4:tabSize=8:noTabs=true:
1986  */