Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/net80211/tkip/test_tkip.c
105418 views
1
/*-
2
* Copyright (c) 2004 Sam Leffler, Errno Consulting
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
15
*
16
* Alternatively, this software may be distributed under the terms of the
17
* GNU General Public License ("GPL") version 2 as published by the Free
18
* Software Foundation.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* TKIP test module.
34
*/
35
#include <sys/param.h>
36
#include <sys/kernel.h>
37
#include <sys/systm.h>
38
#include <sys/mbuf.h>
39
#include <sys/module.h>
40
41
#include <sys/socket.h>
42
43
#include <net/if.h>
44
#include <net/if_var.h>
45
#include <net/if_media.h>
46
47
#include <net80211/ieee80211_var.h>
48
49
/*
50
Key 12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12
51
34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34
52
PN 0x000000000001
53
IV 00 20 01 20 00 00 00 00
54
Phase1 bb 58 07 1f 9e 93 b4 38 25 4b
55
Phase2 00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c
56
*/
57
58
static const u_int8_t test1_key[] = {
59
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
60
0x34, 0x56, 0x78, 0x90, 0x12,
61
62
0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX MIC */
63
/*
64
* NB: 11i test vector specifies a RX MIC key different
65
* from the TX key. But this doesn't work to enmic,
66
* encrypt, then decrypt, demic. So instead we use
67
* the same key for doing the MIC in each direction.
68
*
69
* XXX need additional vectors to test alternate MIC keys
70
*/
71
#if 0
72
0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, /* 11i RX MIC */
73
#else
74
0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX copy */
75
#endif
76
};
77
static const u_int8_t test1_phase1[] = {
78
0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b
79
};
80
static const u_int8_t test1_phase2[] = {
81
0x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86,
82
0x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c,
83
};
84
85
/* Plaintext MPDU with MIC */
86
static const u_int8_t test1_plaintext[] = {
87
0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
88
0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,
89
0xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,
90
0x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0,
91
0x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b,
92
0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
93
0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,
94
0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
95
/* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c
96
};
97
98
/* Encrypted MPDU with MIC and ICV */
99
static const u_int8_t test1_encrypted[] = {
100
0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
101
0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00,
102
0xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac,
103
0x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a,
104
0x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5,
105
0x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e,
106
0x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50,
107
0x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f,
108
0xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8
109
};
110
111
#define TEST(n,name,cipher,keyix,pn) { \
112
name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
113
test##n##_key, sizeof(test##n##_key), \
114
test##n##_phase1, sizeof(test##n##_phase1), \
115
test##n##_phase2, sizeof(test##n##_phase2), \
116
test##n##_plaintext, sizeof(test##n##_plaintext), \
117
test##n##_encrypted, sizeof(test##n##_encrypted) \
118
}
119
120
struct ciphertest {
121
const char *name;
122
int cipher;
123
int keyix;
124
u_int64_t pn;
125
const u_int8_t *key;
126
size_t key_len;
127
const u_int8_t *phase1;
128
size_t phase1_len;
129
const u_int8_t *phase2;
130
size_t phase2_len;
131
const u_int8_t *plaintext;
132
size_t plaintext_len;
133
const u_int8_t *encrypted;
134
size_t encrypted_len;
135
} tkiptests[] = {
136
TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),
137
};
138
139
struct tkip_ctx {
140
struct ieee80211com *tc_ic; /* for diagnostics */
141
142
uint16_t tx_ttak[5];
143
uint8_t tx_rc4key[16];
144
145
uint16_t rx_ttak[5];
146
int rx_phase1_done;
147
uint8_t rx_rc4key[16];
148
uint64_t rx_rsc; /* held until MIC verified */
149
};
150
151
static void
152
dumpdata(const char *tag, const void *p, size_t len)
153
{
154
int i;
155
156
printf("%s: 0x%p len %u", tag, p, len);
157
for (i = 0; i < len; i++) {
158
if ((i % 16) == 0)
159
printf("\n%03d:", i);
160
printf(" %02x", ((const u_int8_t *)p)[i]);
161
}
162
printf("\n");
163
}
164
165
static void
166
cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
167
{
168
int i;
169
170
for (i = 0; i < genlen; i++)
171
if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
172
printf("first difference at byte %u\n", i);
173
break;
174
}
175
dumpdata("Generated", gen, genlen);
176
dumpdata("Reference", ref, reflen);
177
}
178
179
static int
180
runtest(struct ieee80211vap *vap, struct ciphertest *t)
181
{
182
struct tkip_ctx *ctx;
183
struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
184
struct mbuf *m = NULL;
185
const struct ieee80211_cipher *cip;
186
u_int len;
187
int hdrlen;
188
189
printf("%s: ", t->name);
190
191
/*
192
* Setup key.
193
*/
194
memset(key, 0, sizeof(*key));
195
key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
196
key->wk_cipher = &ieee80211_cipher_none;
197
if (!ieee80211_crypto_newkey(vap, t->cipher,
198
IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
199
printf("FAIL: ieee80211_crypto_newkey failed\n");
200
goto bad;
201
}
202
203
memcpy(key->wk_key, t->key, t->key_len);
204
key->wk_keylen = 128/NBBY;
205
memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
206
key->wk_keytsc = t->pn;
207
if (!ieee80211_crypto_setkey(vap, key)) {
208
printf("FAIL: ieee80211_crypto_setkey failed\n");
209
goto bad;
210
}
211
212
/*
213
* Craft frame from plaintext data.
214
*/
215
cip = key->wk_cipher;
216
m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
217
m->m_data += cip->ic_header;
218
len = t->plaintext_len - IEEE80211_WEP_MICLEN;
219
memcpy(mtod(m, void *), t->plaintext, len);
220
m->m_len = len;
221
m->m_pkthdr.len = m->m_len;
222
hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
223
224
/*
225
* Add MIC.
226
*/
227
if (!ieee80211_crypto_enmic(vap, key, m, 1)) {
228
printf("FAIL: tkip enmic failed\n");
229
goto bad;
230
}
231
/*
232
* Verify: frame length, frame contents.
233
*/
234
if (m->m_pkthdr.len != t->plaintext_len) {
235
printf("FAIL: enmic botch; length mismatch\n");
236
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
237
t->plaintext, t->plaintext_len);
238
goto bad;
239
}
240
if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
241
printf("FAIL: enmic botch\n");
242
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
243
t->plaintext, t->plaintext_len);
244
goto bad;
245
}
246
/*
247
* Encrypt frame w/ MIC.
248
*/
249
if (!cip->ic_encap(key, m)) {
250
printf("FAIL: tkip encap failed\n");
251
goto bad;
252
}
253
/*
254
* Verify: phase1, phase2, frame length, frame contents.
255
*/
256
ctx = key->wk_private;
257
if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) {
258
printf("FAIL: encrypt phase1 botch\n");
259
cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
260
t->phase1, t->phase1_len);
261
goto bad;
262
} else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
263
printf("FAIL: encrypt phase2 botch\n");
264
cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),
265
t->phase2, t->phase2_len);
266
goto bad;
267
} else if (m->m_pkthdr.len != t->encrypted_len) {
268
printf("FAIL: encrypt data length mismatch\n");
269
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
270
t->encrypted, t->encrypted_len);
271
goto bad;
272
} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
273
printf("FAIL: encrypt data does not compare\n");
274
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
275
t->encrypted, t->encrypted_len);
276
dumpdata("Plaintext", t->plaintext, t->plaintext_len);
277
goto bad;
278
}
279
280
/*
281
* Decrypt frame.
282
*/
283
if (!cip->ic_decap(key, m, hdrlen)) {
284
printf("tkip decap failed\n");
285
/*
286
* Check reason for failure: phase1, phase2, frame data (ICV).
287
*/
288
if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) {
289
printf("FAIL: decrypt phase1 botch\n");
290
cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak),
291
t->phase1, t->phase1_len);
292
} else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) {
293
printf("FAIL: decrypt phase2 botch\n");
294
cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key),
295
t->phase2, t->phase2_len);
296
} else {
297
printf("FAIL: decrypt data does not compare\n");
298
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
299
t->plaintext, t->plaintext_len);
300
}
301
goto bad;
302
}
303
/*
304
* Verify: frame length, frame contents.
305
*/
306
if (m->m_pkthdr.len != t->plaintext_len) {
307
printf("FAIL: decap botch; length mismatch\n");
308
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
309
t->plaintext, t->plaintext_len);
310
goto bad;
311
}
312
if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
313
printf("FAIL: decap botch; data does not compare\n");
314
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
315
t->plaintext, t->plaintext_len);
316
goto bad;
317
}
318
/*
319
* De-MIC decrypted frame.
320
*/
321
if (!ieee80211_crypto_demic(vap, key, m, 1)) {
322
printf("FAIL: tkip demic failed\n");
323
goto bad;
324
}
325
/* XXX check frame length and contents... */
326
m_freem(m);
327
ieee80211_crypto_delkey(vap, key);
328
printf("PASS\n");
329
return 1;
330
bad:
331
if (m != NULL)
332
m_freem(m);
333
ieee80211_crypto_delkey(vap, key);
334
return 0;
335
}
336
337
/*
338
* Module glue.
339
*/
340
341
static int debug = 0;
342
static int tests = -1;
343
344
static int
345
init_crypto_tkip_test(void)
346
{
347
struct ieee80211com ic;
348
struct ieee80211vap vap;
349
struct ifnet ifp;
350
int i, pass, total;
351
352
memset(&ic, 0, sizeof(ic));
353
memset(&vap, 0, sizeof(vap));
354
memset(&ifp, 0, sizeof(ifp));
355
356
ieee80211_crypto_attach(&ic);
357
358
/* some minimal initialization */
359
strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
360
vap.iv_ic = &ic;
361
vap.iv_ifp = &ifp;
362
if (debug)
363
vap.iv_debug = IEEE80211_MSG_CRYPTO;
364
ieee80211_crypto_vattach(&vap);
365
366
pass = 0;
367
total = 0;
368
for (i = 0; i < nitems(tkiptests); i++)
369
if (tests & (1<<i)) {
370
total++;
371
pass += runtest(&vap, &tkiptests[i]);
372
}
373
printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
374
375
ieee80211_crypto_vdetach(&vap);
376
ieee80211_crypto_detach(&ic);
377
378
return (pass == total ? 0 : -1);
379
}
380
381
static int
382
test_tkip_modevent(module_t mod, int type, void *unused)
383
{
384
switch (type) {
385
case MOD_LOAD:
386
(void) init_crypto_tkip_test();
387
return 0;
388
case MOD_UNLOAD:
389
return 0;
390
}
391
return EINVAL;
392
}
393
394
static moduledata_t test_tkip_mod = {
395
"test_tkip",
396
test_tkip_modevent,
397
0
398
};
399
DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
400
MODULE_VERSION(test_tkip, 1);
401
MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);
402
403