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