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 void wep_crypt(u8 *key, u8 *buf, size_t plen);
25 static inline u16 RotR1(u16 val)
27 return (val >> 1) | (val << 15);
31 static inline u8 Lo8(u16 val)
37 static inline u8 Hi8(u16 val)
43 static inline u16 Lo16(u32 val)
49 static inline u16 Hi16(u32 val)
55 static inline u16 Mk16(u8 hi, u8 lo)
57 return lo | (((u16) hi) << 8);
61 static inline u16 Mk16_le(u16 *v)
63 return le_to_host16(*v);
67 static const u16 Sbox[256] =
69 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
70 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
71 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
72 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
73 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
74 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
75 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
76 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
77 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
78 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
79 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
80 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
81 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
82 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
83 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
84 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
85 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
86 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
87 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
88 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
89 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
90 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
91 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
92 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
93 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
94 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
95 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
96 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
97 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
98 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
99 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
100 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
104 static inline u16 _S_(u16 v)
106 u16 t = Sbox[Hi8(v)];
107 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
111 #define PHASE1_LOOP_COUNT 8
113 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
117 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
118 TTAK[0] = Lo16(IV32);
119 TTAK[1] = Hi16(IV32);
120 TTAK[2] = Mk16(TA[1], TA[0]);
121 TTAK[3] = Mk16(TA[3], TA[2]);
122 TTAK[4] = Mk16(TA[5], TA[4]);
124 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
126 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
127 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
128 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
129 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
130 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
135 static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
140 /* Step 1 - make copy of TTAK and bring in TSC */
146 PPK[5] = TTAK[4] + IV16;
148 /* Step 2 - 96-bit bijective mixing using S-box */
149 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
150 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
151 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
152 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
153 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
154 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
156 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
157 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
158 PPK[2] += RotR1(PPK[1]);
159 PPK[3] += RotR1(PPK[2]);
160 PPK[4] += RotR1(PPK[3]);
161 PPK[5] += RotR1(PPK[4]);
163 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
164 * WEPSeed[0..2] is transmitted as WEP IV */
165 WEPSeed[0] = Hi8(IV16);
166 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
167 WEPSeed[2] = Lo8(IV16);
168 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
169 WPA_PUT_LE16(&WEPSeed[4], PPK[0]);
170 WPA_PUT_LE16(&WEPSeed[6], PPK[1]);
171 WPA_PUT_LE16(&WEPSeed[8], PPK[2]);
172 WPA_PUT_LE16(&WEPSeed[10], PPK[3]);
173 WPA_PUT_LE16(&WEPSeed[12], PPK[4]);
174 WPA_PUT_LE16(&WEPSeed[14], PPK[5]);
178 static inline u32 rotl(u32 val, int bits)
180 return (val << bits) | (val >> (32 - bits));
184 static inline u32 rotr(u32 val, int bits)
186 return (val >> bits) | (val << (32 - bits));
190 static inline u32 xswap(u32 val)
192 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
196 #define michael_block(l, r) \
209 static void michael_mic(const u8 *key, const u8 *hdr, const u8 *data,
210 size_t data_len, u8 *mic)
215 l = WPA_GET_LE32(key);
216 r = WPA_GET_LE32(key + 4);
218 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
219 l ^= WPA_GET_LE32(hdr);
221 l ^= WPA_GET_LE32(&hdr[4]);
223 l ^= WPA_GET_LE32(&hdr[8]);
225 l ^= WPA_GET_LE32(&hdr[12]);
228 /* 32-bit blocks of data */
229 blocks = data_len / 4;
231 for (i = 0; i < blocks; i++) {
232 l ^= WPA_GET_LE32(&data[4 * i]);
236 /* Last block and padding (0x5a, 4..7 x 0) */
242 l ^= data[4 * i] | 0x5a00;
245 l ^= data[4 * i] | (data[4 * i + 1] << 8) | 0x5a0000;
248 l ^= data[4 * i] | (data[4 * i + 1] << 8) |
249 (data[4 * i + 2] << 16) | 0x5a000000;
256 WPA_PUT_LE32(mic, l);
257 WPA_PUT_LE32(mic + 4, r);
261 static void michael_mic_hdr(const struct ieee80211_hdr *hdr11, u8 *hdr)
264 u16 fc = le_to_host16(hdr11->frame_control);
266 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
268 os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
269 os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
272 os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
273 os_memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
275 case WLAN_FC_FROMDS | WLAN_FC_TODS:
276 os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
277 os_memcpy(hdr + ETH_ALEN, hdr11 + 1, ETH_ALEN); /* SA */
281 os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
282 os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
286 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
287 (WLAN_FC_GET_STYPE(fc) & 0x08)) {
288 const u8 *qos = ((const u8 *) hdr11) + hdrlen;
289 hdr[12] = qos[0] & 0x0f; /* priority */
291 hdr[12] = 0; /* priority */
293 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
297 u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
298 const u8 *data, size_t data_len, size_t *decrypted_len)
310 u16 fc = le_to_host16(hdr->frame_control);
312 if (data_len < 8 + 4)
315 iv16 = (data[0] << 8) | data[2];
316 iv32 = WPA_GET_LE32(&data[4]);
317 wpa_printf(MSG_EXCESSIVE, "TKIP decrypt: iv32=%08x iv16=%04x",
320 tkip_mixing_phase1(ttak, tk, hdr->addr2, iv32);
321 wpa_hexdump(MSG_EXCESSIVE, "TKIP TTAK", (u8 *) ttak, sizeof(ttak));
322 tkip_mixing_phase2(rc4key, tk, ttak, iv16);
323 wpa_hexdump(MSG_EXCESSIVE, "TKIP RC4KEY", rc4key, sizeof(rc4key));
325 plain_len = data_len - 8;
326 plain = os_malloc(plain_len);
329 os_memcpy(plain, data + 8, plain_len);
330 wep_crypt(rc4key, plain, plain_len);
332 icv = crc32(plain, plain_len - 4);
333 rx_icv = WPA_GET_LE32(plain + plain_len - 4);
335 wpa_printf(MSG_INFO, "TKIP ICV mismatch in frame from " MACSTR,
336 MAC2STR(hdr->addr2));
337 wpa_printf(MSG_DEBUG, "TKIP calculated ICV %08x received ICV "
338 "%08x", icv, rx_icv);
344 /* TODO: MSDU reassembly */
347 wpa_printf(MSG_INFO, "TKIP: Not enough room for Michael MIC "
348 "in a frame from " MACSTR, MAC2STR(hdr->addr2));
353 michael_mic_hdr(hdr, michael_hdr);
354 mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
355 michael_mic(mic_key, michael_hdr, plain, plain_len - 8, mic);
356 if (os_memcmp(mic, plain + plain_len - 8, 8) != 0) {
357 wpa_printf(MSG_INFO, "TKIP: Michael MIC mismatch in a frame "
358 "from " MACSTR, MAC2STR(hdr->addr2));
359 wpa_hexdump(MSG_DEBUG, "TKIP: Calculated MIC", mic, 8);
360 wpa_hexdump(MSG_DEBUG, "TKIP: Received MIC",
361 plain + plain_len - 8, 8);
366 *decrypted_len = plain_len - 8;
371 void tkip_get_pn(u8 *pn, const u8 *data)
373 pn[0] = data[7]; /* PN5 */
374 pn[1] = data[6]; /* PN4 */
375 pn[2] = data[5]; /* PN3 */
376 pn[3] = data[4]; /* PN2 */
377 pn[4] = data[0]; /* PN1 */
378 pn[5] = data[2]; /* PN0 */
382 u8 * tkip_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
383 u8 *pn, int keyid, size_t *encrypted_len)