2 * Temporal Key Integrity Protocol (CCMP)
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "common/ieee802_11_defs.h"
22 static inline u16 RotR1(u16 val)
24 return (val >> 1) | (val << 15);
28 static inline u8 Lo8(u16 val)
34 static inline u8 Hi8(u16 val)
40 static inline u16 Lo16(u32 val)
46 static inline u16 Hi16(u32 val)
52 static inline u16 Mk16(u8 hi, u8 lo)
54 return lo | (((u16) hi) << 8);
58 static inline u16 Mk16_le(u16 *v)
60 return le_to_host16(*v);
64 static const u16 Sbox[256] =
66 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
67 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
68 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
69 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
70 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
71 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
72 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
73 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
74 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
75 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
76 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
77 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
78 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
79 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
80 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
81 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
82 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
83 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
84 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
85 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
86 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
87 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
88 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
89 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
90 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
91 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
92 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
93 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
94 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
95 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
96 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
97 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
101 static inline u16 _S_(u16 v)
103 u16 t = Sbox[Hi8(v)];
104 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
108 #define PHASE1_LOOP_COUNT 8
110 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
114 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
115 TTAK[0] = Lo16(IV32);
116 TTAK[1] = Hi16(IV32);
117 TTAK[2] = Mk16(TA[1], TA[0]);
118 TTAK[3] = Mk16(TA[3], TA[2]);
119 TTAK[4] = Mk16(TA[5], TA[4]);
121 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
123 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
124 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
125 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
126 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
127 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
132 static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
137 /* Step 1 - make copy of TTAK and bring in TSC */
143 PPK[5] = TTAK[4] + IV16;
145 /* Step 2 - 96-bit bijective mixing using S-box */
146 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
147 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
148 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
149 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
150 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
151 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
153 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
154 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
155 PPK[2] += RotR1(PPK[1]);
156 PPK[3] += RotR1(PPK[2]);
157 PPK[4] += RotR1(PPK[3]);
158 PPK[5] += RotR1(PPK[4]);
160 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
161 * WEPSeed[0..2] is transmitted as WEP IV */
162 WEPSeed[0] = Hi8(IV16);
163 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
164 WEPSeed[2] = Lo8(IV16);
165 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
166 WPA_PUT_LE16(&WEPSeed[4], PPK[0]);
167 WPA_PUT_LE16(&WEPSeed[6], PPK[1]);
168 WPA_PUT_LE16(&WEPSeed[8], PPK[2]);
169 WPA_PUT_LE16(&WEPSeed[10], PPK[3]);
170 WPA_PUT_LE16(&WEPSeed[12], PPK[4]);
171 WPA_PUT_LE16(&WEPSeed[14], PPK[5]);
175 static void wep_crypt(u8 *key, u8 *buf, size_t plen)
179 #define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
182 /* Setup RC4 state */
183 for (i = 0; i < 256; i++)
186 for (i = 0; i < 256; i++) {
187 j = (j + S[i] + key[i & 0x0f]) & 0xff;
191 /* Apply RC4 to data */
194 for (k = 0; k < plen; k++) {
196 j = (j + S[i]) & 0xff;
198 *pos ^= S[(S[i] + S[j]) & 0xff];
204 static inline u32 rotl(u32 val, int bits)
206 return (val << bits) | (val >> (32 - bits));
210 static inline u32 rotr(u32 val, int bits)
212 return (val >> bits) | (val << (32 - bits));
216 static inline u32 xswap(u32 val)
218 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
222 #define michael_block(l, r) \
235 static void michael_mic(const u8 *key, const u8 *hdr, const u8 *data,
236 size_t data_len, u8 *mic)
241 l = WPA_GET_LE32(key);
242 r = WPA_GET_LE32(key + 4);
244 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
245 l ^= WPA_GET_LE32(hdr);
247 l ^= WPA_GET_LE32(&hdr[4]);
249 l ^= WPA_GET_LE32(&hdr[8]);
251 l ^= WPA_GET_LE32(&hdr[12]);
254 /* 32-bit blocks of data */
255 blocks = data_len / 4;
257 for (i = 0; i < blocks; i++) {
258 l ^= WPA_GET_LE32(&data[4 * i]);
262 /* Last block and padding (0x5a, 4..7 x 0) */
268 l ^= data[4 * i] | 0x5a00;
271 l ^= data[4 * i] | (data[4 * i + 1] << 8) | 0x5a0000;
274 l ^= data[4 * i] | (data[4 * i + 1] << 8) |
275 (data[4 * i + 2] << 16) | 0x5a000000;
282 WPA_PUT_LE32(mic, l);
283 WPA_PUT_LE32(mic + 4, r);
287 static void michael_mic_hdr(const struct ieee80211_hdr *hdr11, u8 *hdr)
290 u16 fc = le_to_host16(hdr11->frame_control);
292 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
294 os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
295 os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
298 os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
299 os_memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
301 case WLAN_FC_FROMDS | WLAN_FC_TODS:
302 os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
303 os_memcpy(hdr + ETH_ALEN, hdr11 + 1, ETH_ALEN); /* SA */
307 os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
308 os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
312 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
313 (WLAN_FC_GET_STYPE(fc) & 0x08)) {
314 const u8 *qos = ((const u8 *) hdr11) + hdrlen;
315 hdr[12] = qos[0] & 0x0f; /* priority */
317 hdr[12] = 0; /* priority */
319 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
323 u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
324 const u8 *data, size_t data_len, size_t *decrypted_len)
336 u16 fc = le_to_host16(hdr->frame_control);
338 if (data_len < 8 + 4)
341 iv16 = (data[0] << 8) | data[2];
342 iv32 = WPA_GET_LE32(&data[4]);
343 wpa_printf(MSG_EXCESSIVE, "TKIP decrypt: iv32=%08x iv16=%04x",
346 tkip_mixing_phase1(ttak, tk, hdr->addr2, iv32);
347 wpa_hexdump(MSG_EXCESSIVE, "TKIP TTAK", (u8 *) ttak, sizeof(ttak));
348 tkip_mixing_phase2(rc4key, tk, ttak, iv16);
349 wpa_hexdump(MSG_EXCESSIVE, "TKIP RC4KEY", rc4key, sizeof(rc4key));
351 plain_len = data_len - 8;
352 plain = os_malloc(plain_len);
355 os_memcpy(plain, data + 8, plain_len);
356 wep_crypt(rc4key, plain, plain_len);
358 icv = crc32(plain, plain_len - 4);
359 rx_icv = WPA_GET_LE32(plain + plain_len - 4);
361 wpa_printf(MSG_INFO, "TKIP ICV mismatch in frame from " MACSTR,
362 MAC2STR(hdr->addr2));
363 wpa_printf(MSG_DEBUG, "TKIP calculated ICV %08x received ICV "
364 "%08x", icv, rx_icv);
370 /* TODO: MSDU reassembly */
373 wpa_printf(MSG_INFO, "TKIP: Not enough room for Michael MIC "
374 "in a frame from " MACSTR, MAC2STR(hdr->addr2));
379 michael_mic_hdr(hdr, michael_hdr);
380 mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
381 michael_mic(mic_key, michael_hdr, plain, plain_len - 8, mic);
382 if (os_memcmp(mic, plain + plain_len - 8, 8) != 0) {
383 wpa_printf(MSG_INFO, "TKIP: Michael MIC mismatch in a frame "
384 "from " MACSTR, MAC2STR(hdr->addr2));
385 wpa_hexdump(MSG_DEBUG, "TKIP: Calculated MIC", mic, 8);
386 wpa_hexdump(MSG_DEBUG, "TKIP: Received MIC",
387 plain + plain_len - 8, 8);
392 *decrypted_len = plain_len - 8;
397 void tkip_get_pn(u8 *pn, const u8 *data)
399 pn[0] = data[7]; /* PN5 */
400 pn[1] = data[6]; /* PN4 */
401 pn[2] = data[5]; /* PN3 */
402 pn[3] = data[4]; /* PN2 */
403 pn[4] = data[0]; /* PN1 */
404 pn[5] = data[2]; /* PN0 */