diff options
Diffstat (limited to 'epan/crypt')
-rw-r--r-- | epan/crypt/airpdcap.c | 109 | ||||
-rw-r--r-- | epan/crypt/airpdcap_ccmp.c | 3 | ||||
-rw-r--r-- | epan/crypt/airpdcap_int.h | 7 | ||||
-rw-r--r-- | epan/crypt/airpdcap_system.h | 69 |
4 files changed, 71 insertions, 117 deletions
diff --git a/epan/crypt/airpdcap.c b/epan/crypt/airpdcap.c index 2b4123e8ed..c986e1ac79 100644 --- a/epan/crypt/airpdcap.c +++ b/epan/crypt/airpdcap.c @@ -151,21 +151,21 @@ static INT AirPDcapRsnaPwd2Psk( static INT AirPDcapRsnaMng( UCHAR *decrypt_data, - size_t *decrypt_len, + guint mac_header_len, + guint *decrypt_len, PAIRPDCAP_KEY_ITEM key, AIRPDCAP_SEC_ASSOCIATION *sa, - INT offset, - UINT8 fcsPresent) + INT offset) ; static INT AirPDcapWepMng( PAIRPDCAP_CONTEXT ctx, UCHAR *decrypt_data, - size_t *decrypt_len, + guint mac_header_len, + guint *decrypt_len, PAIRPDCAP_KEY_ITEM key, AIRPDCAP_SEC_ASSOCIATION *sa, - INT offset, - UINT8 fcsPresent) + INT offset) ; static INT AirPDcapRsna4WHandshake( @@ -245,24 +245,22 @@ extern "C" { INT AirPDcapPacketProcess( PAIRPDCAP_CONTEXT ctx, - const UCHAR *data, - const size_t len, + const guint8 *data, + const guint mac_header_len, + const guint tot_len, UCHAR *decrypt_data, - size_t *decrypt_len, + guint *decrypt_len, PAIRPDCAP_KEY_ITEM key, - UINT8 fcsPresent, - UINT8 radioTapPresent, - UINT8 mngHandshake, - UINT8 mngDecrypt) + gboolean mngHandshake, + gboolean mngDecrypt) { - size_t mac_header_len; const UCHAR *address; AIRPDCAP_SEC_ASSOCIATION_ID id; - INT index; + int index; PAIRPDCAP_SEC_ASSOCIATION sa; - INT offset; - UINT16 bodyLength; - const UCHAR dot1x_header[] = { + int offset = 0; + guint bodyLength; + const guint8 dot1x_header[] = { 0xAA, /* DSAP=SNAP */ 0xAA, /* SSAP=SNAP */ 0x03, /* Control field=Unnumbered frame */ @@ -281,33 +279,26 @@ INT AirPDcapPacketProcess( AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess"); return AIRPDCAP_RET_UNSUCCESS; } - if (data==NULL || len==0) { + if (data==NULL || tot_len==0) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5); AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess"); return AIRPDCAP_RET_UNSUCCESS; } - if (radioTapPresent) - offset=AIRPDCAP_RADIOTAP_HEADER_LEN; - else - offset=0; - /* check if the packet is of data type */ - /* TODO consider packets send on an ad-hoc net (QoS) */ - if (AIRPDCAP_TYPE(data[offset])!=AIRPDCAP_TYPE_DATA) { + if (AIRPDCAP_TYPE(data[0])!=AIRPDCAP_TYPE_DATA) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5); return AIRPDCAP_RET_NO_DATA; } /* check correct packet size, to avoid wrong elaboration of encryption algorithms */ - mac_header_len=AIRPDCAP_HEADER_LEN(data[offset+1]); - if (len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) { + if (tot_len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5); return AIRPDCAP_RET_WRONG_DATA_SIZE; } /* get BSSID */ - if ( (address=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data+offset))) != NULL) { + if ( (address=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) { memcpy(id.bssid, address, AIRPDCAP_MAC_LEN); #ifdef _DEBUG 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]); @@ -319,7 +310,7 @@ INT AirPDcapPacketProcess( } /* get STA address */ - if ( (address=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data+offset))) != NULL) { + if ( (address=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) { memcpy(id.sta, address, AIRPDCAP_MAC_LEN); #ifdef _DEBUG 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]); @@ -342,7 +333,7 @@ INT AirPDcapPacketProcess( sa=&ctx->sa[index]; /* cache offset in the packet data (to scan encryption data) */ - offset+=AIRPDCAP_HEADER_LEN(data[offset+1]); + offset = mac_header_len; /* check if data is encrypted (use the WEP bit in the Frame Control field) */ if (AIRPDCAP_WEP(data[1])==0) @@ -373,7 +364,7 @@ INT AirPDcapPacketProcess( /* get and check the body length (IEEE 802.1X-2004, pg. 25) */ bodyLength=pntohs(data+offset+2); - if (((len-offset-4)!=bodyLength && !fcsPresent) || ((len-offset-8)!=bodyLength && fcsPresent)) { + if ((tot_len-offset-4) != bodyLength) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body not valid (wrong length)", AIRPDCAP_DEBUG_LEVEL_5); return AIRPDCAP_RET_NO_VALID_HANDSHAKE; } @@ -408,26 +399,22 @@ INT AirPDcapPacketProcess( return AIRPDCAP_RET_UNSUCCESS; /* create new header and data to modify */ - *decrypt_len=len; + *decrypt_len = tot_len; memcpy(decrypt_data, data, *decrypt_len); /* encrypted data */ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3); - if (fcsPresent) - /* remove from next computation FCS */ - *decrypt_len-=4; - /* check the Extension IV to distinguish between WEP encryption and WPA encryption */ /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP, */ /* IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP, */ /* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */ if (AIRPDCAP_EXTIV(data[offset+3])==0) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3); - return AirPDcapWepMng(ctx, decrypt_data, decrypt_len, key, sa, offset, fcsPresent); + return AirPDcapWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, sa, offset); } else { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3); - return AirPDcapRsnaMng(decrypt_data, decrypt_len, key, sa, offset, fcsPresent); + return AirPDcapRsnaMng(decrypt_data, mac_header_len, decrypt_len, key, sa, offset); } } } @@ -620,14 +607,13 @@ extern "C" { static INT AirPDcapRsnaMng( UCHAR *decrypt_data, - size_t *decrypt_len, + guint mac_header_len, + guint *decrypt_len, PAIRPDCAP_KEY_ITEM key, AIRPDCAP_SEC_ASSOCIATION *sa, - INT offset, - UINT8 fcsPresent) + INT offset) { INT ret_value; - ULONG crc; if (sa->key==NULL) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3); @@ -652,7 +638,7 @@ AirPDcapRsnaMng( /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */ AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3); - ret_value=AirPDcapCcmpDecrypt(decrypt_data, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk)); + ret_value=AirPDcapCcmpDecrypt(decrypt_data, mac_header_len, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk)); if (ret_value) return ret_value; @@ -665,19 +651,10 @@ AirPDcapRsnaMng( decrypt_data[1]&=0xBF; /* remove TKIP/CCMP header */ - offset=AIRPDCAP_HEADER_LEN(decrypt_data[1]); + offset = mac_header_len; *decrypt_len-=8; memcpy(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset); - if (fcsPresent) { - /* calculate FCS */ - crc = crc32_ccitt(decrypt_data, *decrypt_len); - memcpy(decrypt_data+*decrypt_len, &crc, sizeof crc); - - /* add FCS in packet */ - *decrypt_len+=4; - } - if (key!=NULL) { memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM)); @@ -694,16 +671,15 @@ static INT AirPDcapWepMng( PAIRPDCAP_CONTEXT ctx, UCHAR *decrypt_data, - size_t *decrypt_len, + guint mac_header_len, + guint *decrypt_len, PAIRPDCAP_KEY_ITEM key, AIRPDCAP_SEC_ASSOCIATION *sa, - INT offset, - UINT8 fcsPresent) + INT offset) { UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN]; size_t keylen; INT ret_value=1; - ULONG crc; INT key_index; AIRPDCAP_KEY_ITEM *tmp_key; UINT8 useCache=FALSE; @@ -735,14 +711,14 @@ AirPDcapWepMng( memcpy(try_data, decrypt_data, *decrypt_len); /* 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) */ - memcpy(wep_key, try_data+AIRPDCAP_HEADER_LEN(try_data[1]), AIRPDCAP_WEP_IVLEN); + memcpy(wep_key, try_data+mac_header_len, AIRPDCAP_WEP_IVLEN); keylen=tmp_key->KeyData.Wep.WepKeyLen; memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen); ret_value=AirPDcapWepDecrypt(wep_key, keylen+AIRPDCAP_WEP_IVLEN, - try_data + (AIRPDCAP_HEADER_LEN(try_data[1])+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN), - *decrypt_len-(AIRPDCAP_HEADER_LEN(try_data[1])+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN)); + try_data + (mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN), + *decrypt_len-(mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN)); if (ret_value == AIRPDCAP_RET_SUCCESS) memcpy(decrypt_data, try_data, *decrypt_len); @@ -781,19 +757,10 @@ AirPDcapWepMng( decrypt_data[1]&=0xBF; /* remove IC header */ - offset=AIRPDCAP_HEADER_LEN(decrypt_data[1]); + offset = mac_header_len; *decrypt_len-=4; memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset); - if (fcsPresent) { - /* calculate FCS and append it at the end of the decrypted packet */ - crc = crc32_ccitt(decrypt_data, *decrypt_len); - memcpy(decrypt_data+*decrypt_len, &crc, sizeof crc); - - /* add FCS in packet */ - *decrypt_len += 4; - } - return AIRPDCAP_RET_SUCCESS; } diff --git a/epan/crypt/airpdcap_ccmp.c b/epan/crypt/airpdcap_ccmp.c index 7205ab9442..f0ee8e3e64 100644 --- a/epan/crypt/airpdcap_ccmp.c +++ b/epan/crypt/airpdcap_ccmp.c @@ -208,6 +208,7 @@ static void ccmp_init_blocks( INT AirPDcapCcmpDecrypt( UINT8 *m, + gint mac_header_len, INT len, UCHAR TK1[16]) { @@ -219,7 +220,7 @@ INT AirPDcapCcmpDecrypt( UINT i; UINT8 *pos; UINT space; - INT z=AIRPDCAP_HEADER_LEN(m[1]); + INT z = mac_header_len; rijndael_ctx key; UINT64 PN; UINT8 *ivp=m+z; diff --git a/epan/crypt/airpdcap_int.h b/epan/crypt/airpdcap_int.h index 7747fbe49c..222e1e9cdd 100644 --- a/epan/crypt/airpdcap_int.h +++ b/epan/crypt/airpdcap_int.h @@ -60,13 +60,6 @@ /* Macro definitions */ /** - * Macro to get MAC header length (if ToDS and FromDS are set, address 4 - * is present). - */ -#define AIRPDCAP_HEADER_LEN(FrameControl_1) \ - (UINT8)((FrameControl_1 & 0x3)==3 ? 30 : 24) - -/** * Macros to get various bits of a 802.11 control frame */ #define AIRPDCAP_TYPE(FrameControl_0) (UINT8)((FrameControl_0 >> 2) & 0x3) diff --git a/epan/crypt/airpdcap_system.h b/epan/crypt/airpdcap_system.h index 96c0a46f99..5aeb77a37f 100644 --- a/epan/crypt/airpdcap_system.h +++ b/epan/crypt/airpdcap_system.h @@ -164,44 +164,37 @@ extern "C" { #endif /** - * It processes a packet and if necessary it tries to decrypt - * encrypted data. - * The packet received in input should be an 802.11 frame (composed by the - * MAC header, the frame body and the FCS -if specified-). If the data will - * be decrypted the FCS will be recomputed. The packet received could start - * with a RadioTap header. - * @param ctx [IN] pointer to the current context - * @param data [IN] pointer to a buffer with packet data - * @param len [IN] packet data length; this should be the capture packet - * length (to avoid errors in processing) - * @param decrypt_data [OUT] pointer to a buffer that will contain - * decrypted data - * @param decrypt_len [OUT] length of decrypted data - * @param key [OUT] pointer to a preallocated key structure containing - * the key used during the decryption process (if done). If this parameter - * is set to NULL, the key will be not returned. - * @param fcsPresent [IN] flag that specifies if the FCS is present in - * the packet or not (0 when the FCS is not present, 1 when it is). - * @param radioTapPresent [IN] flag that specifies if a RadioTap header - * is present or not (0 when the header is no present, 1 when it is). - * @param mngHandshake [IN] if TRUE this function will manage the 4-way - * handshake for WPA/WPA2 - * @param mngDecrypt [IN] if TRUE this function will manage the WEP or + * Given an 802.11 packet, either extract its key data (in the case of + * WPA handshaking) or try to decrypt it. + * @param ctx [IN] Pointer to the current context + * @param data [IN] Pointer to a buffer with an 802.11 frame, including MAC + * header and payload + * @param data_off [IN] Payload offset (aka the MAC header length) + * @param data_len [IN] Total length of the MAC header and the payload + * @param decrypt_data [OUT] Pointer to a buffer that will contain + * decrypted data + * @param decrypt_len [OUT] Length of decrypted data + * @param key [OUT] Pointer to a preallocated key structure containing + * the key used during the decryption process (if done). If this parameter + * is set to NULL, the key will be not returned. + * @param mngHandshake [IN] If TRUE this function will manage the 4-way + * handshake for WPA/WPA2 + * @param mngDecrypt [IN] If TRUE this function will manage the WEP or * WPA/WPA2 decryption * @return - * - AIRPDCAP_RET_SUCCESS: decryption has been done (decrypt_data and + * - AIRPDCAP_RET_SUCCESS: Decryption has been done (decrypt_data and * decrypt_length will contain the packet data decrypted and the lenght of * the new packet) - * - AIRPDCAP_RET_SUCCESS_HANDSHAKE: a step of the 4-way handshake for + * - AIRPDCAP_RET_SUCCESS_HANDSHAKE: A step of the 4-way handshake for * WPA key has been successfully done - * - AIRPDCAP_RET_NO_DATA: the packet is not a data packet - * - AIRPDCAP_RET_WRONG_DATA_SIZE: the size of the packet is below the + * - AIRPDCAP_RET_NO_DATA: The packet is not a data packet + * - AIRPDCAP_RET_WRONG_DATA_SIZE: The size of the packet is below the * accepted minimum - * - AIRPDCAP_RET_REQ_DATA: required data is not available and the + * - AIRPDCAP_RET_REQ_DATA: Required data is not available and the * processing must be interrupted - * - AIRPDCAP_RET_NO_VALID_HANDSHAKE: the authentication is not for WPA or RSNA - * - AIRPDCAP_RET_NO_DATA_ENCRYPTED: no encrypted data - * - AIRPDCAP_RET_UNSUCCESS: no decryption has been done (decrypt_data + * - AIRPDCAP_RET_NO_VALID_HANDSHAKE: The authentication is not for WPA or RSNA + * - AIRPDCAP_RET_NO_DATA_ENCRYPTED: No encrypted data + * - AIRPDCAP_RET_UNSUCCESS: No decryption has been done (decrypt_data * and decrypt_length will be not modified). * Some other errors could be: * data not correct @@ -225,15 +218,14 @@ extern "C" { */ extern INT AirPDcapPacketProcess( PAIRPDCAP_CONTEXT ctx, - const UCHAR *data, - const size_t len, + const guint8 *data, + const guint data_off, + const guint data_len, UCHAR *decrypt_data, - size_t *decrypt_len, + guint32 *decrypt_len, PAIRPDCAP_KEY_ITEM key, - UINT8 fcsPresent, - UINT8 radioTapPresent, - UINT8 mngHandshake, - UINT8 mngDecrypt) + gboolean mngHandshake, + gboolean mngDecrypt) ; /** @@ -357,6 +349,7 @@ extern INT AirPDcapWepDecrypt( ; extern INT AirPDcapCcmpDecrypt( UINT8 *m, + gint mac_header_len, INT len, UCHAR TK1[16]) ; |