[airpcap] Decrypt protected management frames (802.11w)
authorCedric Izoard <cedric.izoard@ceva-dsp.com>
Mon, 11 Jan 2016 13:37:09 +0000 (14:37 +0100)
committerMichael Mann <mmann78@netscape.net>
Wed, 13 Jan 2016 03:44:26 +0000 (03:44 +0000)
Enable decryption of Protected Management Frames by:
 - Authorizing decryption for robust management frame (i.e. management
   frame that may be encrypted): deauth, disassoc and action
   (Note: Assume all action frames are robust even if it is not the case)
 - Updating initialization of Additional Authentication Data (AAD)
   (don't filter-out subtype) and construct nonce (set mgmt flag) for
   management frames

Bug: 11995
Change-Id: I7c34a021e4c49111b85d217c9272d24d0e29ecb2
Reviewed-on: https://code.wireshark.org/review/13232
Reviewed-by: Michael Mann <mmann78@netscape.net>
epan/crypt/airpdcap.c
epan/crypt/airpdcap_ccmp.c
epan/crypt/airpdcap_int.h

index b976662a398bb4007f4d23db5384a814f4117833..5b5dfb3c5007eb231382ca97bef48cf0f9541117 100644 (file)
@@ -661,9 +661,13 @@ INT AirPDcapPacketProcess(
         return AIRPDCAP_RET_REQ_DATA;
     }
 
-    /* check if the packet is of data type */
-    if (AIRPDCAP_TYPE(data[0])!=AIRPDCAP_TYPE_DATA) {
-        AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
+    /* check if the packet is of data or robust managment type */
+    if (!((AIRPDCAP_TYPE(data[0])==AIRPDCAP_TYPE_DATA) ||
+          (AIRPDCAP_TYPE(data[0])==AIRPDCAP_TYPE_MANAGEMENT &&
+           (AIRPDCAP_SUBTYPE(data[0])==AIRPDCAP_SUBTYPE_DISASS ||
+            AIRPDCAP_SUBTYPE(data[0])==AIRPDCAP_SUBTYPE_DEAUTHENTICATION ||
+            AIRPDCAP_SUBTYPE(data[0])==AIRPDCAP_SUBTYPE_ACTION)))) {
+        AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data nor robust mgmt packet", AIRPDCAP_DEBUG_LEVEL_5);
         return AIRPDCAP_RET_NO_DATA;
     }
 
@@ -682,7 +686,11 @@ INT AirPDcapPacketProcess(
     /* get BSSID */
     if ( (addr=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
         memcpy(id.bssid, addr, AIRPDCAP_MAC_LEN);
+#ifdef _DEBUG
+        g_snprintf(msgbuf, MSGBUF_LEN, "BSSID_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
+                   id.bssid[0],id.bssid[1],id.bssid[2],id.bssid[3],id.bssid[4],id.bssid[5]);
         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
+#endif
     } else {
         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
         return AIRPDCAP_RET_REQ_DATA;
@@ -691,7 +699,11 @@ INT AirPDcapPacketProcess(
     /* get STA address */
     if ( (addr=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
         memcpy(id.sta, addr, AIRPDCAP_MAC_LEN);
+#ifdef _DEBUG
+        g_snprintf(msgbuf, MSGBUF_LEN, "STA_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
+                   id.sta[0],id.sta[1],id.sta[2],id.sta[3],id.sta[4],id.sta[5]);
         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
+#endif
     } else {
         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
         return AIRPDCAP_RET_REQ_DATA;
@@ -1590,11 +1602,11 @@ AirPDcapStoreSa(
  * key caching.  In each case, it's more important to return a value than
  * to return a _correct_ value, so we fudge addresses in some cases, e.g.
  * the BSSID in bridged connections.
- * FromDS    ToDS    Sta    BSSID
- * 0         0       addr2  addr3
- * 0         1       addr2  addr1
- * 1         0       addr1  addr2
- * 1         1       addr2  addr1
+ * FromDS    ToDS   Sta      BSSID
+ * 0         0      addr1/2  addr3
+ * 0         1      addr2    addr1
+ * 1         0      addr1    addr2
+ * 1         1      addr2    addr1
  */
 
 static const UCHAR *
@@ -1603,6 +1615,10 @@ AirPDcapGetStaAddress(
 {
     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
         case 0:
+            if (memcmp(frame->addr2, frame->addr3, AIRPDCAP_MAC_LEN) == 0)
+                return frame->addr1;
+            else
+                return frame->addr2;
         case 1:
             return frame->addr2;
         case 2:
index cedfe423e2bcd9db0d0a78457128991a759c1a40..ac27c26181c7ddce75d6936ba4e77a10314710e5 100644 (file)
@@ -112,6 +112,7 @@ static void ccmp_init_blocks(
        UINT8 a[AES_BLOCK_LEN],
        UINT8 b[AES_BLOCK_LEN])
 {
+       UINT8 mgmt = (AIRPDCAP_TYPE(wh->fc[0]) == AIRPDCAP_TYPE_MANAGEMENT);
 #define IS_4ADDRESS(wh) \
        ((wh->fc[1] & AIRPDCAP_FC1_DIR_MASK) == AIRPDCAP_FC1_DIR_DSTODS)
 #define IS_QOS_DATA(wh) AIRPDCAP_QOS_HAS_SEQ(wh)
@@ -144,7 +145,10 @@ static void ccmp_init_blocks(
        */
        aad[0] = 0;     /* AAD length >> 8 */
        /* NB: aad[1] set below */
-       aad[2] = (UINT8)(wh->fc[0] & 0x8f);    /* XXX magic #s */
+       if (!mgmt)
+               aad[2] = (UINT8)(wh->fc[0] & 0x8f);    /* XXX magic #s */
+       else
+               aad[2] = wh->fc[0];
        aad[3] = (UINT8)(wh->fc[1] & 0xc7);    /* XXX magic #s */
        /* NB: we know 3 addresses are contiguous */
        memcpy(aad + 4, &wh->addr1[0], 3 * AIRPDCAP_MAC_LEN);
@@ -188,6 +192,8 @@ static void ccmp_init_blocks(
                        b0[1] = 0;
                        aad[1] = 22;
                }
+               if (mgmt)
+                       b0[1] |= 0x10; /* set MGMT flag */
                memset(&aad[26], 0, 4);
        }
 
index e0d3f1ea9537a63d3c7faecb1ccbfe034a8a1c62..ec69aece0c06eff66593cfaf49d052225efd85d2 100644 (file)
 #define        AIRPDCAP_TYPE_CONTROL                   1
 #define        AIRPDCAP_TYPE_DATA                      2
 
-/* Min length of encrypted data (TKIP=25bytes, CCMP=21bytes)                   */
-#define        AIRPDCAP_CRYPTED_DATA_MINLEN    21
+/* IEEE 802.11 packet subtype values                                           */
+#define AIRPDCAP_SUBTYPE_ASSOC_REQ             0
+#define AIRPDCAP_SUBTYPE_ASSOC_RESP            1
+#define AIRPDCAP_SUBTYPE_REASSOC_REQ           2
+#define AIRPDCAP_SUBTYPE_REASSOC_RESP          3
+#define AIRPDCAP_SUBTYPE_PROBE_REQ             4
+#define AIRPDCAP_SUBTYPE_PROBE_RESP            5
+#define AIRPDCAP_SUBTYPE_MEASUREMENT_PILOT     6
+#define AIRPDCAP_SUBTYPE_BEACON                        8
+#define AIRPDCAP_SUBTYPE_ATIM                  9
+#define AIRPDCAP_SUBTYPE_DISASS                        10
+#define AIRPDCAP_SUBTYPE_AUTHENTICATION                11
+#define AIRPDCAP_SUBTYPE_DEAUTHENTICATION      12
+#define AIRPDCAP_SUBTYPE_ACTION                        13
+#define AIRPDCAP_SUBTYPE_ACTION_NO_ACK         14
+
+/* Min length of encrypted data (TKIP=21bytes, CCMP=17bytes)                   */
+#define        AIRPDCAP_CRYPTED_DATA_MINLEN    17
 
 #define AIRPDCAP_TA_OFFSET     10