2 * Temporal Key Integrity Protocol (CCMP)
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "common/ieee802_11_defs.h"
16 void wep_crypt(u8 *key, u8 *buf, size_t plen);
19 static inline u16 RotR1(u16 val)
21 return (val >> 1) | (val << 15);
25 static inline u8 Lo8(u16 val)
31 static inline u8 Hi8(u16 val)
37 static inline u16 Lo16(u32 val)
43 static inline u16 Hi16(u32 val)
49 static inline u16 Mk16(u8 hi, u8 lo)
51 return lo | (((u16) hi) << 8);
55 static inline u16 Mk16_le(u16 *v)
57 return le_to_host16(*v);
61 static const u16 Sbox[256] =
63 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
64 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
65 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
66 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
67 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
68 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
69 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
70 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
71 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
72 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
73 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
74 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
75 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
76 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
77 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
78 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
79 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
80 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
81 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
82 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
83 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
84 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
85 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
86 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
87 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
88 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
89 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
90 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
91 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
92 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
93 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
94 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
98 static inline u16 _S_(u16 v)
100 u16 t = Sbox[Hi8(v)];
101 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
105 #define PHASE1_LOOP_COUNT 8
107 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
111 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
112 TTAK[0] = Lo16(IV32);
113 TTAK[1] = Hi16(IV32);
114 TTAK[2] = Mk16(TA[1], TA[0]);
115 TTAK[3] = Mk16(TA[3], TA[2]);
116 TTAK[4] = Mk16(TA[5], TA[4]);
118 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
120 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
121 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
122 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
123 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
124 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
129 static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
134 /* Step 1 - make copy of TTAK and bring in TSC */
140 PPK[5] = TTAK[4] + IV16;
142 /* Step 2 - 96-bit bijective mixing using S-box */
143 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
144 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
145 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
146 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
147 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
148 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
150 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
151 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
152 PPK[2] += RotR1(PPK[1]);
153 PPK[3] += RotR1(PPK[2]);
154 PPK[4] += RotR1(PPK[3]);
155 PPK[5] += RotR1(PPK[4]);
157 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
158 * WEPSeed[0..2] is transmitted as WEP IV */
159 WEPSeed[0] = Hi8(IV16);
160 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
161 WEPSeed[2] = Lo8(IV16);
162 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
163 WPA_PUT_LE16(&WEPSeed[4], PPK[0]);
164 WPA_PUT_LE16(&WEPSeed[6], PPK[1]);
165 WPA_PUT_LE16(&WEPSeed[8], PPK[2]);
166 WPA_PUT_LE16(&WEPSeed[10], PPK[3]);
167 WPA_PUT_LE16(&WEPSeed[12], PPK[4]);
168 WPA_PUT_LE16(&WEPSeed[14], PPK[5]);
172 static inline u32 rotl(u32 val, int bits)
174 return (val << bits) | (val >> (32 - bits));
178 static inline u32 rotr(u32 val, int bits)
180 return (val >> bits) | (val << (32 - bits));
184 static inline u32 xswap(u32 val)
186 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
190 #define michael_block(l, r) \
203 static void michael_mic(const u8 *key, const u8 *hdr, const u8 *data,
204 size_t data_len, u8 *mic)
209 l = WPA_GET_LE32(key);
210 r = WPA_GET_LE32(key + 4);
212 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
213 l ^= WPA_GET_LE32(hdr);
215 l ^= WPA_GET_LE32(&hdr[4]);
217 l ^= WPA_GET_LE32(&hdr[8]);
219 l ^= WPA_GET_LE32(&hdr[12]);
222 /* 32-bit blocks of data */
223 blocks = data_len / 4;
225 for (i = 0; i < blocks; i++) {
226 l ^= WPA_GET_LE32(&data[4 * i]);
230 /* Last block and padding (0x5a, 4..7 x 0) */
236 l ^= data[4 * i] | 0x5a00;
239 l ^= data[4 * i] | (data[4 * i + 1] << 8) | 0x5a0000;
242 l ^= data[4 * i] | (data[4 * i + 1] << 8) |
243 (data[4 * i + 2] << 16) | 0x5a000000;
250 WPA_PUT_LE32(mic, l);
251 WPA_PUT_LE32(mic + 4, r);
255 static void michael_mic_hdr(const struct ieee80211_hdr *hdr11, u8 *hdr)
258 u16 fc = le_to_host16(hdr11->frame_control);
260 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
262 os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
263 os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
266 os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
267 os_memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
269 case WLAN_FC_FROMDS | WLAN_FC_TODS:
270 os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
271 os_memcpy(hdr + ETH_ALEN, hdr11 + 1, ETH_ALEN); /* SA */
275 os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
276 os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
280 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
281 (WLAN_FC_GET_STYPE(fc) & 0x08)) {
282 const u8 *qos = ((const u8 *) hdr11) + hdrlen;
283 hdr[12] = qos[0] & 0x0f; /* priority */
285 hdr[12] = 0; /* priority */
287 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
291 u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
292 const u8 *data, size_t data_len, size_t *decrypted_len)
304 u16 fc = le_to_host16(hdr->frame_control);
306 if (data_len < 8 + 4)
309 iv16 = (data[0] << 8) | data[2];
310 iv32 = WPA_GET_LE32(&data[4]);
311 wpa_printf(MSG_EXCESSIVE, "TKIP decrypt: iv32=%08x iv16=%04x",
314 tkip_mixing_phase1(ttak, tk, hdr->addr2, iv32);
315 wpa_hexdump(MSG_EXCESSIVE, "TKIP TTAK", (u8 *) ttak, sizeof(ttak));
316 tkip_mixing_phase2(rc4key, tk, ttak, iv16);
317 wpa_hexdump(MSG_EXCESSIVE, "TKIP RC4KEY", rc4key, sizeof(rc4key));
319 plain_len = data_len - 8;
320 plain = os_malloc(plain_len);
323 os_memcpy(plain, data + 8, plain_len);
324 wep_crypt(rc4key, plain, plain_len);
326 icv = crc32(plain, plain_len - 4);
327 rx_icv = WPA_GET_LE32(plain + plain_len - 4);
329 wpa_printf(MSG_INFO, "TKIP ICV mismatch in frame from " MACSTR,
330 MAC2STR(hdr->addr2));
331 wpa_printf(MSG_DEBUG, "TKIP calculated ICV %08x received ICV "
332 "%08x", icv, rx_icv);
338 /* TODO: MSDU reassembly */
341 wpa_printf(MSG_INFO, "TKIP: Not enough room for Michael MIC "
342 "in a frame from " MACSTR, MAC2STR(hdr->addr2));
347 michael_mic_hdr(hdr, michael_hdr);
348 mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
349 michael_mic(mic_key, michael_hdr, plain, plain_len - 8, mic);
350 if (os_memcmp(mic, plain + plain_len - 8, 8) != 0) {
351 wpa_printf(MSG_INFO, "TKIP: Michael MIC mismatch in a frame "
352 "from " MACSTR, MAC2STR(hdr->addr2));
353 wpa_hexdump(MSG_DEBUG, "TKIP: Calculated MIC", mic, 8);
354 wpa_hexdump(MSG_DEBUG, "TKIP: Received MIC",
355 plain + plain_len - 8, 8);
360 *decrypted_len = plain_len - 8;
365 void tkip_get_pn(u8 *pn, const u8 *data)
367 pn[0] = data[7]; /* PN5 */
368 pn[1] = data[6]; /* PN4 */
369 pn[2] = data[5]; /* PN3 */
370 pn[3] = data[4]; /* PN2 */
371 pn[4] = data[0]; /* PN1 */
372 pn[5] = data[2]; /* PN0 */
376 u8 * tkip_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
377 u8 *pn, int keyid, size_t *encrypted_len)
381 struct ieee80211_hdr *hdr;
390 if (len < sizeof(*hdr) || len < hdrlen)
392 hdr = (struct ieee80211_hdr *) frame;
393 fc = le_to_host16(hdr->frame_control);
395 michael_mic_hdr(hdr, michael_hdr);
396 mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
397 michael_mic(mic_key, michael_hdr, frame + hdrlen, len - hdrlen, mic);
398 wpa_hexdump(MSG_EXCESSIVE, "TKIP: MIC", mic, sizeof(mic));
400 iv32 = WPA_GET_BE32(pn);
401 iv16 = WPA_GET_BE16(pn + 4);
402 tkip_mixing_phase1(ttak, tk, hdr->addr2, iv32);
403 wpa_hexdump(MSG_EXCESSIVE, "TKIP TTAK", (u8 *) ttak, sizeof(ttak));
404 tkip_mixing_phase2(rc4key, tk, ttak, iv16);
405 wpa_hexdump(MSG_EXCESSIVE, "TKIP RC4KEY", rc4key, sizeof(rc4key));
407 crypt = os_malloc(len + 8 + sizeof(mic) + 4);
410 os_memcpy(crypt, frame, hdrlen);
411 pos = crypt + hdrlen;
412 os_memcpy(pos, rc4key, 3);
414 *pos++ = keyid << 6 | BIT(5);
420 os_memcpy(pos, frame + hdrlen, len - hdrlen);
421 os_memcpy(pos + len - hdrlen, mic, sizeof(mic));
422 WPA_PUT_LE32(pos + len - hdrlen + sizeof(mic),
423 crc32(pos, len - hdrlen + sizeof(mic)));
424 wep_crypt(rc4key, pos, len - hdrlen + sizeof(mic) + 4);
426 *encrypted_len = len + 8 + sizeof(mic) + 4;