📄 wep.c
字号:
/* wep.c: handles decryption for wlandump* --------------------------------------------------------------------** Linux WLAN ** The contents of this file are subject to the Mozilla Public* License Version 1.0 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.mozilla.org/MPL/** Software distributed under the License is distributed on an "AS* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** The initial developer of the original code is Mark S. Mathews* <mark@absoval.com>. Portions created by Mark S. Mathews* are Copyright (C) 1998 AbsoluteValue Software, Inc. All Rights Reserved.* * --------------------------------------------------------------------** The author may be reached as mark@absoval.com, or C/O AbsoluteValue* Software Inc., P.O. Box 941149, Maitland, FL, 32794-1149** Thanks to David Hinds, Donald Becker, and the rest of the Linux* developers worldwide for making all of this possible.** --------------------------------------------------------------------**/#include <stdlib.h>#include <stdio.h>#include <wlan/wlan_compat.h>#include <wlan/version.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/am930mib.h>#include <wlan/wlan_ioctl.h>#include "wlandump.h"#define WLAN_CRC32_POLY_LE (0xedb88320UL)#define WLAN_CRC32_POLY_BE (0x04c11db7UL)#define WLAN_WEP_FULLKEYLEN 8#define WLAN_WEP_SBOXLEN 256#define WLAN_WEP_SWAP(a,b) { UINT8 c; c = (a); (a) = (b); (b) = (c); }typedef struct wlan_wepprng{ UINT8 s[WLAN_WEP_SBOXLEN]; UINT i; UINT j;} wlan_wepprng_t;UINT32 crc32_table[256];static UINT32 wlandump_crc32_block(UINT32 reg, UINT8 *p, UINT len);static UINT32 wlandump_crc32_blockfinish(UINT32 reg);static void wlandump_wep_initprng( wlan_wepprng_t *prng, UINT8 *k, UINT klen);static void wlandump_wep_block( wlan_wepprng_t *prng, UINT8 *d, UINT dlen);#ifdef NOTUSED /* we're not using it right now, ifdef'd to stop warning */ static UINT8 wlandump_wep_nextprn( wlan_wepprng_t *prng);#endif/*----------------------------------------------------------------* wlandump_wep_initprng** Initializes the WEP Psuedo-Random number generator using a* given seed. The seed is usually the private key.* Arguments:* prng - a structure, allocated by the caller, that will * maintain state information during the use of this* prng.* k - an array of bytes containing the seed* klen - length of seed* * returns: nothing----------------------------------------------------------------*/void wlandump_wep_initprng( wlan_wepprng_t *prng, UINT8 *k, UINT klen){ UINT i; UINT j; for ( i = 0; i < WLAN_WEP_SBOXLEN; i++ ) { prng->s[i] = i; } prng->i = prng->j = 0; j = 0; for ( i = 0; i < WLAN_WEP_SBOXLEN; i++) { j = (j + prng->s[i] + k[i % klen]) % WLAN_WEP_SBOXLEN; WLAN_WEP_SWAP( prng->s[i], prng->s[j] ); }}/*----------------------------------------------------------------* wlandump_wep_nextprn** Retrieves the next value from a prng initialized with* wep_prng.* Arguments:* prng - a prng structure previosly initialized with* wep_initprng.* * returns: next psuedo-random number----------------------------------------------------------------*/#ifdef NOTUSED /* we're not using it right now, ifdef'd to stop warning */UINT8 wlandump_wep_nextprn( wlan_wepprng_t *prng){ UINT i; UINT j; UINT t; UINT8 *s; s = prng->s; i = (prng->i + 1) % WLAN_WEP_SBOXLEN; j = (prng->j + s[i]) % WLAN_WEP_SBOXLEN; WLAN_WEP_SWAP( s[i], s[j] ); t = (s[i] + s[j]) % WLAN_WEP_SBOXLEN; prng->i = i; prng->j = j; return s[t];}#endif/*----------------------------------------------------------------* wlandump_wep_block** WEP encrypts a block of bytes in place.* Arguments:* prng - a prng structure previosly initialized with* wep_initprng.* d - ptr to the block of bytes to be encrypted.* dlen - length of the block* * returns: nothing----------------------------------------------------------------*/void wlandump_wep_block( wlan_wepprng_t *prng, UINT8 *d, UINT dlen){ UINT i; UINT j; UINT t; UINT8 *s; UINT index = dlen; UINT8 *data = d; WLAN_LOG_DEBUG2(3,"d=0x%lx dlen=%u\n", (UINT32)d, dlen); s = prng->s; i = prng->i; j = prng->j; WLAN_HEX_DUMP(3, "prewep (payload only):", d, dlen); while( index ) { i = (i + 1) % WLAN_WEP_SBOXLEN; j = (j + s[i]) % WLAN_WEP_SBOXLEN; WLAN_WEP_SWAP( s[i], s[j] ); t = (s[i] + s[j]) % WLAN_WEP_SBOXLEN; *data ^= s[t]; data++; index--; } prng->i = i; prng->j = j; WLAN_HEX_DUMP(3, "postwep (payload only):", d, dlen); return;}/*----------------------------------------------------------------* wlandump_wep_decrypt** Inspects the given frame, if it doesn't require decryption* leave it along. If the frame does require decryption, check* to see that we set up for decryption. If we're not set up* for decryption, print an error. If the frame* needs decryption _and_ we support and are configured for it,* decrypt the frame inside the given buffer and return it to the * caller.* Arguments:* f - frame buffer* len - length of frame in buffer* * returns: * nothing----------------------------------------------------------------*/void wlandump_wep_decrypt( UINT8 *f, UINT16 len){ UINT8 key[WLAN_WEP_FULLKEYLEN]; wlan_wepprng_t prng; UINT32 crc32 = 0xffffffffUL; UINT8 keyid; p80211_hdr_t *phdr; DBFENTER; if ( !opt_wepkeyset ) { fprintf(stderr, "%s: trying to decrypt frame but no keys set!\n", appname); return; } phdr = (p80211_hdr_t*)f; if ( !WLAN_GET_FC_ISWEP(phdr->a3.fc) ) /* frame not encrypted, do nothing */ { return; } /* make the key and init the prng */ keyid = (f + WLAN_HDR_A3_LEN)[3]; keyid = keyid >> 6; memcpy(key, f + WLAN_HDR_A3_LEN, 3);/* TODO: change this so the decryption is done in a separate buffer */ /* decrypt the body and the icv */ memcpy(key+3, wep_key[keyid], WLAN_WEP_KEYLEN); wlandump_wep_initprng( &prng, key, WLAN_WEP_FULLKEYLEN); wlandump_wep_block( &prng, f + WLAN_HDR_A3_LEN + WLAN_WEP_IV_LEN, len - WLAN_HDR_A3_LEN - WLAN_WEP_IV_LEN - WLAN_FCS_LEN); /* check for undecryptable */ crc32 = wlandump_crc32_block( crc32, f + WLAN_HDR_A3_LEN + WLAN_WEP_IV_LEN, len - WLAN_HDR_A3_LEN - WLAN_WEP_IV_LEN - WLAN_WEP_ICV_LEN - WLAN_FCS_LEN); crc32 = wlandump_crc32_blockfinish(crc32); if ( crc32 != ieee2host32(*((UINT32*)(f + len - WLAN_WEP_ICV_LEN - WLAN_FCS_LEN))) ) { printf("Undecryptable "); } DBFEXIT; return;}/*----------------------------------------------------------------* wlandump_crc32_block** Calculate the crc over a block of bytes. To get the final crc value,* don't forget to call crc32_blockfinish.* Arguments: * reg initial accumulator value, passing it in allows us to * crc non-contiguous blocks. On the first call to this * function for a given crc calculation, reg should be* 0xffffffffUL.* p ptr to the block* len size of block* returns: * crc32 value----------------------------------------------------------------*/UINT32 wlandump_crc32_block(UINT32 reg, UINT8 *p, UINT len){ while(len) { reg = crc32_table[(reg ^ *p) & 0x000000ffUL] ^ (reg >> 8); len--; p++; } return reg;}UINT32 wlandump_crc32_blockfinish(UINT32 reg){ return reg ^ 0xffffffffUL;}/*----------------------------------------------------------------* wlandump_crc32_accum** Accumulates, in a given register, the crc of a series of bytes* passed to this function.* Arguments: * reg current accumulated crc value* d next byte in series* returns: * new accumulated crc32 value----------------------------------------------------------------*/#ifdef NOTUSED /* we're not using it right now, ifdef'd to stop warning */UINT32 wlandump_crc32_accum(UINT32 reg, UINT8 d){ reg = crc32_table[(reg ^ d) & 0x000000ffUL] ^ (reg >> 8); return reg;}#endif/*----------------------------------------------------------------* wlandump_crc32_mktable** Constructs the table used for the crc32 calculation.* Arguments: none* returns: nothing----------------------------------------------------------------*/void wlandump_crc32_mktable(void){ UINT i; UINT k; UINT32 c; crc32_table[0] = 0; for ( i = 1; i < 256; i++) { c = 0; for ( k = i | 256; k != 1; k >>= 1) { c = (c & 1) ? ((c >> 1) ^ WLAN_CRC32_POLY_LE) : (c >> 1); if ( k & 1 ) { c ^= WLAN_CRC32_POLY_LE; } } crc32_table[i] = c; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -