Add another buffer length check to group key decryption.
[obnox/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;
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                 memcpy(&key_len, pEAPKey->key_length, 2);  /* get the key length as a UINT16 */
353         }else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
354                 /* AES */
355                 memcpy(&key_len, pEAPKey->key_data_len, 2);  /* get the key length as a UINT16 */
356         }
357         key_len = ntohs(key_len); /* Convert to proper endianess */
358     if (key_len > sizeof(RSN_IE)) { /* Don't read past the end of pEAPKey->ie */
359         return;
360     }
361
362         /* Encrypted key is in the information element field of the EAPOL key packet */
363         szEncryptedKey = g_memdup(pEAPKey->ie, key_len);
364
365         DEBUG_DUMP("Encrypted Broadcast key:", szEncryptedKey, key_len);
366         DEBUG_DUMP("KeyIV:", pEAPKey->key_iv, 16);
367         DEBUG_DUMP("decryption_key:", decryption_key, 16);
368
369         /* Build the full decryption key based on the IV and part of the pairwise key */
370         memcpy(new_key, pEAPKey->key_iv, 16);
371         memcpy(new_key+16, decryption_key, 16);
372         DEBUG_DUMP("FullDecrKey:", new_key, 32);
373
374         if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
375                 guint8 dummy[256];
376                 /* TKIP key */
377                 /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
378                 /* group key is decrypted using RC4.  Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
379
380                 rc4_state_struct rc4_state;
381                 crypt_rc4_init(&rc4_state, new_key, sizeof(new_key));
382
383                 /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
384                 crypt_rc4(&rc4_state, dummy, 256);
385                 crypt_rc4(&rc4_state, szEncryptedKey, key_len);
386
387         } else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
388                 /* AES CCMP key */
389
390                 guint8 key_found;
391                 guint16 key_index;
392                 guint8 *decrypted_data;
393
394                 /* This storage is needed for the AES_unwrap function */
395                 decrypted_data = (guint8 *) g_malloc(key_len);
396
397                 AES_unwrap(decryption_key, 16, szEncryptedKey,  key_len, decrypted_data);
398
399                 /* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure.
400                    The key itself is stored as a GTK KDE
401                    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
402                    pass pointer to the actual key with 8 bytes offset */
403
404                 key_found = FALSE;
405                 key_index = 0;
406                 while(key_index < key_len && !key_found){
407                         guint8 rsn_id;
408
409                         /* Get RSN ID */
410                         rsn_id = decrypted_data[key_index];
411
412                         if (rsn_id != 0xdd){
413                                 key_index += decrypted_data[key_index+1]+2;
414                         }else{
415                                 key_found = TRUE;
416                         }
417                 }
418
419                 if (key_found){
420                         /* Skip over the GTK header info, and don't copy past the end of the encrypted data */
421                         memcpy(szEncryptedKey, decrypted_data+key_index+8, key_len-key_index-8);
422                 }
423
424                 g_free(decrypted_data);
425         }
426
427         /* Decrypted key is now in szEncryptedKey with len of key_len */
428         DEBUG_DUMP("Broadcast key:", szEncryptedKey, key_len);
429
430         /* Load the proper key material info into the SA */
431         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 */
432         sa->validKey = TRUE;
433         sa->wpa.key_ver = key_version;
434
435         /* 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  */
436         /* AirPDcapRsnaMng() function will extract the right piece of the GTK for decryption. (The first 16 bytes of the GTK are used for decryption.) */
437         memset(sa->wpa.ptk, 0, sizeof(sa->wpa.ptk));
438         memcpy(sa->wpa.ptk+32, szEncryptedKey, key_len);
439         g_free(szEncryptedKey);
440 }
441
442
443 /* Return a pointer the the requested SA. If it doesn't exist create it. */
444 PAIRPDCAP_SEC_ASSOCIATION
445 AirPDcapGetSaPtr(
446         PAIRPDCAP_CONTEXT ctx,
447     AIRPDCAP_SEC_ASSOCIATION_ID *id)
448 {
449     int sa_index;
450
451         /* search for a cached Security Association for supplied BSSID and STA MAC      */
452         if ((sa_index=AirPDcapGetSa(ctx, id))==-1) {
453                 /* create a new Security Association if it doesn't currently exist      */
454                 if ((sa_index=AirPDcapStoreSa(ctx, id))==-1) {
455                         return NULL;
456                 }
457         }
458         /* get the Security Association structure       */
459         return &ctx->sa[sa_index];
460 }
461
462 #define GROUP_KEY_PAYLOAD_LEN (8+4+sizeof(EAPOL_RSN_KEY))
463 INT AirPDcapScanForGroupKey(
464     PAIRPDCAP_CONTEXT ctx,
465     const guint8 *data,
466     const guint mac_header_len,
467     const guint tot_len
468 )
469 {
470     const UCHAR *address;
471     AIRPDCAP_SEC_ASSOCIATION_ID id;
472     guint bodyLength;
473     PAIRPDCAP_SEC_ASSOCIATION sta_sa;
474     PAIRPDCAP_SEC_ASSOCIATION sa;
475     int offset = 0;
476     const guint8 dot1x_header[] = {
477         0xAA,             /* DSAP=SNAP */
478         0xAA,             /* SSAP=SNAP */
479         0x03,             /* Control field=Unnumbered frame */
480         0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
481         0x88, 0x8E        /* Type: 802.1X authentication */
482     };
483
484         P_EAPOL_RSN_KEY pEAPKey;
485 #ifdef _DEBUG
486     CHAR msgbuf[255];
487 #endif
488
489         AIRPDCAP_DEBUG_TRACE_START("AirPDcapScanForGroupKey");
490
491         if (mac_header_len + GROUP_KEY_PAYLOAD_LEN < tot_len) {
492             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Message too short", AIRPDCAP_DEBUG_LEVEL_3);
493             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
494         }
495
496         /* cache offset in the packet data */
497         offset = mac_header_len;
498
499     /* check if the packet has an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
500     if (memcmp(data+offset, dot1x_header, 8) == 0) {
501
502                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
503
504         /* skip LLC header      */
505         offset+=8;
506
507
508        /*       check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25)    */
509         if (data[offset+1]!=3) {
510             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_3);
511             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
512         }
513
514         /* get and check the body length (IEEE 802.1X-2004, pg. 25)     */
515         bodyLength=pntohs(data+offset+2);
516         if ((tot_len-offset-4) < bodyLength) {
517             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_3);
518             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
519         }
520
521         /* skip EAPOL MPDU and go to the first byte of the body */
522         offset+=4;
523
524                 pEAPKey = (P_EAPOL_RSN_KEY) (data+offset);
525
526         /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
527         if (/*pEAPKey->type!=0x1 &&*/   /* RC4 Key Descriptor Type (deprecated) */
528             pEAPKey->type != AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR &&                /* IEEE 802.11 Key Descriptor Type       (WPA2)         */
529             pEAPKey->type != AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR)           /* 254 = RSN_KEY_DESCRIPTOR - WPA,                                      */
530         {
531             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_3);
532             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
533         }
534
535         /* start with descriptor body   */
536         offset+=1;
537
538                 /* Verify the bitfields: Key = 0(groupwise) Mic = 1 Ack = 1 Secure = 1 */
539                 if (AIRPDCAP_EAP_KEY(data[offset+1])!=0 ||
540                         AIRPDCAP_EAP_ACK(data[offset+1])!=1 ||
541                         AIRPDCAP_EAP_MIC(data[offset]) != 1 ||
542                         AIRPDCAP_EAP_SEC(data[offset]) != 1){
543
544             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Key bitfields not correct", AIRPDCAP_DEBUG_LEVEL_3);
545             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
546                 }
547
548                 /* get BSSID */
549                 if ( (address=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
550                         memcpy(id.bssid, address, AIRPDCAP_MAC_LEN);
551 #ifdef _DEBUG
552                         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]);
553 #endif
554                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
555                 } else {
556                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
557                         return AIRPDCAP_RET_REQ_DATA;
558                 }
559
560                 /* force STA address to be the broadcast MAC so we create an SA for the groupkey        */
561                 memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
562
563                 /* get the Security Association structure for the broadcast MAC and AP */
564                 sa = AirPDcapGetSaPtr(ctx, &id);
565                 if (sa == NULL){
566                         return AIRPDCAP_RET_UNSUCCESS;
567                 }
568
569                 /* Get the SA for the STA, since we need its pairwise key to decrpyt the group key */
570
571                 /* get STA address      */
572                 if ( (address=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
573                         memcpy(id.sta, address, AIRPDCAP_MAC_LEN);
574 #ifdef _DEBUG
575                         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]);
576 #endif
577                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
578                 } else {
579                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
580                         return AIRPDCAP_RET_REQ_DATA;
581                 }
582
583                 sta_sa = AirPDcapGetSaPtr(ctx, &id);
584                 if (sta_sa == NULL){
585                         return AIRPDCAP_RET_UNSUCCESS;
586                 }
587
588                 /* Extract the group key and install it in the SA */
589                 AirPDcapDecryptWPABroadcastKey(pEAPKey, sta_sa->wpa.ptk+16, sa);
590
591         }else{
592                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Skipping: not an EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
593         }
594
595         AIRPDCAP_DEBUG_TRACE_END("AirPDcapScanForGroupKey");
596         return 0;
597 }
598
599
600 INT AirPDcapPacketProcess(
601     PAIRPDCAP_CONTEXT ctx,
602     const guint8 *data,
603     const guint mac_header_len,
604     const guint tot_len,
605     UCHAR *decrypt_data,
606     guint *decrypt_len,
607     PAIRPDCAP_KEY_ITEM key,
608     gboolean mngHandshake,
609     gboolean mngDecrypt)
610 {
611     const UCHAR *address;
612     AIRPDCAP_SEC_ASSOCIATION_ID id;
613     PAIRPDCAP_SEC_ASSOCIATION sa;
614     int offset = 0;
615     guint bodyLength;
616     const guint8 dot1x_header[] = {
617         0xAA,             /* DSAP=SNAP */
618         0xAA,             /* SSAP=SNAP */
619         0x03,             /* Control field=Unnumbered frame */
620         0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
621         0x88, 0x8E        /* Type: 802.1X authentication */
622     };
623
624 #ifdef _DEBUG
625     CHAR msgbuf[255];
626 #endif
627
628     AIRPDCAP_DEBUG_TRACE_START("AirPDcapPacketProcess");
629
630     if (ctx==NULL) {
631         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
632         AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
633         return AIRPDCAP_RET_UNSUCCESS;
634     }
635     if (data==NULL || tot_len==0) {
636         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5);
637         AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
638         return AIRPDCAP_RET_UNSUCCESS;
639     }
640
641     /* check if the packet is of data type      */
642     if (AIRPDCAP_TYPE(data[0])!=AIRPDCAP_TYPE_DATA) {
643         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
644         return AIRPDCAP_RET_NO_DATA;
645     }
646
647     /* check correct packet size, to avoid wrong elaboration of encryption algorithms   */
648     if (tot_len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) {
649         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5);
650         return AIRPDCAP_RET_WRONG_DATA_SIZE;
651     }
652
653     /* get BSSID */
654     if ( (address=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
655         memcpy(id.bssid, address, AIRPDCAP_MAC_LEN);
656 #ifdef _DEBUG
657         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]);
658 #endif
659         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
660     } else {
661         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
662         return AIRPDCAP_RET_REQ_DATA;
663     }
664
665     /* get STA address  */
666     if ( (address=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
667         memcpy(id.sta, address, AIRPDCAP_MAC_LEN);
668 #ifdef _DEBUG
669         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]);
670 #endif
671         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
672     } else {
673         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
674         return AIRPDCAP_RET_REQ_DATA;
675     }
676
677         /* get the Security Association structure for the STA and AP */
678         sa = AirPDcapGetSaPtr(ctx, &id);
679         if (sa == NULL){
680                 return AIRPDCAP_RET_UNSUCCESS;
681         }
682
683     /* cache offset in the packet data (to scan encryption data)        */
684     offset = mac_header_len;
685
686     /*  check if data is encrypted (use the WEP bit in the Frame Control field) */
687     if (AIRPDCAP_WEP(data[1])==0)
688     {
689         if (mngHandshake) {
690             /* data is sent in cleartext, check if is an authentication message or end the process      */
691             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Unencrypted data", AIRPDCAP_DEBUG_LEVEL_3);
692
693             /* check if the packet as an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24)  */
694             if (memcmp(data+offset, dot1x_header, 8) == 0) {
695                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
696
697                 /* skip LLC header      */
698                 offset+=8;
699
700                 /* check the version of the EAPOL protocol used (IEEE 802.1X-2004, pg. 24)      */
701                 /* TODO EAPOL protocol version to check?        */
702                 /*if (data[offset]!=2) {
703                     AIRPDCAP_DEBUG_PRINT_LINE("EAPOL protocol version not recognized", AIRPDCAP_DEBUG_LEVEL_5);
704                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
705                 }*/
706
707                 /*      check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25)    */
708                 if (data[offset+1]!=3) {
709                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_5);
710                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
711                 }
712
713                 /* get and check the body length (IEEE 802.1X-2004, pg. 25)     */
714                 bodyLength=pntohs(data+offset+2);
715                 if ((tot_len-offset-4) < bodyLength) {
716                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_5);
717                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
718                 }
719
720                 /* skip EAPOL MPDU and go to the first byte of the body */
721                 offset+=4;
722
723                 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
724                 if (/*data[offset]!=0x1 &&*/    /* RC4 Key Descriptor Type (deprecated) */
725                     data[offset]!=0x2 &&                /* IEEE 802.11 Key Descriptor Type                      */
726                     data[offset]!=0xFE)         /* TODO what's this value???                                    */
727                 {
728                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_5);
729                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
730                 }
731
732                 /* start with descriptor body   */
733                 offset+=1;
734
735                 /* manage the 4-way handshake to define the key */
736                 return AirPDcapRsna4WHandshake(ctx, data, sa, key, offset);
737             } else {
738                 /* cleartext message, not authentication */
739                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "No authentication data", AIRPDCAP_DEBUG_LEVEL_5);
740                 return AIRPDCAP_RET_NO_DATA_ENCRYPTED;
741             }
742         }
743     } else {
744         if (mngDecrypt) {
745
746             if (decrypt_data==NULL)
747                 return AIRPDCAP_RET_UNSUCCESS;
748
749             /*  create new header and data to modify    */
750             *decrypt_len = tot_len;
751             memcpy(decrypt_data, data, *decrypt_len);
752
753             /* encrypted data   */
754             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3);
755
756             /* check the Extension IV to distinguish between WEP encryption and WPA encryption  */
757             /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP,     */
758             /*          IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP,           */
759             /*          IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP                    */
760             if (AIRPDCAP_EXTIV(data[offset+3])==0) {
761                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3);
762                 return AirPDcapWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
763             } else {
764                                 INT status;
765                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3);
766
767                                 /* If index >= 1, then use the group key.  This will not work if the AP is using
768                                    more than one group key simultaneously.  I've not seen this in practice, however. Usually an AP
769                                    will rotate between the two key index values of 1 and 2 whenever it needs to change the group key to be used. */
770                                 if (AIRPDCAP_KEY_INDEX(data[offset+3])>=1){
771
772                                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "The key index = 1. This is encrypted with a group key.", AIRPDCAP_DEBUG_LEVEL_3);
773
774                                         /* force STA address to broadcast MAC so we load the SA for the groupkey        */
775                                         memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
776
777 #ifdef _DEBUG
778                                         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]);
779                                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
780 #endif
781
782                                         /* search for a cached Security Association for current BSSID and broadcast MAC */
783                                         sa = AirPDcapGetSaPtr(ctx, &id);
784                                         if (sa == NULL){
785                                                 return AIRPDCAP_RET_UNSUCCESS;
786                                         }
787                                 }
788
789                                 /* Decrypt the packet using the appropriate SA */
790                 status = AirPDcapRsnaMng(decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
791
792                                  /* If we successfully decrypted a packet, scan it to see if it contains a group key handshake.
793                                    The group key handshake could be sent at any time the AP wants to change the key (such as when
794                                    it is using key rotation) so we must scan every packet. */
795                                 if (status == AIRPDCAP_RET_SUCCESS)
796                                         AirPDcapScanForGroupKey(ctx, decrypt_data, mac_header_len, *decrypt_len);
797                                 return status;
798             }
799         }
800     }
801
802     return AIRPDCAP_RET_UNSUCCESS;
803 }
804
805 INT AirPDcapSetKeys(
806     PAIRPDCAP_CONTEXT ctx,
807     AIRPDCAP_KEY_ITEM keys[],
808     const size_t keys_nr)
809 {
810     INT i;
811     INT success;
812     AIRPDCAP_DEBUG_TRACE_START("AirPDcapSetKeys");
813
814     if (ctx==NULL || keys==NULL) {
815         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "NULL context or NULL keys array", AIRPDCAP_DEBUG_LEVEL_3);
816         AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
817         return 0;
818     }
819
820     if (keys_nr>AIRPDCAP_MAX_KEYS_NR) {
821         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Keys number greater than maximum", AIRPDCAP_DEBUG_LEVEL_3);
822         AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
823         return 0;
824     }
825
826     /* clean key and SA collections before setting new ones     */
827     AirPDcapInitContext(ctx);
828
829     /* check and insert keys    */
830     for (i=0, success=0; i<(INT)keys_nr; i++) {
831         if (AirPDcapValidateKey(keys+i)==TRUE) {
832             if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD) {
833                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PWD key", AIRPDCAP_DEBUG_LEVEL_4);
834                 AirPDcapRsnaPwd2Psk(keys[i].UserPwd.Passphrase, keys[i].UserPwd.Ssid, keys[i].UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
835             }
836 #ifdef  _DEBUG
837             else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
838                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PMK key", AIRPDCAP_DEBUG_LEVEL_4);
839             } else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WEP) {
840                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WEP key", AIRPDCAP_DEBUG_LEVEL_4);
841             } else {
842                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a key", AIRPDCAP_DEBUG_LEVEL_4);
843             }
844 #endif
845             memcpy(&ctx->keys[success], &keys[i], sizeof(keys[i]));
846             success++;
847         }
848     }
849
850     ctx->keys_nr=success;
851
852     AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
853     return success;
854 }
855
856 static void
857 AirPDcapCleanKeys(
858     PAIRPDCAP_CONTEXT ctx)
859 {
860     AIRPDCAP_DEBUG_TRACE_START("AirPDcapCleanKeys");
861
862     if (ctx==NULL) {
863         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
864         AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
865         return;
866     }
867
868     memset(ctx->keys, 0, sizeof(AIRPDCAP_KEY_ITEM) * AIRPDCAP_MAX_KEYS_NR);
869
870     ctx->keys_nr=0;
871
872     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "Keys collection cleaned!", AIRPDCAP_DEBUG_LEVEL_5);
873     AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
874 }
875
876 INT AirPDcapGetKeys(
877     const PAIRPDCAP_CONTEXT ctx,
878     AIRPDCAP_KEY_ITEM keys[],
879     const size_t keys_nr)
880 {
881     UINT i;
882     UINT j;
883     AIRPDCAP_DEBUG_TRACE_START("AirPDcapGetKeys");
884
885     if (ctx==NULL) {
886         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
887         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
888         return 0;
889     } else if (keys==NULL) {
890         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL keys array", AIRPDCAP_DEBUG_LEVEL_5);
891         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
892         return (INT)ctx->keys_nr;
893     } else {
894         for (i=0, j=0; i<ctx->keys_nr && i<keys_nr && i<AIRPDCAP_MAX_KEYS_NR; i++) {
895             memcpy(&keys[j], &ctx->keys[i], sizeof(keys[j]));
896             j++;
897             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "Got a key", AIRPDCAP_DEBUG_LEVEL_5);
898         }
899
900         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
901         return j;
902     }
903 }
904
905 /*
906  * XXX - This won't be reliable if a packet containing SSID "B" shows
907  * up in the middle of a 4-way handshake for SSID "A".
908  * We should probably use a small array or hash table to keep multiple
909  * SSIDs.
910  */
911 INT AirPDcapSetLastSSID(
912     PAIRPDCAP_CONTEXT ctx,
913     CHAR *pkt_ssid,
914     size_t pkt_ssid_len)
915 {
916     if (!ctx || !pkt_ssid || pkt_ssid_len < 1 || pkt_ssid_len > WPA_SSID_MAX_SIZE)
917         return AIRPDCAP_RET_UNSUCCESS;
918
919     memcpy(ctx->pkt_ssid, pkt_ssid, pkt_ssid_len);
920     ctx->pkt_ssid_len = pkt_ssid_len;
921
922     return AIRPDCAP_RET_SUCCESS;
923 }
924
925 INT AirPDcapInitContext(
926     PAIRPDCAP_CONTEXT ctx)
927 {
928     AIRPDCAP_DEBUG_TRACE_START("AirPDcapInitContext");
929
930     if (ctx==NULL) {
931         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
932         AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
933         return AIRPDCAP_RET_UNSUCCESS;
934     }
935
936     AirPDcapCleanKeys(ctx);
937
938     ctx->first_free_index=0;
939     ctx->index=-1;
940     ctx->sa_index=-1;
941     ctx->pkt_ssid_len = 0;
942
943     memset(ctx->sa, 0, AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR * sizeof(AIRPDCAP_SEC_ASSOCIATION));
944
945     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "Context initialized!", AIRPDCAP_DEBUG_LEVEL_5);
946     AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
947     return AIRPDCAP_RET_SUCCESS;
948 }
949
950 INT AirPDcapDestroyContext(
951     PAIRPDCAP_CONTEXT ctx)
952 {
953     AIRPDCAP_DEBUG_TRACE_START("AirPDcapDestroyContext");
954
955     if (ctx==NULL) {
956         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
957         AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
958         return AIRPDCAP_RET_UNSUCCESS;
959     }
960
961     AirPDcapCleanKeys(ctx);
962
963     ctx->first_free_index=0;
964     ctx->index=-1;
965     ctx->sa_index=-1;
966
967     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "Context destroyed!", AIRPDCAP_DEBUG_LEVEL_5);
968     AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
969     return AIRPDCAP_RET_SUCCESS;
970 }
971
972 #ifdef  __cplusplus
973 }
974 #endif
975
976 /****************************************************************************/
977
978 /****************************************************************************/
979 /* Internal function definitions                                                */
980
981 #ifdef  __cplusplus
982 extern "C" {
983 #endif
984
985 static INT
986 AirPDcapRsnaMng(
987     UCHAR *decrypt_data,
988     guint mac_header_len,
989     guint *decrypt_len,
990     PAIRPDCAP_KEY_ITEM key,
991     AIRPDCAP_SEC_ASSOCIATION *sa,
992     INT offset)
993 {
994     INT ret_value;
995
996     if (sa->key==NULL) {
997         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3);
998         return AIRPDCAP_RET_REQ_DATA;
999     }
1000     if (sa->validKey==FALSE) {
1001         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Key not yet valid", AIRPDCAP_DEBUG_LEVEL_3);
1002         return AIRPDCAP_RET_UNSUCCESS;
1003     }
1004     if (sa->wpa.key_ver==1) {
1005         /*      CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm        */
1006         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP", AIRPDCAP_DEBUG_LEVEL_3);
1007
1008                 DEBUG_DUMP("ptk", sa->wpa.ptk, 64);
1009                 DEBUG_DUMP("ptk portion used", AIRPDCAP_GET_TK(sa->wpa.ptk), 16);
1010
1011         ret_value=AirPDcapTkipDecrypt(decrypt_data+offset, *decrypt_len-offset, decrypt_data+AIRPDCAP_TA_OFFSET, AIRPDCAP_GET_TK(sa->wpa.ptk));
1012                 if (ret_value){
1013                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP failed!", AIRPDCAP_DEBUG_LEVEL_3);
1014             return ret_value;
1015                 }
1016
1017         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1018         /* remove MIC (8bytes) and ICV (4bytes) from the end of packet  */
1019         *decrypt_len-=12;
1020     } else {
1021         /*      AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm  */
1022         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3);
1023
1024         ret_value=AirPDcapCcmpDecrypt(decrypt_data, mac_header_len, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk));
1025         if (ret_value)
1026             return ret_value;
1027
1028         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1029         /* remove MIC (8bytes) from the end of packet   */
1030         *decrypt_len-=8;
1031     }
1032
1033     /* remove protection bit    */
1034     decrypt_data[1]&=0xBF;
1035
1036     /* remove TKIP/CCMP header  */
1037     offset = mac_header_len;
1038     *decrypt_len-=8;
1039     memcpy(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset);
1040
1041     if (key!=NULL) {
1042         memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1043
1044         if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1045             key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1046         else if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1047             key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1048     }
1049
1050     return AIRPDCAP_RET_SUCCESS;
1051 }
1052
1053 static INT
1054 AirPDcapWepMng(
1055     PAIRPDCAP_CONTEXT ctx,
1056     UCHAR *decrypt_data,
1057     guint mac_header_len,
1058     guint *decrypt_len,
1059     PAIRPDCAP_KEY_ITEM key,
1060     AIRPDCAP_SEC_ASSOCIATION *sa,
1061     INT offset)
1062 {
1063     UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN];
1064     size_t keylen;
1065     INT ret_value=1;
1066     INT key_index;
1067     AIRPDCAP_KEY_ITEM *tmp_key;
1068     UINT8 useCache=FALSE;
1069     UCHAR *try_data = ep_alloc(*decrypt_len);
1070
1071     if (sa->key!=NULL)
1072         useCache=TRUE;
1073
1074     for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
1075         /* use the cached one, or try all keys  */
1076         if (!useCache) {
1077             tmp_key=&ctx->keys[key_index];
1078         } else {
1079             if (sa->key!=NULL && sa->key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1080                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try cached WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1081                 tmp_key=sa->key;
1082             } else {
1083                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Cached key is not valid, try another WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1084                 tmp_key=&ctx->keys[key_index];
1085             }
1086         }
1087
1088         /* obviously, try only WEP keys...      */
1089         if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP)
1090         {
1091             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1092
1093             memset(wep_key, 0, sizeof(wep_key));
1094             memcpy(try_data, decrypt_data, *decrypt_len);
1095
1096             /* 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)     */
1097             memcpy(wep_key, try_data+mac_header_len, AIRPDCAP_WEP_IVLEN);
1098             keylen=tmp_key->KeyData.Wep.WepKeyLen;
1099             memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
1100
1101             ret_value=AirPDcapWepDecrypt(wep_key,
1102                 keylen+AIRPDCAP_WEP_IVLEN,
1103                 try_data + (mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN),
1104                 *decrypt_len-(mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN));
1105
1106             if (ret_value == AIRPDCAP_RET_SUCCESS)
1107                 memcpy(decrypt_data, try_data, *decrypt_len);
1108         }
1109
1110         if (!ret_value && tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1111             /* the tried key is the correct one, cached in the Security Association     */
1112
1113             sa->key=tmp_key;
1114
1115             if (key!=NULL) {
1116                 memcpy(key, &sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1117                 key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1118             }
1119
1120             break;
1121         } else {
1122             /* the cached key was not valid, try other keys     */
1123
1124             if (useCache==TRUE) {
1125                 useCache=FALSE;
1126                 key_index--;
1127             }
1128         }
1129     }
1130
1131     if (ret_value)
1132         return ret_value;
1133
1134     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "WEP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1135
1136     /* remove ICV (4bytes) from the end of packet       */
1137     *decrypt_len-=4;
1138
1139     /* remove protection bit    */
1140     decrypt_data[1]&=0xBF;
1141
1142     /* remove IC header */
1143     offset = mac_header_len;
1144     *decrypt_len-=4;
1145     memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset);
1146
1147     return AIRPDCAP_RET_SUCCESS;
1148 }
1149
1150 /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85   */
1151 static INT
1152 AirPDcapRsna4WHandshake(
1153     PAIRPDCAP_CONTEXT ctx,
1154     const UCHAR *data,
1155     AIRPDCAP_SEC_ASSOCIATION *sa,
1156     PAIRPDCAP_KEY_ITEM key,
1157     INT offset)
1158 {
1159     AIRPDCAP_KEY_ITEM *tmp_key, pkt_key;
1160     INT key_index;
1161     INT ret_value=1;
1162     UCHAR useCache=FALSE;
1163     UCHAR eapol[AIRPDCAP_EAPOL_MAX_LEN];
1164     USHORT eapol_len;
1165
1166     if (sa->key!=NULL)
1167         useCache=TRUE;
1168
1169     /* a 4-way handshake packet use a Pairwise key type (IEEE 802.11i-2004, pg. 79)     */
1170     if (AIRPDCAP_EAP_KEY(data[offset+1])!=1) {
1171         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Group/STAKey message (not used)", AIRPDCAP_DEBUG_LEVEL_5);
1172         return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1173     }
1174
1175     /* TODO timeouts? reauthentication? */
1176
1177     /* TODO consider key-index  */
1178
1179     /* TODO considera Deauthentications */
1180
1181     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake...", AIRPDCAP_DEBUG_LEVEL_5);
1182
1183     /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85)       */
1184
1185     /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0)       */
1186     if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1187         AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1188         AIRPDCAP_EAP_MIC(data[offset])==0)
1189     {
1190         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 1", AIRPDCAP_DEBUG_LEVEL_3);
1191
1192         /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been                     */
1193         /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current       */
1194         /* local value, the Supplicant discards the message.                                                                                                                                                                    */
1195         /* -> not checked, the Authenticator will be send another Message 1 (hopefully!)                                                                                                */
1196
1197         /* save ANonce (from authenticator)     to derive the PTK with the SNonce (from the 2 message)  */
1198         memcpy(sa->wpa.nonce, data+offset+12, 32);
1199
1200         /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-)       */
1201         sa->wpa.key_ver=AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]);
1202
1203         sa->handshake=1;
1204
1205         return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1206     }
1207
1208     /* 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))    */
1209     if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1210         AIRPDCAP_EAP_ACK(data[offset+1])==0 &&
1211         AIRPDCAP_EAP_MIC(data[offset])==1)
1212     {
1213         if (AIRPDCAP_EAP_SEC(data[offset])==0) {
1214
1215             /* PATCH:   some implementations set secure bit to 0 also in the 4th message                */
1216             /*          to recognize which message is this check if wep_key data length is 0            */
1217             /*          in the 4th message                                                              */
1218             if (data[offset+92]!=0 || data[offset+93]!=0) {
1219                 /* message 2    */
1220                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 2", AIRPDCAP_DEBUG_LEVEL_3);
1221
1222                 /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the   */
1223                 /* outstanding Message 1. If not, it silently discards the message.                                                                                             */
1224                 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame,    */
1225                 /* the Authenticator silently discards Message 2.                                                                                                                                               */
1226                 /* -> not checked; the Supplicant will send another message 2 (hopefully!)                                                                              */
1227
1228                 /* now you can derive the PTK   */
1229                 for (key_index=0; key_index<(INT)ctx->keys_nr || useCache; key_index++) {
1230                     /* use the cached one, or try all keys      */
1231                     if (!useCache) {
1232                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1233                         tmp_key=&ctx->keys[key_index];
1234                     } else {
1235                         /* there is a cached key in the security association, if it's a WPA key try it...       */
1236                         if (sa->key!=NULL &&
1237                             (sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1238                              sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1239                              sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)) {
1240                                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try cached WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1241                                 tmp_key=sa->key;
1242                         } else {
1243                             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Cached key is of a wrong type, try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1244                             tmp_key=&ctx->keys[key_index];
1245                         }
1246                     }
1247
1248                     /* obviously, try only WPA keys...  */
1249                     if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1250                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1251                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)
1252                     {
1253                         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) {
1254                             /* We have a "wildcard" SSID.  Use the one from the packet. */
1255                             memcpy(&pkt_key, tmp_key, sizeof(pkt_key));
1256                             memcpy(&pkt_key.UserPwd.Ssid, ctx->pkt_ssid, ctx->pkt_ssid_len);
1257                              pkt_key.UserPwd.SsidLen = ctx->pkt_ssid_len;
1258                             AirPDcapRsnaPwd2Psk(pkt_key.UserPwd.Passphrase, pkt_key.UserPwd.Ssid,
1259                                 pkt_key.UserPwd.SsidLen, pkt_key.KeyData.Wpa.Psk);
1260                             tmp_key = &pkt_key;
1261                         }
1262
1263                         /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce  */
1264                         AirPDcapRsnaPrfX(sa,                    /* authenticator nonce, bssid, station mac      */
1265                             tmp_key->KeyData.Wpa.Pmk,   /* PMK  */
1266                             data+offset+12,             /* supplicant nonce     */
1267                             512,
1268                             sa->wpa.ptk);
1269
1270                         /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK)   */
1271                         eapol_len=pntohs(data+offset-3)+4;
1272                         memcpy(eapol, &data[offset-5], (eapol_len<AIRPDCAP_EAPOL_MAX_LEN?eapol_len:AIRPDCAP_EAPOL_MAX_LEN));
1273                         ret_value=AirPDcapRsnaMicCheck(eapol,                                           /*      eapol frame (header also)               */
1274                             eapol_len,                                                                                                  /*      eapol frame length                              */
1275                             sa->wpa.ptk,                                                                                                /*      Key Confirmation Key                            */
1276                             AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]));                /*      EAPOL-Key description version   */
1277
1278                         /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches              */
1279                         /* that from the (Re)Association Request message.                                                                                                                                               */
1280                         /*              i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request   */
1281                         /* primitive to terminate the association.                                                                                                                                                              */
1282                         /*              ii) If they do match bit-wise, the Authenticator constructs Message 3.                                                                  */
1283                     }
1284
1285                     if (!ret_value &&
1286                         (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1287                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1288                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK))
1289                     {
1290                         /* the temporary key is the correct one, cached in the Security Association     */
1291
1292                         sa->key=tmp_key;
1293
1294                         if (key!=NULL) {
1295                             memcpy(key, &tmp_key, sizeof(AIRPDCAP_KEY_ITEM));
1296                             if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1297                                 key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1298                             else if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1299                                 key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1300                         }
1301
1302                         break;
1303                     } else {
1304                         /* the cached key was not valid, try other keys */
1305
1306                         if (useCache==TRUE) {
1307                             useCache=FALSE;
1308                             key_index--;
1309                         }
1310                     }
1311                 }
1312
1313                 if (ret_value) {
1314                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "handshake step failed", AIRPDCAP_DEBUG_LEVEL_3);
1315                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1316                 }
1317
1318                 sa->handshake=2;
1319
1320                 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1321             } else {
1322                 /* message 4    */
1323
1324                 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear."      */
1325
1326                 /* TODO check MIC and Replay Counter                                                                                                                                                                                    */
1327                 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
1328                 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                                                */
1329                 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the        */
1330                 /* Authenticator silently discards Message 4.                                                                                                                                                           */
1331
1332                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4 (patched)", AIRPDCAP_DEBUG_LEVEL_3);
1333
1334                 sa->handshake=4;
1335
1336                 sa->validKey=TRUE;
1337
1338                 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1339             }
1340             /* END OF PATCH                                                                                                                                                                     */
1341             /*                                                                                                                                                                                                          */
1342         } else {
1343             /* message 4        */
1344
1345             /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear."  */
1346
1347             /* TODO check MIC and Replay Counter                                                                                                                                                                                        */
1348             /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one     */
1349             /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                                            */
1350             /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the    */
1351             /* Authenticator silently discards Message 4.                                                                                                                                                               */
1352
1353             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4", AIRPDCAP_DEBUG_LEVEL_3);
1354
1355             sa->handshake=4;
1356
1357             sa->validKey=TRUE;
1358
1359             return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1360         }
1361     }
1362
1363     /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1)   */
1364     if (AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1365         AIRPDCAP_EAP_MIC(data[offset])==1)
1366     {
1367                 P_EAPOL_RSN_KEY pEAPKey;
1368         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 3", AIRPDCAP_DEBUG_LEVEL_3);
1369
1370         /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field              */
1371         /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1.  */
1372         /* -> not checked, the Authenticator will send another message 3 (hopefully!)                                                                                           */
1373
1374         /*      TODO check page 88 (RNS)        */
1375
1376                 /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1377                                  In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key.*/
1378                 pEAPKey = (P_EAPOL_RSN_KEY)(&(data[offset-1]));
1379                 if (pEAPKey->type == AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR){
1380                         PAIRPDCAP_SEC_ASSOCIATION broadcast_sa;
1381                         AIRPDCAP_SEC_ASSOCIATION_ID id;
1382
1383                         /* Get broadcacst SA for the current BSSID */
1384                         memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
1385                         memcpy(id.bssid, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1386                         broadcast_sa = AirPDcapGetSaPtr(ctx, &id);
1387
1388                         if (broadcast_sa == NULL){
1389                                 return AIRPDCAP_RET_UNSUCCESS;
1390                         }
1391                         AirPDcapDecryptWPABroadcastKey(pEAPKey, sa->wpa.ptk+16, broadcast_sa);
1392                 }
1393
1394         return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1395     }
1396
1397     return AIRPDCAP_RET_UNSUCCESS;
1398 }
1399
1400 static INT
1401 AirPDcapRsnaMicCheck(
1402     UCHAR *eapol,
1403     USHORT eapol_len,
1404     UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
1405     USHORT key_ver)
1406 {
1407     UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN];
1408     UCHAR c_mic[20];    /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */
1409
1410     /* copy the MIC from the EAPOL packet       */
1411     memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN);
1412
1413     /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
1414     memset(eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, 0, AIRPDCAP_WPA_MICKEY_LEN);
1415
1416     if (key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP) {
1417         /* use HMAC-MD5 for the EAPOL-Key MIC   */
1418         md5_hmac(eapol, eapol_len, KCK, AIRPDCAP_WPA_KCK_LEN, c_mic);
1419     } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) {
1420         /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
1421         sha1_hmac(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
1422     } else
1423         /* key descriptor version not recognized */
1424         return AIRPDCAP_RET_UNSUCCESS;
1425
1426     /* compare calculated MIC with the Key MIC and return result (0 means success) */
1427     return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN);
1428 }
1429
1430 static INT
1431 AirPDcapValidateKey(
1432     PAIRPDCAP_KEY_ITEM key)
1433 {
1434     size_t len;
1435     UCHAR ret=TRUE;
1436     AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1437
1438     if (key==NULL) {
1439         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "NULL key", AIRPDCAP_DEBUG_LEVEL_5);
1440         AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1441         return FALSE;
1442     }
1443
1444     switch (key->KeyType) {
1445         case AIRPDCAP_KEY_TYPE_WEP:
1446             /* check key size limits    */
1447             len=key->KeyData.Wep.WepKeyLen;
1448             if (len<AIRPDCAP_WEP_KEY_MINLEN || len>AIRPDCAP_WEP_KEY_MAXLEN) {
1449                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WEP key: key length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1450                 ret=FALSE;
1451             }
1452             break;
1453
1454         case AIRPDCAP_KEY_TYPE_WEP_40:
1455             /* set the standard length  and use a generic WEP key type  */
1456             key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_40_KEY_LEN;
1457             key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1458             break;
1459
1460         case AIRPDCAP_KEY_TYPE_WEP_104:
1461             /* set the standard length  and use a generic WEP key type  */
1462             key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_104_KEY_LEN;
1463             key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1464             break;
1465
1466         case AIRPDCAP_KEY_TYPE_WPA_PWD:
1467             /* check passphrase and SSID size limits    */
1468             len=strlen(key->UserPwd.Passphrase);
1469             if (len<AIRPDCAP_WPA_PASSPHRASE_MIN_LEN || len>AIRPDCAP_WPA_PASSPHRASE_MAX_LEN) {
1470                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: passphrase length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1471                 ret=FALSE;
1472             }
1473
1474             len=key->UserPwd.SsidLen;
1475             if (len>AIRPDCAP_WPA_SSID_MAX_LEN) {
1476                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: ssid length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1477                 ret=FALSE;
1478             }
1479
1480             break;
1481
1482         case AIRPDCAP_KEY_TYPE_WPA_PSK:
1483             break;
1484
1485         case AIRPDCAP_KEY_TYPE_WPA_PMK:
1486             break;
1487
1488         default:
1489             ret=FALSE;
1490     }
1491
1492     AIRPDCAP_DEBUG_TRACE_END("AirPDcapValidateKey");
1493     return ret;
1494 }
1495
1496 static INT
1497 AirPDcapGetSa(
1498     PAIRPDCAP_CONTEXT ctx,
1499     AIRPDCAP_SEC_ASSOCIATION_ID *id)
1500 {
1501     INT sa_index;
1502
1503     if (ctx->sa_index!=-1) {
1504         /* at least one association was stored                                                                                                          */
1505         /* search for the association from sa_index to 0 (most recent added)    */
1506         for (sa_index=ctx->sa_index; sa_index>=0; sa_index--) {
1507             if (ctx->sa[sa_index].used) {
1508                 if (memcmp(id, &(ctx->sa[sa_index].saId), sizeof(AIRPDCAP_SEC_ASSOCIATION_ID))==0) {
1509                     ctx->index=sa_index;
1510                     return sa_index;
1511                 }
1512             }
1513         }
1514     }
1515
1516     return -1;
1517 }
1518
1519 static INT
1520 AirPDcapStoreSa(
1521     PAIRPDCAP_CONTEXT ctx,
1522     AIRPDCAP_SEC_ASSOCIATION_ID *id)
1523 {
1524     INT last_free;
1525
1526     if (ctx->sa[ctx->first_free_index].used) {
1527         /* last addition was in the middle of the array (and the first_free_index was just incremented by 1)    */
1528         /* search for a free space from the first_free_index to AIRPDCAP_STA_INFOS_NR (to avoid free blocks in  */
1529         /*              the middle)                                                                                                                                                                                                                                     */
1530         for (last_free=ctx->first_free_index; last_free<AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; last_free++)
1531             if (!ctx->sa[last_free].used)
1532                 break;
1533
1534         if (last_free>=AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR) {
1535             /* there is no empty space available. FAILURE       */
1536             return -1;
1537         }
1538
1539         /* store first free space index */
1540         ctx->first_free_index=last_free;
1541     }
1542
1543     /* use this info    */
1544     ctx->index=ctx->first_free_index;
1545
1546     /* reset the info structure */
1547     memset(ctx->sa+ctx->index, 0, sizeof(AIRPDCAP_SEC_ASSOCIATION));
1548
1549     ctx->sa[ctx->index].used=1;
1550
1551     /* set the info structure   */
1552     memcpy(&(ctx->sa[ctx->index].saId), id, sizeof(AIRPDCAP_SEC_ASSOCIATION_ID));
1553
1554     /* increment by 1 the first_free_index (heuristic)  */
1555     ctx->first_free_index++;
1556
1557     /* set the sa_index if the added index is greater the the sa_index  */
1558     if (ctx->index > ctx->sa_index)
1559         ctx->sa_index=ctx->index;
1560
1561     return ctx->index;
1562 }
1563
1564 /*
1565  * AirPDcapGetBssidAddress() and AirPDcapGetBssidAddress() are used for
1566  * key caching.  In each case, it's more important to return a value than
1567  * to return a _correct_ value, so we fudge addresses in some cases, e.g.
1568  * the BSSID in bridged connections.
1569  * FromDS    ToDS    Sta    BSSID
1570  * 0         0       addr2  addr3
1571  * 0         1       addr2  addr1
1572  * 1         0       addr1  addr2
1573  * 1         1       addr2  addr1
1574  */
1575
1576 static const UCHAR *
1577 AirPDcapGetStaAddress(
1578     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1579 {
1580     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1581         case 0:
1582         case 1:
1583         case 3:
1584             return frame->addr2;
1585         case 2:
1586             return frame->addr1;
1587         default:
1588             return NULL;
1589     }
1590 }
1591
1592 static const UCHAR *
1593 AirPDcapGetBssidAddress(
1594     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1595 {
1596     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1597         case 0:
1598             return frame->addr3;
1599         case 1:
1600         case 3:
1601             return frame->addr1;
1602         case 2:
1603             return frame->addr2;
1604         default:
1605             return NULL;
1606     }
1607 }
1608
1609 /* Function used to derive the PTK. Refer to IEEE 802.11I-2004, pag. 74 */
1610 static void
1611 AirPDcapRsnaPrfX(
1612     AIRPDCAP_SEC_ASSOCIATION *sa,
1613     const UCHAR pmk[32],
1614     const UCHAR snonce[32],
1615     const INT x,        /*      for TKIP 512, for CCMP 384      */
1616     UCHAR *ptk)
1617 {
1618     UINT8 i;
1619     UCHAR R[100];
1620     INT offset=sizeof("Pairwise key expansion");
1621
1622     memset(R, 0, 100);
1623
1624     memcpy(R, "Pairwise key expansion", offset);
1625
1626     /*  Min(AA, SPA) || Max(AA, SPA)    */
1627     if (memcmp(sa->saId.sta, sa->saId.bssid, AIRPDCAP_MAC_LEN) < 0)
1628     {
1629         memcpy(R + offset, sa->saId.sta, AIRPDCAP_MAC_LEN);
1630         memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1631     }
1632     else
1633     {
1634         memcpy(R + offset, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1635         memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.sta, AIRPDCAP_MAC_LEN);
1636     }
1637
1638     offset+=AIRPDCAP_MAC_LEN*2;
1639
1640     /*  Min(ANonce,SNonce) || Max(ANonce,SNonce)        */
1641     if( memcmp(snonce, sa->wpa.nonce, 32) < 0 )
1642     {
1643         memcpy(R + offset, snonce, 32);
1644         memcpy(R + offset + 32, sa->wpa.nonce, 32);
1645     }
1646     else
1647     {
1648         memcpy(R + offset, sa->wpa.nonce, 32);
1649         memcpy(R + offset + 32, snonce, 32);
1650     }
1651
1652     offset+=32*2;
1653
1654     for(i = 0; i < (x+159)/160; i++)
1655     {
1656         R[offset] = i;
1657         sha1_hmac(pmk, 32, R, 100, ptk + i * 20);
1658     }
1659 }
1660
1661 static INT
1662 AirPDcapRsnaPwd2PskStep(
1663     const guint8 *ppBytes,
1664     const guint ppLength,
1665     const CHAR *ssid,
1666     const size_t ssidLength,
1667     const INT iterations,
1668     const INT count,
1669     UCHAR *output)
1670 {
1671     UCHAR digest[36], digest1[AIRPDCAP_SHA_DIGEST_LEN];
1672     INT i, j;
1673
1674     /* U1 = PRF(P, S || INT(i)) */
1675     memcpy(digest, ssid, ssidLength);
1676     digest[ssidLength] = (UCHAR)((count>>24) & 0xff);
1677     digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff);
1678     digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff);
1679     digest[ssidLength+3] = (UCHAR)(count & 0xff);
1680     sha1_hmac(ppBytes, ppLength, digest, ssidLength+4, digest1);
1681
1682     /* output = U1 */
1683     memcpy(output, digest1, AIRPDCAP_SHA_DIGEST_LEN);
1684     for (i = 1; i < iterations; i++) {
1685         /* Un = PRF(P, Un-1) */
1686         sha1_hmac(ppBytes, ppLength, digest1, AIRPDCAP_SHA_DIGEST_LEN, digest);
1687
1688         memcpy(digest1, digest, AIRPDCAP_SHA_DIGEST_LEN);
1689         /* output = output xor Un */
1690         for (j = 0; j < AIRPDCAP_SHA_DIGEST_LEN; j++) {
1691             output[j] ^= digest[j];
1692         }
1693     }
1694
1695     return AIRPDCAP_RET_SUCCESS;
1696 }
1697
1698 static INT
1699 AirPDcapRsnaPwd2Psk(
1700     const CHAR *passphrase,
1701     const CHAR *ssid,
1702     const size_t ssidLength,
1703     UCHAR *output)
1704 {
1705     UCHAR m_output[AIRPDCAP_WPA_PSK_LEN];
1706     GByteArray *pp_ba = g_byte_array_new();
1707
1708     memset(m_output, 0, AIRPDCAP_WPA_PSK_LEN);
1709
1710     if (!uri_str_to_bytes(passphrase, pp_ba)) {
1711         g_byte_array_free(pp_ba, TRUE);
1712         return 0;
1713     }
1714
1715     AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 1, m_output);
1716     AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[AIRPDCAP_SHA_DIGEST_LEN]);
1717
1718     memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN);
1719     g_byte_array_free(pp_ba, TRUE);
1720
1721     return 0;
1722 }
1723
1724 /*
1725  * Returns the decryption_key_t struct given a string describing the key.
1726  * Returns NULL if the key_string cannot be parsed.
1727  */
1728 decryption_key_t*
1729 parse_key_string(gchar* input_string)
1730 {
1731     gchar *type;
1732     gchar *key;
1733     gchar *ssid;
1734
1735     GString    *key_string = NULL;
1736     GByteArray *ssid_ba = NULL, *key_ba;
1737     gboolean    res;
1738
1739     gchar **tokens;
1740     guint n = 0;
1741     decryption_key_t *dk;
1742     gchar *first_nibble = input_string;
1743
1744     if(input_string == NULL)
1745         return NULL;
1746
1747     /*
1748      * Parse the input_string. It should be in the form
1749      * <key type>:<key data>[:<ssid>]
1750      * XXX - For backward compatibility, the a WEP key can be just a string
1751      * of hexadecimal characters (if WEP key is wrong, null will be
1752      * returned...).
1753      */
1754
1755     /* First, check for a WEP string */
1756     /* XXX - This duplicates code in packet-ieee80211.c */
1757     if (g_ascii_strncasecmp(input_string, STRING_KEY_TYPE_WEP ":", 4) == 0) {
1758         first_nibble += 4;
1759     }
1760
1761     key_ba = g_byte_array_new();
1762     res = hex_str_to_bytes(first_nibble, key_ba, FALSE);
1763
1764     if (res && key_ba->len > 0) {
1765         /* Key is correct! It was probably an 'old style' WEP key */
1766         /* Create the decryption_key_t structure, fill it and return it*/
1767         dk = g_malloc(sizeof(decryption_key_t));
1768
1769         dk->type = AIRPDCAP_KEY_TYPE_WEP;
1770         /* XXX - The current key handling code in the GUI requires
1771          * no separators and lower case */
1772         dk->key  = g_string_new(bytes_to_str(key_ba->data, key_ba->len));
1773         g_string_down(dk->key);
1774         dk->bits = key_ba->len * 8;
1775         dk->ssid = NULL;
1776
1777         g_byte_array_free(key_ba, TRUE);
1778         return dk;
1779     }
1780     g_byte_array_free(key_ba, TRUE);
1781
1782
1783     tokens = g_strsplit(input_string,":",0);
1784
1785     /* Tokens is a null termiated array of strings ... */
1786     while(tokens[n] != NULL)
1787         n++;
1788
1789     if(n < 2)
1790     {
1791         /* Free the array of strings */
1792         g_strfreev(tokens);
1793         return NULL;
1794     }
1795
1796     type = g_strdup(tokens[0]);
1797
1798     /*
1799      * The second token is the key (right now it doesn't matter
1800      * if it is a passphrase[+ssid] or an hexadecimal one)
1801      */
1802     key = g_strdup(tokens[1]);
1803
1804     ssid = NULL;
1805     /* Maybe there is a third token (an ssid, if everything else is ok) */
1806     if(n >= 3)
1807     {
1808         ssid = g_strdup(tokens[2]);
1809     }
1810
1811     if (g_ascii_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
1812     {
1813         /* Create a new string */
1814         key_string = g_string_new(key);
1815
1816         key_ba = g_byte_array_new();
1817         res = hex_str_to_bytes(key, key_ba, FALSE);
1818
1819         /* Two tokens means that the user should have entered a WPA-BIN key ... */
1820         if(!res || ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
1821         {
1822             g_string_free(key_string, TRUE);
1823             g_byte_array_free(key_ba, TRUE);
1824
1825             g_free(type);
1826             g_free(key);
1827             /* No ssid has been created ... */
1828             /* Free the array of strings */
1829             g_strfreev(tokens);
1830             return NULL;
1831         }
1832
1833         /* Key was correct!!! Create the new decryption_key_t ... */
1834         dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1835
1836         dk->type = AIRPDCAP_KEY_TYPE_WPA_PMK;
1837         dk->key  = g_string_new(key);
1838         dk->bits = dk->key->len * 4;
1839         dk->ssid = NULL;
1840
1841         g_string_free(key_string, TRUE);
1842         g_byte_array_free(key_ba, TRUE);
1843         g_free(key);
1844         g_free(type);
1845
1846         /* Free the array of strings */
1847         g_strfreev(tokens);
1848         return dk;
1849     }
1850     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... */
1851     {
1852         /* Create a new string */
1853         key_string = g_string_new(key);
1854         ssid_ba = NULL;
1855
1856         /* Three (or more) tokens mean that the user entered a WPA-PWD key ... */
1857         if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
1858         {
1859             g_string_free(key_string, TRUE);
1860
1861             g_free(type);
1862             g_free(key);
1863             g_free(ssid);
1864
1865             /* Free the array of strings */
1866             g_strfreev(tokens);
1867             return NULL;
1868         }
1869
1870         if(ssid != NULL) /* more than three tokens found, means that the user specified the ssid */
1871         {
1872             ssid_ba = g_byte_array_new();
1873             if (! uri_str_to_bytes(ssid, ssid_ba)) {
1874                 g_string_free(key_string, TRUE);
1875                 g_byte_array_free(ssid_ba, TRUE);
1876                 g_free(type);
1877                 g_free(key);
1878                 g_free(ssid);
1879                 /* Free the array of strings */
1880                 g_strfreev(tokens);
1881                 return NULL;
1882             }
1883
1884             if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
1885             {
1886                 g_string_free(key_string, TRUE);
1887                 g_byte_array_free(ssid_ba, TRUE);
1888
1889                 g_free(type);
1890                 g_free(key);
1891                 g_free(ssid);
1892
1893                 /* Free the array of strings */
1894                 g_strfreev(tokens);
1895                 return NULL;
1896             }
1897         }
1898
1899         /* Key was correct!!! Create the new decryption_key_t ... */
1900         dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1901
1902         dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
1903         dk->key  = g_string_new(key);
1904         dk->bits = 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
1905         dk->ssid = byte_array_dup(ssid_ba); /* NULL if ssid_ba is NULL */
1906
1907         g_string_free(key_string, TRUE);
1908         if (ssid_ba != NULL)
1909             g_byte_array_free(ssid_ba, TRUE);
1910
1911         g_free(type);
1912         g_free(key);
1913         if(ssid != NULL)
1914             g_free(ssid);
1915
1916         /* Free the array of strings */
1917         g_strfreev(tokens);
1918         return dk;
1919     }
1920
1921     /* Something was wrong ... free everything */
1922
1923     g_free(type);
1924     g_free(key);
1925     if(ssid != NULL)
1926         g_free(ssid); /* It is not always present */
1927     if (ssid_ba != NULL)
1928         g_byte_array_free(ssid_ba, TRUE);
1929
1930     /* Free the array of strings */
1931     g_strfreev(tokens);
1932
1933     return NULL;
1934 }
1935
1936 /*
1937  * Returns a newly allocated string representing the given decryption_key_t
1938  * struct, or NULL if something is wrong...
1939  */
1940 gchar*
1941 get_key_string(decryption_key_t* dk)
1942 {
1943     gchar* output_string = NULL;
1944
1945     if(dk == NULL || dk->key == NULL)
1946         return NULL;
1947
1948     switch(dk->type) {
1949         case AIRPDCAP_KEY_TYPE_WEP:
1950             output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WEP,dk->key->str);
1951             break;
1952         case AIRPDCAP_KEY_TYPE_WPA_PWD:
1953             if(dk->ssid == NULL)
1954                 output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PWD,dk->key->str);
1955             else
1956                 output_string = g_strdup_printf("%s:%s:%s",
1957                     STRING_KEY_TYPE_WPA_PWD, dk->key->str,
1958                     format_uri(dk->ssid, ":"));
1959             break;
1960         case AIRPDCAP_KEY_TYPE_WPA_PMK:
1961             output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PSK,dk->key->str);
1962             break;
1963         default:
1964             return NULL;
1965             break;
1966     }
1967
1968     return output_string;
1969 }
1970
1971 #ifdef  __cplusplus
1972 }
1973 #endif
1974
1975 /****************************************************************************/
1976
1977 /*
1978  * Editor modelines
1979  *
1980  * Local Variables:
1981  * c-basic-offset: 4
1982  * tab-width: 8
1983  * set-tabs-mode: nil
1984  * End:
1985  *
1986  * ex: set shiftwidth=4 tabstop=8 expandtab
1987  * :indentSize=4:tabSize=8:noTabs=true:
1988  */