Camel/Inap: add missing sub-trees
[metze/wireshark/wip.git] / wsutil / dot11decrypt_wep.c
1 /* dot11decrypt_wep.c
2  *
3  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4  * Copyright (c) 2006 CACE Technologies, Davis (California)
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  */
9
10 #include "config.h"
11
12 /************************************************************************/
13 /*      File includes                                                   */
14
15 #include <glib.h>
16 #include "crc32.h"
17
18 /************************************************************************/
19 /* Note: copied from net80211/ieee80211_airpdcap_tkip.c                 */
20 #define S_SWAP(a,b) { guint8 t = S[a]; S[a] = S[b]; S[b] = t; }
21
22 /* Note: copied from FreeBSD source code, RELENG 6,                     */
23 /*              sys/net80211/ieee80211_crypto_wep.c, 391                */
24 int Dot11DecryptWepDecrypt(
25         const guchar *seed,
26         const size_t seed_len,
27         guchar *cypher_text,
28         const size_t data_len)
29 {
30         guint32 i, j, k, crc;
31         guint8 S[256];
32         guint8 icv[4];
33         size_t buflen;
34
35         /* Generate key stream (RC4 Pseudo-Random Number Generator) */
36         for (i = 0; i < 256; i++)
37                 S[i] = (guint8)i;
38         for (j = i = 0; i < 256; i++) {
39                 j = (j + S[i] + seed[i % seed_len]) & 0xff;
40                 S_SWAP(i, j);
41         }
42
43         /* Apply RC4 to data and compute CRC32 over decrypted data */
44         crc = ~(guint32)0;
45         buflen = data_len;
46
47         for (i = j = k = 0; k < buflen; k++) {
48                 i = (i + 1) & 0xff;
49                 j = (j + S[i]) & 0xff;
50                 S_SWAP(i, j);
51                 *cypher_text ^= S[(S[i] + S[j]) & 0xff];
52                 crc = crc32_ccitt_table_lookup((crc ^ *cypher_text) & 0xff) ^ (crc >> 8);
53                 cypher_text++;
54         }
55
56         crc = ~crc;
57
58         /* Encrypt little-endian CRC32 and verify that it matches with the received ICV */
59         icv[0] = (guint8)crc;
60         icv[1] = (guint8)(crc >> 8);
61         icv[2] = (guint8)(crc >> 16);
62         icv[3] = (guint8)(crc >> 24);
63         for (k = 0; k < 4; k++) {
64                 i = (i + 1) & 0xff;
65                 j = (j + S[i]) & 0xff;
66                 S_SWAP(i, j);
67                 if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *cypher_text++) {
68                         /* ICV mismatch - drop frame */
69                         return 1/*DOT11DECRYPT_RET_UNSUCCESS*/;
70                 }
71         }
72
73         return 0/*DOT11DECRYPT_RET_SUCCESS*/;
74 }
75
76 /*
77  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
78  *
79  * Local variables:
80  * c-basic-offset: 8
81  * tab-width: 8
82  * indent-tabs-mode: t
83  * End:
84  *
85  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
86  * :indentSize=8:tabSize=8:noTabs=false:
87  */