3 * Copyright (c) 2006 CACE Technologies, Davis (California)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
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
35 /****************************************************************************/
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>
48 #include <epan/tvbuff.h>
49 #include <epan/to_str.h>
50 #include <epan/strutil.h>
51 #include <epan/crypt/airpdcap_rijndael.h>
53 #include "airpdcap_system.h"
54 #include "airpdcap_int.h"
56 #include "airpdcap_debug.h"
58 #include "wep-wpadefs.h"
61 /****************************************************************************/
63 /****************************************************************************/
64 /* Constant definitions */
66 #define AIRPDCAP_SHA_DIGEST_LEN 20
68 /* EAPOL definitions */
70 * Length of the EAPOL-Key key confirmation key (KCK) used to calculate
71 * MIC over EAPOL frame and validate an EAPOL packet (128 bits)
73 #define AIRPDCAP_WPA_KCK_LEN 16
75 *Offset of the Key MIC in the EAPOL packet body
77 #define AIRPDCAP_WPA_MICKEY_OFFSET 77
79 * Maximum length of the EAPOL packet (it depends on the maximum MAC
82 #define AIRPDCAP_WPA_MAX_EAPOL_LEN 4095
84 * EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and
85 * from a STA when neither the group nor pairwise ciphers are CCMP for
88 * Defined in 802.11i-2004, page 78
90 #define AIRPDCAP_WPA_KEY_VER_NOT_CCMP 1
92 * EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and
93 * from a STA when either the pairwise or the group cipher is AES-CCMP
94 * for Key Descriptor 2.
96 * Defined in 802.11i-2004, page 78
98 #define AIRPDCAP_WPA_KEY_VER_AES_CCMP 2
100 /** Define EAPOL Key Descriptor type values: use 254 for WPA and 2 for WPA2 **/
101 #define AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR 254
102 #define AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR 2
104 /****************************************************************************/
108 /****************************************************************************/
109 /* Macro definitions */
111 extern const UINT32 crc32_table[256];
112 #define CRC(crc, ch) (crc = (crc >> 8) ^ crc32_table[(crc ^ (ch)) & 0xff])
114 #define AIRPDCAP_GET_TK(ptk) (ptk + 32)
116 /****************************************************************************/
118 /****************************************************************************/
119 /* Type definitions */
121 /* Internal function prototype declarations */
128 * It is a step of the PBKDF2 (specifically the PKCS #5 v2.0) defined in
129 * the RFC 2898 to derive a key (used as PMK in WPA)
130 * @param ppbytes [IN] pointer to a password (sequence of between 8 and
131 * 63 ASCII encoded characters)
132 * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
134 * @param iterations [IN] times to hash the password (4096 for WPA)
135 * @param count [IN] ???
136 * @param output [OUT] pointer to a preallocated buffer of
137 * AIRPDCAP_SHA_DIGEST_LEN characters that will contain a part of the key
139 static INT AirPDcapRsnaPwd2PskStep(
140 const guint8 *ppbytes,
141 const guint passLength,
143 const size_t ssidLength,
144 const INT iterations,
150 * It calculates the passphrase-to-PSK mapping reccomanded for use with
151 * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
153 * @param passphrase [IN] pointer to a password (sequence of between 8 and
154 * 63 ASCII encoded characters)
155 * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
157 * @param output [OUT] calculated PSK (to use as PMK in WPA)
159 * Described in 802.11i-2004, page 165
161 static INT AirPDcapRsnaPwd2Psk(
162 const CHAR *passphrase,
164 const size_t ssidLength,
168 static INT AirPDcapRsnaMng(
170 guint mac_header_len,
172 PAIRPDCAP_KEY_ITEM key,
173 AIRPDCAP_SEC_ASSOCIATION *sa,
177 static INT AirPDcapWepMng(
178 PAIRPDCAP_CONTEXT ctx,
180 guint mac_header_len,
182 PAIRPDCAP_KEY_ITEM key,
183 AIRPDCAP_SEC_ASSOCIATION *sa,
187 static INT AirPDcapRsna4WHandshake(
188 PAIRPDCAP_CONTEXT ctx,
190 AIRPDCAP_SEC_ASSOCIATION *sa,
191 PAIRPDCAP_KEY_ITEM key,
195 * It checks whether the specified key is corrected or not.
197 * For a standard WEP key the length will be changed to the standard
198 * length, and the type changed in a generic WEP key.
199 * @param key [IN] pointer to the key to validate
201 * - TRUE: the key contains valid fields and values
202 * - FALSE: the key has some invalid field or value
204 static INT AirPDcapValidateKey(
205 PAIRPDCAP_KEY_ITEM key)
208 static INT AirPDcapRsnaMicCheck(
211 UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
216 * @param ctx [IN] pointer to the current context
217 * @param id [IN] id of the association (composed by BSSID and MAC of
220 * - index of the Security Association structure if found
221 * - -1, if the specified addresses pair BSSID-STA MAC has not been found
223 static INT AirPDcapGetSa(
224 PAIRPDCAP_CONTEXT ctx,
225 AIRPDCAP_SEC_ASSOCIATION_ID *id)
228 static INT AirPDcapStoreSa(
229 PAIRPDCAP_CONTEXT ctx,
230 AIRPDCAP_SEC_ASSOCIATION_ID *id)
233 static const UCHAR * AirPDcapGetStaAddress(
234 const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
237 static const UCHAR * AirPDcapGetBssidAddress(
238 const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
241 static void AirPDcapRsnaPrfX(
242 AIRPDCAP_SEC_ASSOCIATION *sa,
244 const UCHAR snonce[32],
245 const INT x, /* for TKIP 512, for CCMP 384 */
253 /****************************************************************************/
255 /****************************************************************************/
256 /* Exported function definitions */
262 const guint8 broadcast_mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
265 /* NOTE : this assumes the WPA RSN IE format. If it were to be a generic RSN IE, then
266 we would need to change the structure since it could be variable length depending on the number
267 of unicast OUI and auth OUI. */
273 guint8 multicastOUI[4];
274 guint16 iUnicastCount; /* this should always be 1 for WPA client */
275 guint8 unicastOUI[4];
276 guint16 iAuthCount; /* this should always be 1 for WPA client */
281 #define EAPKEY_MIC_LEN 16 /* length of the MIC key for EAPoL_Key packet's MIC using MD5 */
284 #define TKIP_GROUP_KEY_LEN 32
285 #define CCMP_GROUP_KEY_LEN 16
286 /* Minimum size of the key bytes payload for a TKIP group key in an M3 message*/
287 #define TKIP_GROUP_KEYBYTES_LEN ( sizeof(RSN_IE) + 8 + TKIP_GROUP_KEY_LEN + 6 ) /* 72 */
288 /* arbitrary upper limit */
289 #define TKIP_GROUP_KEYBYTES_LEN_MAX ( TKIP_GROUP_KEYBYTES_LEN + 28 )
290 /* Minimum size of the key bytes payload for a TKIP group key in a group key message */
291 #define TKIP_GROUP_KEYBYTES_LEN_GKEY (8 + 8 + TKIP_GROUP_KEY_LEN ) /* 48 */
292 /* size of CCMP key bytes payload */
293 #define CCMP_GROUP_KEYBYTES_LEN ( sizeof(RSN_IE) + 8 + CCMP_GROUP_KEY_LEN + 6 ) /* 56 */
296 guint8 key_information[2]; /* Make this an array to avoid alignment issues */
297 guint8 key_length[2]; /* Make this an array to avoid alignment issues */
298 guint8 replay_counter[8];
299 guint8 key_nonce[NONCE_LEN];
301 guint8 key_sequence_counter[8]; /* also called the RSC */
303 guint8 key_mic[EAPKEY_MIC_LEN];
304 guint8 key_data_len[2]; /* Make this an array rather than a U16 to avoid alignment shifting */
305 guint8 ie[TKIP_GROUP_KEYBYTES_LEN_MAX]; /* Make this an array to avoid alignment issues */
306 } EAPOL_RSN_KEY, * P_EAPOL_RSN_KEY;
307 #define RSN_KEY_WITHOUT_KEYBYTES_LEN sizeof(EAPOL_RSN_KEY)-TKIP_GROUP_KEYBYTES_LEN_MAX
308 /* Minimum possible group key msg size (group key msg using CCMP as cipher)*/
309 #define GROUP_KEY_PAYLOAD_LEN_MIN RSN_KEY_WITHOUT_KEYBYTES_LEN+CCMP_GROUP_KEY_LEN
311 /* A note about some limitations with the WPA decryption:
313 Unless someone takes the time to restructure the current method used for maintaining decryption keys, there
314 will be some anomalies observed when using the decryption feature.
316 Currently, there is only one pairwise (unicast) key and one group (broadcast) key saved for each security association
317 (SA). As a result, if a wireless sniffer session captures the traffic of a station (STA) associating with an AP
318 more than once, or captures a STA roaming, then you will not be able to arbitrarilly click on different encrypted
319 packets in the trace and observe their internal decrypted structure. This is because when you click on a packet,
320 Wireshark immediately performs the decryption routine with whatever the last key used was. It does not maintain a
321 cache of all the keys that were used by this STA/AP pairing.
323 However, if you are just looking at the summary lines of a capture, it will appear that everything was decrypted properly.
324 This is because when first performing a capture or initially reading a capture file, Wireshark will first
325 process the packets in order. As it encounters new EAPOL packets, it will update its internal key list with the
326 newfound key. Then it will use that key for decrypting subsequent packets. Each time a new key is found, the old key
327 is overwritten. So, if you then click on a packet that was previously decrypted properly, it might suddenly no longer
328 be decrypted because a later EAPOL key had caused the internal decryption key to be updated.
330 For broadcast packets, there is a clunky work-around. If the AP is using group-key rotation, you simply have to find the appropriate
331 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
332 and then click on the broadcast packet you are trying to decrypt, the packet will be decrypted properly. By first
333 clicking on the EAPOL packet for the group-key, you will force Wireshark to parse that packet and load the group-key it
334 contains. That group key will then be used for decrypting all subsequent broadcast packets you click on.
336 Ideally, it would be best to maintain an expanding list of SA keys. Perhaps we could associate packet number ranges
337 that they apply to. Then, whenever we need to decrypt a packet, we can determine which key to use based on whether
338 it is broadcast or unicast and within what packet number range it falls.
340 Either that, or store two versions of encrypted packets - the orginal packet and its successfully
341 decrypted version. Then Wireshark wouldn't have to decrypt packets on the fly if they were already successfully decrypted.
347 AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption_key, PAIRPDCAP_SEC_ASSOCIATION sa, gboolean group_hshake)
351 guint8 *szEncryptedKey;
352 guint16 key_bytes_len = 0; /* Length of the total key data field */
353 guint16 key_len = 0; /* Actual group key length */
354 static AIRPDCAP_KEY_ITEM dummy_key; /* needed in case AirPDcapRsnaMng() wants the key structure */
356 /* 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. */
358 /* Preparation for decrypting the group key - determine group key data length */
359 /* depending on whether the pairwise key is TKIP or AES encryption key */
360 key_version = AIRPDCAP_EAP_KEY_DESCR_VER(pEAPKey->key_information[1]);
361 if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
363 key_bytes_len = pntoh16(pEAPKey->key_length);
364 }else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
366 key_bytes_len = pntoh16(pEAPKey->key_data_len);
369 if (key_bytes_len > TKIP_GROUP_KEYBYTES_LEN_MAX || key_bytes_len == 0) { /* Don't read past the end of pEAPKey->ie */
373 /* Encrypted key is in the information element field of the EAPOL key packet */
374 szEncryptedKey = (guint8 *)g_memdup(pEAPKey->ie, key_bytes_len);
376 DEBUG_DUMP("Encrypted Broadcast key:", szEncryptedKey, key_bytes_len);
377 DEBUG_DUMP("KeyIV:", pEAPKey->key_iv, 16);
378 DEBUG_DUMP("decryption_key:", decryption_key, 16);
380 /* Build the full decryption key based on the IV and part of the pairwise key */
381 memcpy(new_key, pEAPKey->key_iv, 16);
382 memcpy(new_key+16, decryption_key, 16);
383 DEBUG_DUMP("FullDecrKey:", new_key, 32);
385 /* As we have no concept of the prior association request at this point, we need to deduce the */
386 /* group key cipher from the length of the key bytes. In WPA this is straightforward as the */
387 /* keybytes just contain the GTK, and the GTK is only in the group handshake, NOT the M3. */
388 /* In WPA2 its a little more tricky as the M3 keybytes contain an RSN_IE, but the group handshake */
389 /* does not. Also there are other (variable length) items in the keybytes which we need to account */
390 /* for to determine the true key length, and thus the group cipher. */
392 if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
395 /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
396 /* group key is decrypted using RC4. Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
398 rc4_state_struct rc4_state;
400 /* The WPA group key just contains the GTK bytes so deducing the type is straightforward */
401 /* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
402 sa->wpa.key_ver = (key_bytes_len >=TKIP_GROUP_KEY_LEN)?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
404 crypt_rc4_init(&rc4_state, new_key, sizeof(new_key));
406 /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
407 crypt_rc4(&rc4_state, dummy, 256);
408 crypt_rc4(&rc4_state, szEncryptedKey, key_bytes_len);
410 } else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
415 guint8 *decrypted_data;
417 /* If this EAPOL frame is part of a separate group key handshake then this contains no */
418 /* RSN IE, so we can deduct that from the calculation. */
420 sa->wpa.key_ver = (key_bytes_len >= (TKIP_GROUP_KEYBYTES_LEN_GKEY))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
422 sa->wpa.key_ver = (key_bytes_len >= (TKIP_GROUP_KEYBYTES_LEN))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
424 /* This storage is needed for the AES_unwrap function */
425 decrypted_data = (guint8 *) g_malloc(key_bytes_len);
427 AES_unwrap(decryption_key, 16, szEncryptedKey, key_bytes_len, decrypted_data);
429 /* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure.
430 The key itself is stored as a GTK KDE
431 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
432 pass pointer to the actual key with 8 bytes offset */
436 while(key_index < key_bytes_len && !key_found){
440 rsn_id = decrypted_data[key_index];
443 key_index += decrypted_data[key_index+1]+2;
450 /* Skip over the GTK header info, and don't copy past the end of the encrypted data */
451 memcpy(szEncryptedKey, decrypted_data+key_index+8, key_bytes_len-key_index-8);
454 g_free(decrypted_data);
457 key_len = (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)?TKIP_GROUP_KEY_LEN:CCMP_GROUP_KEY_LEN;
459 /* Decrypted key is now in szEncryptedKey with len of key_len */
460 DEBUG_DUMP("Broadcast key:", szEncryptedKey, key_len);
462 /* Load the proper key material info into the SA */
463 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 */
466 /* 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 */
467 /* AirPDcapRsnaMng() function will extract the right piece of the GTK for decryption. (The first 16 bytes of the GTK are used for decryption.) */
468 memset(sa->wpa.ptk, 0, sizeof(sa->wpa.ptk));
469 memcpy(sa->wpa.ptk+32, szEncryptedKey, key_len);
470 g_free(szEncryptedKey);
474 /* Return a pointer the the requested SA. If it doesn't exist create it. */
475 static PAIRPDCAP_SEC_ASSOCIATION
477 PAIRPDCAP_CONTEXT ctx,
478 AIRPDCAP_SEC_ASSOCIATION_ID *id)
482 /* search for a cached Security Association for supplied BSSID and STA MAC */
483 if ((sa_index=AirPDcapGetSa(ctx, id))==-1) {
484 /* create a new Security Association if it doesn't currently exist */
485 if ((sa_index=AirPDcapStoreSa(ctx, id))==-1) {
489 /* get the Security Association structure */
490 return &ctx->sa[sa_index];
493 static INT AirPDcapScanForGroupKey(
494 PAIRPDCAP_CONTEXT ctx,
496 const guint mac_header_len,
501 AIRPDCAP_SEC_ASSOCIATION_ID id;
503 PAIRPDCAP_SEC_ASSOCIATION sta_sa;
504 PAIRPDCAP_SEC_ASSOCIATION sa;
506 const guint8 dot1x_header[] = {
507 0xAA, /* DSAP=SNAP */
508 0xAA, /* SSAP=SNAP */
509 0x03, /* Control field=Unnumbered frame */
510 0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
511 0x88, 0x8E /* Type: 802.1X authentication */
514 const EAPOL_RSN_KEY *pEAPKey;
518 AIRPDCAP_DEBUG_TRACE_START("AirPDcapScanForGroupKey");
520 if (mac_header_len + GROUP_KEY_PAYLOAD_LEN_MIN > tot_len) {
521 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Message too short", AIRPDCAP_DEBUG_LEVEL_3);
522 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
525 /* cache offset in the packet data */
526 offset = mac_header_len;
528 /* check if the packet has an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
529 if (memcmp(data+offset, dot1x_header, 8) == 0) {
531 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
533 /* skip LLC header */
537 /* check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25) */
538 if (data[offset+1]!=3) {
539 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_3);
540 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
543 /* get and check the body length (IEEE 802.1X-2004, pg. 25) */
544 bodyLength=pntoh16(data+offset+2);
545 if ((tot_len-offset-4) > bodyLength) {
546 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_3);
547 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
550 /* skip EAPOL MPDU and go to the first byte of the body */
553 pEAPKey = (const EAPOL_RSN_KEY *) (data+offset);
555 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
556 if (/*pEAPKey->type!=0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
557 pEAPKey->type != AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR && /* IEEE 802.11 Key Descriptor Type (WPA2) */
558 pEAPKey->type != AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR) /* 254 = RSN_KEY_DESCRIPTOR - WPA, */
560 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_3);
561 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
564 /* start with descriptor body */
567 /* Verify the bitfields: Key = 0(groupwise) Mic = 1 Ack = 1 Secure = 1 */
568 if (AIRPDCAP_EAP_KEY(data[offset+1])!=0 ||
569 AIRPDCAP_EAP_ACK(data[offset+1])!=1 ||
570 AIRPDCAP_EAP_MIC(data[offset]) != 1 ||
571 AIRPDCAP_EAP_SEC(data[offset]) != 1){
573 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Key bitfields not correct", AIRPDCAP_DEBUG_LEVEL_3);
574 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
578 if ( (addr=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
579 memcpy(id.bssid, addr, AIRPDCAP_MAC_LEN);
581 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]);
583 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
585 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
586 return AIRPDCAP_RET_REQ_DATA;
589 /* force STA address to be the broadcast MAC so we create an SA for the groupkey */
590 memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
592 /* get the Security Association structure for the broadcast MAC and AP */
593 sa = AirPDcapGetSaPtr(ctx, &id);
595 return AIRPDCAP_RET_UNSUCCESS;
598 /* Get the SA for the STA, since we need its pairwise key to decrpyt the group key */
600 /* get STA address */
601 if ( (addr=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
602 memcpy(id.sta, addr, AIRPDCAP_MAC_LEN);
604 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]);
606 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
608 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
609 return AIRPDCAP_RET_REQ_DATA;
612 sta_sa = AirPDcapGetSaPtr(ctx, &id);
614 return AIRPDCAP_RET_UNSUCCESS;
617 /* Extract the group key and install it in the SA */
618 AirPDcapDecryptWPABroadcastKey(pEAPKey, sta_sa->wpa.ptk+16, sa, TRUE);
621 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Skipping: not an EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
624 AIRPDCAP_DEBUG_TRACE_END("AirPDcapScanForGroupKey");
629 INT AirPDcapPacketProcess(
630 PAIRPDCAP_CONTEXT ctx,
632 const guint mac_header_len,
636 PAIRPDCAP_KEY_ITEM key,
637 gboolean mngHandshake,
641 AIRPDCAP_SEC_ASSOCIATION_ID id;
642 PAIRPDCAP_SEC_ASSOCIATION sa;
645 const guint8 dot1x_header[] = {
646 0xAA, /* DSAP=SNAP */
647 0xAA, /* SSAP=SNAP */
648 0x03, /* Control field=Unnumbered frame */
649 0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
650 0x88, 0x8E /* Type: 802.1X authentication */
653 const guint8 bt_dot1x_header[] = {
654 0xAA, /* DSAP=SNAP */
655 0xAA, /* SSAP=SNAP */
656 0x03, /* Control field=Unnumbered frame */
657 0x00, 0x19, 0x58, /* Org. code=Bluetooth SIG */
658 0x00, 0x03 /* Type: Bluetooth Security */
665 AIRPDCAP_DEBUG_TRACE_START("AirPDcapPacketProcess");
668 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
669 AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
670 return AIRPDCAP_RET_UNSUCCESS;
672 if (data==NULL || tot_len==0) {
673 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5);
674 AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
675 return AIRPDCAP_RET_UNSUCCESS;
678 /* check if the packet is of data type */
679 if (AIRPDCAP_TYPE(data[0])!=AIRPDCAP_TYPE_DATA) {
680 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
681 return AIRPDCAP_RET_NO_DATA;
684 /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
685 if (tot_len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) {
686 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5);
687 return AIRPDCAP_RET_WRONG_DATA_SIZE;
691 if ( (addr=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
692 memcpy(id.bssid, addr, AIRPDCAP_MAC_LEN);
694 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]);
696 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
698 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
699 return AIRPDCAP_RET_REQ_DATA;
702 /* get STA address */
703 if ( (addr=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
704 memcpy(id.sta, addr, AIRPDCAP_MAC_LEN);
706 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]);
708 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
710 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
711 return AIRPDCAP_RET_REQ_DATA;
714 /* get the Security Association structure for the STA and AP */
715 sa = AirPDcapGetSaPtr(ctx, &id);
717 return AIRPDCAP_RET_UNSUCCESS;
720 /* cache offset in the packet data (to scan encryption data) */
721 offset = mac_header_len;
723 /* check if data is encrypted (use the WEP bit in the Frame Control field) */
724 if (AIRPDCAP_WEP(data[1])==0)
727 /* data is sent in cleartext, check if is an authentication message or end the process */
728 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Unencrypted data", AIRPDCAP_DEBUG_LEVEL_3);
730 /* check if the packet as an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
731 if (memcmp(data+offset, dot1x_header, 8) == 0 || memcmp(data+offset, bt_dot1x_header, 8) == 0) {
732 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
734 /* skip LLC header */
737 /* check the version of the EAPOL protocol used (IEEE 802.1X-2004, pg. 24) */
738 /* TODO EAPOL protocol version to check? */
740 if (data[offset]!=2) {
741 AIRPDCAP_DEBUG_PRINT_LINE("EAPOL protocol version not recognized", AIRPDCAP_DEBUG_LEVEL_5);
742 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
746 /* check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25) */
747 if (data[offset+1]!=3) {
748 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_5);
749 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
752 /* get and check the body length (IEEE 802.1X-2004, pg. 25) */
753 bodyLength=pntoh16(data+offset+2);
754 if ((tot_len-offset-4) < bodyLength) {
755 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_5);
756 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
759 /* skip EAPOL MPDU and go to the first byte of the body */
762 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
763 if (/*data[offset]!=0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
764 data[offset]!=0x2 && /* IEEE 802.11 Key Descriptor Type */
765 data[offset]!=0xFE) /* TODO what's this value??? */
767 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_5);
768 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
771 /* start with descriptor body */
774 /* manage the 4-way handshake to define the key */
775 return AirPDcapRsna4WHandshake(ctx, data, sa, key, offset);
777 /* cleartext message, not authentication */
778 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "No authentication data", AIRPDCAP_DEBUG_LEVEL_5);
779 return AIRPDCAP_RET_NO_DATA_ENCRYPTED;
785 if (decrypt_data==NULL)
786 return AIRPDCAP_RET_UNSUCCESS;
788 /* create new header and data to modify */
789 *decrypt_len = tot_len;
790 memcpy(decrypt_data, data, *decrypt_len);
793 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3);
795 /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
796 /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP, */
797 /* IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP, */
798 /* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */
799 if (AIRPDCAP_EXTIV(data[offset+3])==0) {
800 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3);
801 return AirPDcapWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
804 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3);
806 /* If index >= 1, then use the group key. This will not work if the AP is using
807 more than one group key simultaneously. I've not seen this in practice, however.
808 Usually an AP will rotate between the two key index values of 1 and 2 whenever
809 it needs to change the group key to be used. */
810 if (AIRPDCAP_KEY_INDEX(data[offset+3])>=1){
812 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "The key index = 1. This is encrypted with a group key.", AIRPDCAP_DEBUG_LEVEL_3);
814 /* force STA address to broadcast MAC so we load the SA for the groupkey */
815 memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
818 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]);
819 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
822 /* search for a cached Security Association for current BSSID and broadcast MAC */
823 sa = AirPDcapGetSaPtr(ctx, &id);
825 return AIRPDCAP_RET_UNSUCCESS;
829 /* Decrypt the packet using the appropriate SA */
830 status = AirPDcapRsnaMng(decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
832 /* If we successfully decrypted a packet, scan it to see if it contains a group key handshake.
833 The group key handshake could be sent at any time the AP wants to change the key (such as when
834 it is using key rotation) so we must scan every packet. */
835 if (status == AIRPDCAP_RET_SUCCESS)
836 AirPDcapScanForGroupKey(ctx, decrypt_data, mac_header_len, *decrypt_len);
842 return AIRPDCAP_RET_UNSUCCESS;
846 PAIRPDCAP_CONTEXT ctx,
847 AIRPDCAP_KEY_ITEM keys[],
848 const size_t keys_nr)
852 AIRPDCAP_DEBUG_TRACE_START("AirPDcapSetKeys");
854 if (ctx==NULL || keys==NULL) {
855 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "NULL context or NULL keys array", AIRPDCAP_DEBUG_LEVEL_3);
856 AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
860 if (keys_nr>AIRPDCAP_MAX_KEYS_NR) {
861 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Keys number greater than maximum", AIRPDCAP_DEBUG_LEVEL_3);
862 AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
866 /* clean key and SA collections before setting new ones */
867 AirPDcapInitContext(ctx);
869 /* check and insert keys */
870 for (i=0, success=0; i<(INT)keys_nr; i++) {
871 if (AirPDcapValidateKey(keys+i)==TRUE) {
872 if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD) {
873 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PWD key", AIRPDCAP_DEBUG_LEVEL_4);
874 AirPDcapRsnaPwd2Psk(keys[i].UserPwd.Passphrase, keys[i].UserPwd.Ssid, keys[i].UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
877 else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
878 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PMK key", AIRPDCAP_DEBUG_LEVEL_4);
879 } else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WEP) {
880 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WEP key", AIRPDCAP_DEBUG_LEVEL_4);
882 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a key", AIRPDCAP_DEBUG_LEVEL_4);
885 memcpy(&ctx->keys[success], &keys[i], sizeof(keys[i]));
890 ctx->keys_nr=success;
892 AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
898 PAIRPDCAP_CONTEXT ctx)
900 AIRPDCAP_DEBUG_TRACE_START("AirPDcapCleanKeys");
903 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
904 AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
908 memset(ctx->keys, 0, sizeof(AIRPDCAP_KEY_ITEM) * AIRPDCAP_MAX_KEYS_NR);
912 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "Keys collection cleaned!", AIRPDCAP_DEBUG_LEVEL_5);
913 AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
917 AirPDcapRecurseCleanSA(
918 PAIRPDCAP_SEC_ASSOCIATION sa)
920 if (sa->next != NULL) {
921 AirPDcapRecurseCleanSA(sa->next);
928 AirPDcapCleanSecAssoc(
929 PAIRPDCAP_CONTEXT ctx)
931 PAIRPDCAP_SEC_ASSOCIATION psa;
934 for (psa = ctx->sa, i = 0; i < AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; i++, psa++) {
935 /* To iterate is human, to recurse, divine */
936 AirPDcapRecurseCleanSA(psa);
941 const PAIRPDCAP_CONTEXT ctx,
942 AIRPDCAP_KEY_ITEM keys[],
943 const size_t keys_nr)
947 AIRPDCAP_DEBUG_TRACE_START("AirPDcapGetKeys");
950 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
951 AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
953 } else if (keys==NULL) {
954 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL keys array", AIRPDCAP_DEBUG_LEVEL_5);
955 AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
956 return (INT)ctx->keys_nr;
958 for (i=0, j=0; i<ctx->keys_nr && i<keys_nr && i<AIRPDCAP_MAX_KEYS_NR; i++) {
959 memcpy(&keys[j], &ctx->keys[i], sizeof(keys[j]));
961 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "Got a key", AIRPDCAP_DEBUG_LEVEL_5);
964 AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
970 * XXX - This won't be reliable if a packet containing SSID "B" shows
971 * up in the middle of a 4-way handshake for SSID "A".
972 * We should probably use a small array or hash table to keep multiple
975 INT AirPDcapSetLastSSID(
976 PAIRPDCAP_CONTEXT ctx,
980 if (!ctx || !pkt_ssid || pkt_ssid_len < 1 || pkt_ssid_len > WPA_SSID_MAX_SIZE)
981 return AIRPDCAP_RET_UNSUCCESS;
983 memcpy(ctx->pkt_ssid, pkt_ssid, pkt_ssid_len);
984 ctx->pkt_ssid_len = pkt_ssid_len;
986 return AIRPDCAP_RET_SUCCESS;
989 INT AirPDcapInitContext(
990 PAIRPDCAP_CONTEXT ctx)
992 AIRPDCAP_DEBUG_TRACE_START("AirPDcapInitContext");
995 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
996 AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
997 return AIRPDCAP_RET_UNSUCCESS;
1000 AirPDcapCleanKeys(ctx);
1002 ctx->first_free_index=0;
1005 ctx->pkt_ssid_len = 0;
1007 memset(ctx->sa, 0, AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR * sizeof(AIRPDCAP_SEC_ASSOCIATION));
1009 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "Context initialized!", AIRPDCAP_DEBUG_LEVEL_5);
1010 AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
1011 return AIRPDCAP_RET_SUCCESS;
1014 INT AirPDcapDestroyContext(
1015 PAIRPDCAP_CONTEXT ctx)
1017 AIRPDCAP_DEBUG_TRACE_START("AirPDcapDestroyContext");
1020 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
1021 AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
1022 return AIRPDCAP_RET_UNSUCCESS;
1025 AirPDcapCleanKeys(ctx);
1026 AirPDcapCleanSecAssoc(ctx);
1028 ctx->first_free_index=0;
1032 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "Context destroyed!", AIRPDCAP_DEBUG_LEVEL_5);
1033 AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
1034 return AIRPDCAP_RET_SUCCESS;
1041 /****************************************************************************/
1043 /****************************************************************************/
1044 /* Internal function definitions */
1052 UCHAR *decrypt_data,
1053 guint mac_header_len,
1055 PAIRPDCAP_KEY_ITEM key,
1056 AIRPDCAP_SEC_ASSOCIATION *sa,
1061 guint try_data_len = *decrypt_len;
1063 if (sa->key==NULL) {
1064 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3);
1065 return AIRPDCAP_RET_REQ_DATA;
1067 if (sa->validKey==FALSE) {
1068 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Key not yet valid", AIRPDCAP_DEBUG_LEVEL_3);
1069 return AIRPDCAP_RET_UNSUCCESS;
1072 /* allocate a temp buffer for the decryption loop */
1073 try_data=(UCHAR *)g_malloc(try_data_len);
1075 /* start of loop added by GCS */
1076 for(/* sa */; sa != NULL ;sa=sa->next) {
1078 if (*decrypt_len > try_data_len) {
1079 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Invalid decryption length", AIRPDCAP_DEBUG_LEVEL_3);
1081 return AIRPDCAP_RET_UNSUCCESS;
1084 /* copy the encrypted data into a temp buffer */
1085 memcpy(try_data, decrypt_data, *decrypt_len);
1087 if (sa->wpa.key_ver==1) {
1088 /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
1089 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP", AIRPDCAP_DEBUG_LEVEL_3);
1090 DEBUG_DUMP("ptk", sa->wpa.ptk, 64);
1091 DEBUG_DUMP("ptk portion used", AIRPDCAP_GET_TK(sa->wpa.ptk), 16);
1093 ret_value=AirPDcapTkipDecrypt(try_data+offset, *decrypt_len-offset, try_data+AIRPDCAP_TA_OFFSET, AIRPDCAP_GET_TK(sa->wpa.ptk));
1095 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP failed!", AIRPDCAP_DEBUG_LEVEL_3);
1099 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1100 /* remove MIC (8bytes) and ICV (4bytes) from the end of packet */
1104 /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
1105 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3);
1107 ret_value=AirPDcapCcmpDecrypt(try_data, mac_header_len, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk));
1111 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1112 /* remove MIC (8bytes) from the end of packet */
1119 /* none of the keys worked */
1125 if (*decrypt_len > try_data_len || *decrypt_len < 8) {
1126 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Invalid decryption length", AIRPDCAP_DEBUG_LEVEL_3);
1128 return AIRPDCAP_RET_UNSUCCESS;
1131 /* copy the decrypted data into the decrypt buffer GCS*/
1132 memcpy(decrypt_data, try_data, *decrypt_len);
1135 /* remove protection bit */
1136 decrypt_data[1]&=0xBF;
1138 /* remove TKIP/CCMP header */
1139 offset = mac_header_len;
1141 memmove(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset);
1144 memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1146 if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1147 key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1148 else if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1149 key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1152 return AIRPDCAP_RET_SUCCESS;
1157 PAIRPDCAP_CONTEXT ctx,
1158 UCHAR *decrypt_data,
1159 guint mac_header_len,
1161 PAIRPDCAP_KEY_ITEM key,
1162 AIRPDCAP_SEC_ASSOCIATION *sa,
1165 UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN];
1169 AIRPDCAP_KEY_ITEM *tmp_key;
1170 UINT8 useCache=FALSE;
1172 guint try_data_len = *decrypt_len;
1174 try_data = (UCHAR *)g_malloc(try_data_len);
1179 for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
1180 /* use the cached one, or try all keys */
1182 tmp_key=&ctx->keys[key_index];
1184 if (sa->key!=NULL && sa->key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1185 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try cached WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1188 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Cached key is not valid, try another WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1189 tmp_key=&ctx->keys[key_index];
1193 /* obviously, try only WEP keys... */
1194 if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP)
1196 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1198 memset(wep_key, 0, sizeof(wep_key));
1199 memcpy(try_data, decrypt_data, *decrypt_len);
1201 /* 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) */
1202 memcpy(wep_key, try_data+mac_header_len, AIRPDCAP_WEP_IVLEN);
1203 keylen=tmp_key->KeyData.Wep.WepKeyLen;
1204 memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
1206 ret_value=AirPDcapWepDecrypt(wep_key,
1207 keylen+AIRPDCAP_WEP_IVLEN,
1208 try_data + (mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN),
1209 *decrypt_len-(mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN));
1211 if (ret_value == AIRPDCAP_RET_SUCCESS)
1212 memcpy(decrypt_data, try_data, *decrypt_len);
1215 if (!ret_value && tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1216 /* the tried key is the correct one, cached in the Security Association */
1221 memcpy(key, &sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1222 key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1227 /* the cached key was not valid, try other keys */
1229 if (useCache==TRUE) {
1240 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "WEP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1242 /* remove ICV (4bytes) from the end of packet */
1245 if (*decrypt_len < 4) {
1246 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Decryption length too short", AIRPDCAP_DEBUG_LEVEL_3);
1247 return AIRPDCAP_RET_UNSUCCESS;
1250 /* remove protection bit */
1251 decrypt_data[1]&=0xBF;
1253 /* remove IC header */
1254 offset = mac_header_len;
1256 memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset);
1258 return AIRPDCAP_RET_SUCCESS;
1261 /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
1263 AirPDcapRsna4WHandshake(
1264 PAIRPDCAP_CONTEXT ctx,
1266 AIRPDCAP_SEC_ASSOCIATION *sa,
1267 PAIRPDCAP_KEY_ITEM key,
1270 AIRPDCAP_KEY_ITEM *tmp_key, *tmp_pkt_key, pkt_key;
1271 AIRPDCAP_SEC_ASSOCIATION *tmp_sa;
1274 UCHAR useCache=FALSE;
1275 UCHAR eapol[AIRPDCAP_EAPOL_MAX_LEN];
1281 /* a 4-way handshake packet use a Pairwise key type (IEEE 802.11i-2004, pg. 79) */
1282 if (AIRPDCAP_EAP_KEY(data[offset+1])!=1) {
1283 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Group/STAKey message (not used)", AIRPDCAP_DEBUG_LEVEL_5);
1284 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1287 /* TODO timeouts? */
1289 /* This saves the sa since we are reauthenticating which will overwrite our current sa GCS*/
1290 if(sa->handshake == 4) {
1291 tmp_sa= g_new(AIRPDCAP_SEC_ASSOCIATION, 1);
1292 memcpy(tmp_sa, sa, sizeof(AIRPDCAP_SEC_ASSOCIATION));
1296 /* TODO consider key-index */
1298 /* TODO considera Deauthentications */
1300 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake...", AIRPDCAP_DEBUG_LEVEL_5);
1302 /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
1304 /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
1305 if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1306 AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1307 AIRPDCAP_EAP_MIC(data[offset])==0)
1309 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 1", AIRPDCAP_DEBUG_LEVEL_3);
1311 /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been */
1312 /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current */
1313 /* local value, the Supplicant discards the message. */
1314 /* -> not checked, the Authenticator will be send another Message 1 (hopefully!) */
1316 /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
1317 memcpy(sa->wpa.nonce, data+offset+12, 32);
1319 /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
1320 sa->wpa.key_ver=AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]);
1324 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1327 /* 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)) */
1328 if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1329 AIRPDCAP_EAP_ACK(data[offset+1])==0 &&
1330 AIRPDCAP_EAP_MIC(data[offset])==1)
1332 if (AIRPDCAP_EAP_SEC(data[offset])==0) {
1334 /* PATCH: some implementations set secure bit to 0 also in the 4th message */
1335 /* to recognize which message is this check if wep_key data length is 0 */
1336 /* in the 4th message */
1337 if (data[offset+92]!=0 || data[offset+93]!=0) {
1339 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 2", AIRPDCAP_DEBUG_LEVEL_3);
1341 /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
1342 /* outstanding Message 1. If not, it silently discards the message. */
1343 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, */
1344 /* the Authenticator silently discards Message 2. */
1345 /* -> not checked; the Supplicant will send another message 2 (hopefully!) */
1347 /* now you can derive the PTK */
1348 for (key_index=0; key_index<(INT)ctx->keys_nr || useCache; key_index++) {
1349 /* use the cached one, or try all keys */
1351 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1352 tmp_key=&ctx->keys[key_index];
1354 /* there is a cached key in the security association, if it's a WPA key try it... */
1355 if (sa->key!=NULL &&
1356 (sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1357 sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1358 sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)) {
1359 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try cached WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1362 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Cached key is of a wrong type, try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1363 tmp_key=&ctx->keys[key_index];
1367 /* obviously, try only WPA keys... */
1368 if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1369 tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1370 tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)
1372 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) {
1373 /* We have a "wildcard" SSID. Use the one from the packet. */
1374 memcpy(&pkt_key, tmp_key, sizeof(pkt_key));
1375 memcpy(&pkt_key.UserPwd.Ssid, ctx->pkt_ssid, ctx->pkt_ssid_len);
1376 pkt_key.UserPwd.SsidLen = ctx->pkt_ssid_len;
1377 AirPDcapRsnaPwd2Psk(pkt_key.UserPwd.Passphrase, pkt_key.UserPwd.Ssid,
1378 pkt_key.UserPwd.SsidLen, pkt_key.KeyData.Wpa.Psk);
1379 tmp_pkt_key = &pkt_key;
1381 tmp_pkt_key = tmp_key;
1384 /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
1385 AirPDcapRsnaPrfX(sa, /* authenticator nonce, bssid, station mac */
1386 tmp_pkt_key->KeyData.Wpa.Pmk, /* PMK */
1387 data+offset+12, /* supplicant nonce */
1391 /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK) */
1392 eapol_len=pntoh16(data+offset-3)+4;
1393 memcpy(eapol, &data[offset-5], (eapol_len<AIRPDCAP_EAPOL_MAX_LEN?eapol_len:AIRPDCAP_EAPOL_MAX_LEN));
1394 ret_value=AirPDcapRsnaMicCheck(eapol, /* eapol frame (header also) */
1395 eapol_len, /* eapol frame length */
1396 sa->wpa.ptk, /* Key Confirmation Key */
1397 AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])); /* EAPOL-Key description version */
1399 /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches */
1400 /* that from the (Re)Association Request message. */
1401 /* i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
1402 /* primitive to terminate the association. */
1403 /* ii) If they do match bit-wise, the Authenticator constructs Message 3. */
1407 (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1408 tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1409 tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK))
1411 /* the temporary key is the correct one, cached in the Security Association */
1416 memcpy(key, &tmp_key, sizeof(AIRPDCAP_KEY_ITEM));
1417 if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1418 key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1419 else if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1420 key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1425 /* the cached key was not valid, try other keys */
1427 if (useCache==TRUE) {
1435 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "handshake step failed", AIRPDCAP_DEBUG_LEVEL_3);
1436 return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1441 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1445 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1447 /* TODO check MIC and Replay Counter */
1448 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
1449 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
1450 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1451 /* Authenticator silently discards Message 4. */
1453 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4 (patched)", AIRPDCAP_DEBUG_LEVEL_3);
1459 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1466 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1468 /* TODO check MIC and Replay Counter */
1469 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
1470 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
1471 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1472 /* Authenticator silently discards Message 4. */
1474 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4", AIRPDCAP_DEBUG_LEVEL_3);
1480 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1484 /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
1485 if (AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1486 AIRPDCAP_EAP_MIC(data[offset])==1)
1488 const EAPOL_RSN_KEY *pEAPKey;
1489 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 3", AIRPDCAP_DEBUG_LEVEL_3);
1491 /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field */
1492 /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
1493 /* -> not checked, the Authenticator will send another message 3 (hopefully!) */
1495 /* TODO check page 88 (RNS) */
1497 /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1498 In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key. */
1499 pEAPKey = (const EAPOL_RSN_KEY *)(&(data[offset-1]));
1500 if (pEAPKey->type == AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR){
1501 PAIRPDCAP_SEC_ASSOCIATION broadcast_sa;
1502 AIRPDCAP_SEC_ASSOCIATION_ID id;
1504 /* Get broadcacst SA for the current BSSID */
1505 memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
1506 memcpy(id.bssid, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1507 broadcast_sa = AirPDcapGetSaPtr(ctx, &id);
1509 if (broadcast_sa == NULL){
1510 return AIRPDCAP_RET_UNSUCCESS;
1512 AirPDcapDecryptWPABroadcastKey(pEAPKey, sa->wpa.ptk+16, broadcast_sa, FALSE);
1515 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1518 return AIRPDCAP_RET_UNSUCCESS;
1522 AirPDcapRsnaMicCheck(
1525 UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
1528 UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN];
1529 UCHAR c_mic[20]; /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */
1531 /* copy the MIC from the EAPOL packet */
1532 memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN);
1534 /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
1535 memset(eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, 0, AIRPDCAP_WPA_MICKEY_LEN);
1537 if (key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP) {
1538 /* use HMAC-MD5 for the EAPOL-Key MIC */
1539 md5_hmac(eapol, eapol_len, KCK, AIRPDCAP_WPA_KCK_LEN, c_mic);
1540 } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) {
1541 /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
1542 sha1_hmac(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
1544 /* key descriptor version not recognized */
1545 return AIRPDCAP_RET_UNSUCCESS;
1547 /* compare calculated MIC with the Key MIC and return result (0 means success) */
1548 return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN);
1552 AirPDcapValidateKey(
1553 PAIRPDCAP_KEY_ITEM key)
1557 AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1560 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "NULL key", AIRPDCAP_DEBUG_LEVEL_5);
1561 AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1565 switch (key->KeyType) {
1566 case AIRPDCAP_KEY_TYPE_WEP:
1567 /* check key size limits */
1568 len=key->KeyData.Wep.WepKeyLen;
1569 if (len<AIRPDCAP_WEP_KEY_MINLEN || len>AIRPDCAP_WEP_KEY_MAXLEN) {
1570 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WEP key: key length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1575 case AIRPDCAP_KEY_TYPE_WEP_40:
1576 /* set the standard length and use a generic WEP key type */
1577 key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_40_KEY_LEN;
1578 key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1581 case AIRPDCAP_KEY_TYPE_WEP_104:
1582 /* set the standard length and use a generic WEP key type */
1583 key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_104_KEY_LEN;
1584 key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1587 case AIRPDCAP_KEY_TYPE_WPA_PWD:
1588 /* check passphrase and SSID size limits */
1589 len=strlen(key->UserPwd.Passphrase);
1590 if (len<AIRPDCAP_WPA_PASSPHRASE_MIN_LEN || len>AIRPDCAP_WPA_PASSPHRASE_MAX_LEN) {
1591 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: passphrase length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1595 len=key->UserPwd.SsidLen;
1596 if (len>AIRPDCAP_WPA_SSID_MAX_LEN) {
1597 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: ssid length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1603 case AIRPDCAP_KEY_TYPE_WPA_PSK:
1606 case AIRPDCAP_KEY_TYPE_WPA_PMK:
1613 AIRPDCAP_DEBUG_TRACE_END("AirPDcapValidateKey");
1619 PAIRPDCAP_CONTEXT ctx,
1620 AIRPDCAP_SEC_ASSOCIATION_ID *id)
1624 if (ctx->sa_index!=-1) {
1625 /* at least one association was stored */
1626 /* search for the association from sa_index to 0 (most recent added) */
1627 for (sa_index=ctx->sa_index; sa_index>=0; sa_index--) {
1628 if (ctx->sa[sa_index].used) {
1629 if (memcmp(id, &(ctx->sa[sa_index].saId), sizeof(AIRPDCAP_SEC_ASSOCIATION_ID))==0) {
1630 ctx->index=sa_index;
1642 PAIRPDCAP_CONTEXT ctx,
1643 AIRPDCAP_SEC_ASSOCIATION_ID *id)
1647 if (ctx->sa[ctx->first_free_index].used) {
1648 /* last addition was in the middle of the array (and the first_free_index was just incremented by 1) */
1649 /* search for a free space from the first_free_index to AIRPDCAP_STA_INFOS_NR (to avoid free blocks in */
1651 for (last_free=ctx->first_free_index; last_free<AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; last_free++)
1652 if (!ctx->sa[last_free].used)
1655 if (last_free>=AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR) {
1656 /* there is no empty space available. FAILURE */
1660 /* store first free space index */
1661 ctx->first_free_index=last_free;
1665 ctx->index=ctx->first_free_index;
1667 /* reset the info structure */
1668 memset(ctx->sa+ctx->index, 0, sizeof(AIRPDCAP_SEC_ASSOCIATION));
1670 ctx->sa[ctx->index].used=1;
1672 /* set the info structure */
1673 memcpy(&(ctx->sa[ctx->index].saId), id, sizeof(AIRPDCAP_SEC_ASSOCIATION_ID));
1675 /* increment by 1 the first_free_index (heuristic) */
1676 ctx->first_free_index++;
1678 /* set the sa_index if the added index is greater the the sa_index */
1679 if (ctx->index > ctx->sa_index)
1680 ctx->sa_index=ctx->index;
1686 * AirPDcapGetBssidAddress() and AirPDcapGetBssidAddress() are used for
1687 * key caching. In each case, it's more important to return a value than
1688 * to return a _correct_ value, so we fudge addresses in some cases, e.g.
1689 * the BSSID in bridged connections.
1690 * FromDS ToDS Sta BSSID
1697 static const UCHAR *
1698 AirPDcapGetStaAddress(
1699 const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1701 switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1704 return frame->addr2;
1706 return frame->addr1;
1708 if (memcmp(frame->addr1, frame->addr2, AIRPDCAP_MAC_LEN) < 0)
1709 return frame->addr1;
1711 return frame->addr2;
1718 static const UCHAR *
1719 AirPDcapGetBssidAddress(
1720 const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1722 switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1724 return frame->addr3;
1726 return frame->addr1;
1728 return frame->addr2;
1730 if (memcmp(frame->addr1, frame->addr2, AIRPDCAP_MAC_LEN) > 0)
1731 return frame->addr1;
1733 return frame->addr2;
1740 /* Function used to derive the PTK. Refer to IEEE 802.11I-2004, pag. 74 */
1743 AIRPDCAP_SEC_ASSOCIATION *sa,
1744 const UCHAR pmk[32],
1745 const UCHAR snonce[32],
1746 const INT x, /* for TKIP 512, for CCMP 384 */
1751 INT offset=sizeof("Pairwise key expansion");
1755 memcpy(R, "Pairwise key expansion", offset);
1757 /* Min(AA, SPA) || Max(AA, SPA) */
1758 if (memcmp(sa->saId.sta, sa->saId.bssid, AIRPDCAP_MAC_LEN) < 0)
1760 memcpy(R + offset, sa->saId.sta, AIRPDCAP_MAC_LEN);
1761 memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1765 memcpy(R + offset, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1766 memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.sta, AIRPDCAP_MAC_LEN);
1769 offset+=AIRPDCAP_MAC_LEN*2;
1771 /* Min(ANonce,SNonce) || Max(ANonce,SNonce) */
1772 if( memcmp(snonce, sa->wpa.nonce, 32) < 0 )
1774 memcpy(R + offset, snonce, 32);
1775 memcpy(R + offset + 32, sa->wpa.nonce, 32);
1779 memcpy(R + offset, sa->wpa.nonce, 32);
1780 memcpy(R + offset + 32, snonce, 32);
1785 for(i = 0; i < (x+159)/160; i++)
1788 sha1_hmac(pmk, 32, R, 100, ptk + i * 20);
1793 AirPDcapRsnaPwd2PskStep(
1794 const guint8 *ppBytes,
1795 const guint ppLength,
1797 const size_t ssidLength,
1798 const INT iterations,
1802 UCHAR digest[64], digest1[64];
1805 if (ssidLength+4 > 36)
1806 return AIRPDCAP_RET_UNSUCCESS;
1808 memset(digest, 0, 64);
1809 memset(digest1, 0, 64);
1811 /* U1 = PRF(P, S || INT(i)) */
1812 memcpy(digest, ssid, ssidLength);
1813 digest[ssidLength] = (UCHAR)((count>>24) & 0xff);
1814 digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff);
1815 digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff);
1816 digest[ssidLength+3] = (UCHAR)(count & 0xff);
1817 sha1_hmac(ppBytes, ppLength, digest, (guint32) ssidLength+4, digest1);
1820 memcpy(output, digest1, AIRPDCAP_SHA_DIGEST_LEN);
1821 for (i = 1; i < iterations; i++) {
1822 /* Un = PRF(P, Un-1) */
1823 sha1_hmac(ppBytes, ppLength, digest1, AIRPDCAP_SHA_DIGEST_LEN, digest);
1825 memcpy(digest1, digest, AIRPDCAP_SHA_DIGEST_LEN);
1826 /* output = output xor Un */
1827 for (j = 0; j < AIRPDCAP_SHA_DIGEST_LEN; j++) {
1828 output[j] ^= digest[j];
1832 return AIRPDCAP_RET_SUCCESS;
1836 AirPDcapRsnaPwd2Psk(
1837 const CHAR *passphrase,
1839 const size_t ssidLength,
1842 UCHAR m_output[AIRPDCAP_WPA_PSK_LEN];
1843 GByteArray *pp_ba = g_byte_array_new();
1845 memset(m_output, 0, AIRPDCAP_WPA_PSK_LEN);
1847 if (!uri_str_to_bytes(passphrase, pp_ba)) {
1848 g_byte_array_free(pp_ba, TRUE);
1852 AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 1, m_output);
1853 AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[AIRPDCAP_SHA_DIGEST_LEN]);
1855 memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN);
1856 g_byte_array_free(pp_ba, TRUE);
1862 * Returns the decryption_key_t struct given a string describing the key.
1863 * Returns NULL if the input_string cannot be parsed.
1866 parse_key_string(gchar* input_string, guint8 key_type)
1868 gchar *key, *tmp_str;
1871 GString *key_string = NULL;
1872 GByteArray *ssid_ba = NULL, *key_ba;
1877 decryption_key_t *dk;
1879 if(input_string == NULL)
1883 * Parse the input_string. WEP and WPA will be just a string
1884 * of hexadecimal characters (if key is wrong, null will be
1886 * WPA-PWD should be in the form
1887 * <key data>[:<ssid>]
1892 case AIRPDCAP_KEY_TYPE_WEP:
1893 case AIRPDCAP_KEY_TYPE_WEP_40:
1894 case AIRPDCAP_KEY_TYPE_WEP_104:
1896 key_ba = g_byte_array_new();
1897 res = hex_str_to_bytes(input_string, key_ba, FALSE);
1899 if (res && key_ba->len > 0) {
1900 /* Key is correct! It was probably an 'old style' WEP key */
1901 /* Create the decryption_key_t structure, fill it and return it*/
1902 dk = (decryption_key_t *)g_malloc(sizeof(decryption_key_t));
1904 dk->type = AIRPDCAP_KEY_TYPE_WEP;
1905 /* XXX - The current key handling code in the GUI requires
1906 * no separators and lower case */
1907 tmp_str = bytes_to_str(NULL, key_ba->data, key_ba->len);
1908 dk->key = g_string_new(tmp_str);
1909 g_string_ascii_down(dk->key);
1910 dk->bits = key_ba->len * 8;
1913 wmem_free(NULL, tmp_str);
1914 g_byte_array_free(key_ba, TRUE);
1918 /* Key doesn't work */
1919 g_byte_array_free(key_ba, TRUE);
1922 case AIRPDCAP_KEY_TYPE_WPA_PWD:
1924 tokens = g_strsplit(input_string,":",0);
1926 /* Tokens is a null termiated array of strings ... */
1927 while(tokens[n] != NULL)
1932 /* Free the array of strings */
1938 * The first token is the key
1940 key = g_strdup(tokens[0]);
1943 /* Maybe there is a second token (an ssid, if everything else is ok) */
1946 ssid = g_strdup(tokens[1]);
1949 /* Create a new string */
1950 key_string = g_string_new(key);
1953 /* Two (or more) tokens mean that the user entered a WPA-PWD key ... */
1954 if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
1956 g_string_free(key_string, TRUE);
1961 /* Free the array of strings */
1966 if(ssid != NULL) /* more than two tokens found, means that the user specified the ssid */
1968 ssid_ba = g_byte_array_new();
1969 if (! uri_str_to_bytes(ssid, ssid_ba)) {
1970 g_string_free(key_string, TRUE);
1971 g_byte_array_free(ssid_ba, TRUE);
1974 /* Free the array of strings */
1979 if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
1981 g_string_free(key_string, TRUE);
1982 g_byte_array_free(ssid_ba, TRUE);
1987 /* Free the array of strings */
1993 /* Key was correct!!! Create the new decryption_key_t ... */
1994 dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1996 dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
1997 dk->key = g_string_new(key);
1998 dk->bits = 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
1999 dk->ssid = byte_array_dup(ssid_ba); /* NULL if ssid_ba is NULL */
2001 g_string_free(key_string, TRUE);
2002 if (ssid_ba != NULL)
2003 g_byte_array_free(ssid_ba, TRUE);
2009 /* Free the array of strings */
2013 case AIRPDCAP_KEY_TYPE_WPA_PSK:
2015 key_ba = g_byte_array_new();
2016 res = hex_str_to_bytes(input_string, key_ba, FALSE);
2018 /* Two tokens means that the user should have entered a WPA-BIN key ... */
2019 if(!res || ((key_ba->len) != WPA_PSK_KEY_SIZE))
2021 g_byte_array_free(key_ba, TRUE);
2023 /* No ssid has been created ... */
2027 /* Key was correct!!! Create the new decryption_key_t ... */
2028 dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
2030 dk->type = AIRPDCAP_KEY_TYPE_WPA_PSK;
2031 dk->key = g_string_new(input_string);
2032 dk->bits = (guint) dk->key->len * 4;
2035 g_byte_array_free(key_ba, TRUE);
2039 /* Type not supported */
2044 * Returns a newly allocated string representing the given decryption_key_t
2045 * struct, or NULL if something is wrong...
2048 get_key_string(decryption_key_t* dk)
2050 gchar* output_string = NULL;
2052 if(dk == NULL || dk->key == NULL)
2056 case AIRPDCAP_KEY_TYPE_WEP:
2057 output_string = g_strdup(dk->key->str);
2059 case AIRPDCAP_KEY_TYPE_WPA_PWD:
2060 if(dk->ssid == NULL)
2061 output_string = g_strdup(dk->key->str);
2063 output_string = g_strdup_printf("%s:%s",
2064 dk->key->str, format_uri(dk->ssid, ":"));
2066 case AIRPDCAP_KEY_TYPE_WPA_PMK:
2067 output_string = g_strdup(dk->key->str);
2073 return output_string;
2080 /****************************************************************************/
2088 * indent-tabs-mode: nil
2091 * ex: set shiftwidth=4 tabstop=8 expandtab:
2092 * :indentSize=4:tabSize=8:noTabs=true: