diff options
Diffstat (limited to 'epan/crypt/dot11decrypt_ccmp_compat.c')
-rw-r--r-- | epan/crypt/dot11decrypt_ccmp_compat.c | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/epan/crypt/dot11decrypt_ccmp_compat.c b/epan/crypt/dot11decrypt_ccmp_compat.c deleted file mode 100644 index 95f95b3d9b..0000000000 --- a/epan/crypt/dot11decrypt_ccmp_compat.c +++ /dev/null @@ -1,262 +0,0 @@ -/* dot11decrypt_ccmp_compat.c - * - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2006 CACE Technologies, Davis (California) - * All rights reserved. - * - * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) - */ - -/* - * This file is only used for backwards compatibility with libgcrypt - * versions < 1.6.0 that don't support AEAD. When building towards later - * versions dot11decrypt_ccmp.c file is used instead - */ - -/* - * Note: This file was derived from the FreeBSD source code, RELENG 6, - * sys/net80211/ieee80211_crypto_ccmp.c - */ - -/****************************************************************************/ -/* File includes */ -#include "config.h" -#include "dot11decrypt_system.h" -#include "dot11decrypt_int.h" - -#include "dot11decrypt_debug.h" -#include <glib.h> -#include <wsutil/wsgcrypt.h> - -/****************************************************************************/ -/* Internal definitions */ - -#define AES_BLOCK_LEN 16 - -#define FC1_AAD_MASK 0xc7 -#define FC1_AAD_QOS_MASK 0x47 - -/****************************************************************************/ -/* Internal macros */ - -#define XOR_BLOCK(b, a, len) { \ - INT __i__; \ - for (__i__ = 0; __i__ < (INT)(len); __i__++) \ - (b)[__i__] ^= (a)[__i__]; \ -} - -#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len) { \ - /* Decrypt, with counter */ \ - _b0[14] = (UINT8)((_i >> 8) & 0xff); \ - _b0[15] = (UINT8)(_i & 0xff); \ - gcry_cipher_encrypt(rijndael_handle, _b, AES_BLOCK_LEN, _b0, AES_BLOCK_LEN); \ - XOR_BLOCK(_pos, _b, _len); \ - /* Authentication */ \ - XOR_BLOCK(_a, _pos, _len); \ - gcry_cipher_encrypt(rijndael_handle, _a, AES_BLOCK_LEN, NULL, 0); \ -} - -#define READ_6(b0, b1, b2, b3, b4, b5) \ - ((((UINT64)((UINT16)((b4 << 0) | (b5 << 8)))) << 32) | \ - ((UINT32)((b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24)))) - -/****************************************************************************/ -/* Internal function prototypes declarations */ - -static void ccmp_init_blocks( - gcry_cipher_hd_t rijndael_handle, - PDOT11DECRYPT_MAC_FRAME wh, - UINT64 pn, - size_t dlen, - UINT8 b0[AES_BLOCK_LEN], - UINT8 aad[2 * AES_BLOCK_LEN], - UINT8 a[AES_BLOCK_LEN], - UINT8 b[AES_BLOCK_LEN]) - ; - -/****************************************************************************/ -/* Function definitions */ - -static void ccmp_init_blocks( - gcry_cipher_hd_t rijndael_handle, - PDOT11DECRYPT_MAC_FRAME wh, - UINT64 pn, - size_t dlen, - UINT8 b0[AES_BLOCK_LEN], - UINT8 aad[2 * AES_BLOCK_LEN], - UINT8 a[AES_BLOCK_LEN], - UINT8 b[AES_BLOCK_LEN]) -{ - UINT8 mgmt = (DOT11DECRYPT_TYPE(wh->fc[0]) == DOT11DECRYPT_TYPE_MANAGEMENT); - - memset(aad, 0, 2*AES_BLOCK_LEN); - - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen */ - b0[0] = 0x59; - /* NB: b0[1] set below */ - DOT11DECRYPT_ADDR_COPY(b0 + 2, wh->addr2); - b0[8] = (UINT8)(pn >> 40); - b0[9] = (UINT8)(pn >> 32); - b0[10] = (UINT8)(pn >> 24); - b0[11] = (UINT8)(pn >> 16); - b0[12] = (UINT8)(pn >> 8); - b0[13] = (UINT8)(pn >> 0); - b0[14] = (UINT8)((UINT8)(dlen >> 8) & 0xff); - b0[15] = (UINT8)(dlen & 0xff); - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one; 15 zero when QoS Control field present - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - aad[0] = 0; /* AAD length >> 8 */ - /* NB: aad[1] set below */ - if (!mgmt) - aad[2] = (UINT8)(wh->fc[0] & 0x8f); /* XXX magic #s */ - else - aad[2] = wh->fc[0]; - if (DOT11DECRYPT_IS_QOS_DATA(wh)) { - aad[3] = (UINT8)((wh->fc[1] & FC1_AAD_QOS_MASK) | 0x40); - } else { - aad[3] = (UINT8)((wh->fc[1] & FC1_AAD_MASK) | 0x40); - } - - /* NB: we know 3 addresses are contiguous */ - memcpy(aad + 4, (guint8 *)wh->addr1, 3 * DOT11DECRYPT_MAC_LEN); - aad[22] = (UINT8)(wh->seq[0] & DOT11DECRYPT_SEQ_FRAG_MASK); - aad[23] = 0; /* all bits masked */ - /* - * Construct variable-length portion of AAD based - * on whether this is a 4-address frame/QOS frame. - * We always zero-pad to 32 bytes before running it - * through the cipher. - * - * We also fill in the priority bits of the CCM - * initial block as we know whether or not we have - * a QOS frame. - */ - if (DOT11DECRYPT_IS_4ADDRESS(wh)) { - DOT11DECRYPT_ADDR_COPY(aad + 24, - ((PDOT11DECRYPT_MAC_FRAME_ADDR4)wh)->addr4); - if (DOT11DECRYPT_IS_QOS_DATA(wh)) { - PDOT11DECRYPT_MAC_FRAME_ADDR4_QOS qwh4 = - (PDOT11DECRYPT_MAC_FRAME_ADDR4_QOS) wh; - aad[30] = (UINT8)(qwh4->qos[0] & 0x0f);/* just priority bits */ - aad[31] = 0; - b0[1] = aad[30]; - aad[1] = 22 + DOT11DECRYPT_MAC_LEN + 2; - } else { - memset(&aad[30], 0, 2); - b0[1] = 0; - aad[1] = 22 + DOT11DECRYPT_MAC_LEN; - } - } else { - if (DOT11DECRYPT_IS_QOS_DATA(wh)) { - PDOT11DECRYPT_MAC_FRAME_QOS qwh = - (PDOT11DECRYPT_MAC_FRAME_QOS) wh; - aad[24] = (UINT8)(qwh->qos[0] & 0x0f); /* just priority bits */ - aad[25] = 0; - b0[1] = aad[24]; - aad[1] = 22 + 2; - } else { - memset(&aad[24], 0, 2); - b0[1] = 0; - aad[1] = 22; - } - if (mgmt) - b0[1] |= 0x10; /* set MGMT flag */ - memset(&aad[26], 0, 4); - } - - /* Start with the first block and AAD */ - gcry_cipher_encrypt(rijndael_handle, a, AES_BLOCK_LEN, b0, AES_BLOCK_LEN); - XOR_BLOCK(a, aad, AES_BLOCK_LEN); - gcry_cipher_encrypt(rijndael_handle, a, AES_BLOCK_LEN, NULL, 0); - XOR_BLOCK(a, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - gcry_cipher_encrypt(rijndael_handle, a, AES_BLOCK_LEN, NULL, 0); - b0[0] &= 0x07; - b0[14] = b0[15] = 0; - gcry_cipher_encrypt(rijndael_handle, b, AES_BLOCK_LEN, b0, AES_BLOCK_LEN); - - /** //XOR( m + len - 8, b, 8 ); **/ -} - -int Dot11DecryptCcmpDecrypt( - guint8 *m, - int mac_header_len, - int len, - guint8 *TK1, - int tk_len, - int mic_len) -{ - PDOT11DECRYPT_MAC_FRAME wh; - UINT8 aad[2 * AES_BLOCK_LEN]; - UINT8 b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN], a[AES_BLOCK_LEN]; - UINT8 mic[AES_BLOCK_LEN]; - ssize_t data_len; - UINT i; - UINT8 *pos; - UINT space; - INT z = mac_header_len; - gcry_cipher_hd_t rijndael_handle; - UINT64 PN; - UINT8 *ivp=m+z; - - if (tk_len > 16 || mic_len > 8) { - /* NOT SUPPORTED*/ - return 1; - } - - PN = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]); - - if (gcry_cipher_open(&rijndael_handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)) { - return 1; - } - if (gcry_cipher_setkey(rijndael_handle, TK1, 16)) { - gcry_cipher_close(rijndael_handle); - return 1; - } - - wh = (PDOT11DECRYPT_MAC_FRAME )m; - data_len = len - (z + DOT11DECRYPT_CCMP_HEADER+DOT11DECRYPT_CCMP_TRAILER); - if (data_len < 1) { - gcry_cipher_close(rijndael_handle); - return 0; - } - ccmp_init_blocks(rijndael_handle, wh, PN, data_len, b0, aad, a, b); - memcpy(mic, m+len-DOT11DECRYPT_CCMP_TRAILER, DOT11DECRYPT_CCMP_TRAILER); - XOR_BLOCK(mic, b, DOT11DECRYPT_CCMP_TRAILER); - - i = 1; - pos = (UINT8 *)m + z + DOT11DECRYPT_CCMP_HEADER; - space = len - (z + DOT11DECRYPT_CCMP_HEADER); - - if (space > data_len) - space = (UINT)data_len; - while (space >= AES_BLOCK_LEN) { - CCMP_DECRYPT(i, b, b0, pos, a, AES_BLOCK_LEN); - pos += AES_BLOCK_LEN; - space -= AES_BLOCK_LEN; - i++; - } - - if (space != 0) /* short last block */ - CCMP_DECRYPT(i, b, b0, pos, a, space); - - gcry_cipher_close(rijndael_handle); - /* MIC Key ?= MIC */ - if (memcmp(mic, a, DOT11DECRYPT_CCMP_TRAILER) == 0) { - return 0; - } - - /* TODO replay check (IEEE 802.11i-2004, pg. 62) */ - /* TODO PN must be incremental (IEEE 802.11i-2004, pg. 62) */ - - return 1; -} |