1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
6 ******************************************************************************/
7 #define _RTW_SECURITY_C_
9 #include <osdep_service.h>
10 #include <drv_types.h>
12 #include <osdep_intf.h>
13 #include <net/lib80211.h>
15 /* WEP related ===== */
17 #define CRC32_POLY 0x04c11db7
25 static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
33 state = parc4ctx->state;
36 for (counter = 0; counter < 256; counter++)
37 state[counter] = (u8)counter;
40 for (counter = 0; counter < 256; counter++) {
42 stateindex = (stateindex + key[keyindex] + t) & 0xff;
43 u = state[stateindex];
44 state[stateindex] = (u8)t;
45 state[counter] = (u8)u;
46 if (++keyindex >= key_len)
51 static u32 arcfour_byte(struct arc4context *parc4ctx)
58 state = parc4ctx->state;
59 x = (parc4ctx->x + 1) & 0xff;
61 y = (sx + parc4ctx->y) & 0xff;
67 return state[(sx + sy) & 0xff];
70 static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len)
74 for (i = 0; i < len; i++)
75 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
78 static int bcrc32initialized;
79 static u32 crc32_table[256];
81 static u8 crc32_reverseBit(u8 data)
83 return (u8)((data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3) & 0x20) |
84 ((data << 1) & 0x10) | ((data >> 1) & 0x08) | ((data >> 3) & 0x04) |
85 ((data >> 5) & 0x02) | ((data >> 7) & 0x01);
88 static void crc32_init(void)
92 u8 *p = (u8 *)&c, *p1;
95 if (bcrc32initialized == 1)
100 for (i = 0; i < 256; ++i) {
101 k = crc32_reverseBit((u8)i);
102 for (c = ((u32)k) << 24, j = 8; j > 0; --j)
103 c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
104 p1 = (u8 *)&crc32_table[i];
106 p1[0] = crc32_reverseBit(p[3]);
107 p1[1] = crc32_reverseBit(p[2]);
108 p1[2] = crc32_reverseBit(p[1]);
109 p1[3] = crc32_reverseBit(p[0]);
111 bcrc32initialized = 1;
114 static __le32 getcrc32(u8 *buf, int len)
119 if (bcrc32initialized == 0)
122 crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
124 for (p = buf; len > 0; ++p, --len)
125 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
126 return cpu_to_le32(~crc); /* transmit complement, per CRC-32 spec */
130 Need to consider the fragment situation
132 void rtw_wep_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
134 int curfragnum, length;
136 u8 hw_hdr_offset = 0;
137 struct pkt_attrib *pattrib = &pxmitframe->attrib;
138 struct security_priv *psecuritypriv = &padapter->securitypriv;
139 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
140 const int keyindex = psecuritypriv->dot11PrivacyKeyIndex;
141 void *crypto_private;
143 struct lib80211_crypto_ops *crypto_ops;
145 if (!pxmitframe->buf_addr)
148 if ((pattrib->encrypt != _WEP40_) && (pattrib->encrypt != _WEP104_))
151 hw_hdr_offset = TXDESC_SIZE +
152 (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
154 pframe = pxmitframe->buf_addr + hw_hdr_offset;
156 crypto_ops = lib80211_get_crypto_ops("WEP");
161 crypto_private = crypto_ops->init(keyindex);
165 if (crypto_ops->set_key(psecuritypriv->dot11DefKey[keyindex].skey,
166 psecuritypriv->dot11DefKeylen[keyindex], NULL, crypto_private) < 0)
167 goto free_crypto_private;
169 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
170 if (curfragnum + 1 == pattrib->nr_frags)
171 length = pattrib->last_txcmdsz;
173 length = pxmitpriv->frag_len;
174 skb = dev_alloc_skb(length);
176 goto free_crypto_private;
178 skb_put_data(skb, pframe, length);
180 memmove(skb->data + 4, skb->data, pattrib->hdrlen);
182 skb_trim(skb, skb->len - 4);
184 if (crypto_ops->encrypt_mpdu(skb, pattrib->hdrlen, crypto_private)) {
186 goto free_crypto_private;
189 memcpy(pframe, skb->data, skb->len);
192 pframe = (u8 *)round_up((size_t)(pframe), 4);
198 crypto_ops->deinit(crypto_private);
201 int rtw_wep_decrypt(struct adapter *padapter, struct recv_frame *precvframe)
203 struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
205 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
206 struct security_priv *psecuritypriv = &padapter->securitypriv;
207 struct sk_buff *skb = precvframe->pkt;
208 u8 *pframe = skb->data;
209 void *crypto_private = NULL;
210 int status = _SUCCESS;
211 const int keyindex = prxattrib->key_index;
212 struct lib80211_crypto_ops *crypto_ops = lib80211_get_crypto_ops("WEP");
220 memcpy(iv, pframe + prxattrib->hdrlen, 4);
221 memcpy(icv, pframe + skb->len - 4, 4);
223 crypto_private = crypto_ops->init(keyindex);
224 if (!crypto_private) {
228 if (crypto_ops->set_key(psecuritypriv->dot11DefKey[keyindex].skey,
229 psecuritypriv->dot11DefKeylen[keyindex], NULL, crypto_private) < 0) {
233 if (crypto_ops->decrypt_mpdu(skb, prxattrib->hdrlen, crypto_private)) {
238 memmove(pframe, pframe + 4, prxattrib->hdrlen);
242 memcpy(pframe + prxattrib->hdrlen, iv, 4);
243 memcpy(pframe + skb->len - 4, icv, 4);
246 if (crypto_ops && crypto_private)
247 crypto_ops->deinit(crypto_private);
254 /* 3 ===== TKIP related ===== */
256 static u32 secmicgetuint32(u8 *p)
257 /* Convert from Byte[] to Us3232 in a portable way */
262 for (i = 0; i < 4; i++)
263 res |= ((u32)(*p++)) << (8 * i);
267 static void secmicputuint32(u8 *p, u32 val)
268 /* Convert from Us3232 to Byte[] in a portable way */
272 for (i = 0; i < 4; i++) {
273 *p++ = (u8)(val & 0xff);
278 static void secmicclear(struct mic_data *pmicdata)
280 /* Reset the state to the empty message. */
281 pmicdata->L = pmicdata->K0;
282 pmicdata->R = pmicdata->K1;
283 pmicdata->nBytesInM = 0;
287 void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
290 pmicdata->K0 = secmicgetuint32(key);
291 pmicdata->K1 = secmicgetuint32(key + 4);
292 /* and reset the message */
293 secmicclear(pmicdata);
296 void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
298 /* Append the byte to our word-sized buffer */
299 pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);
300 pmicdata->nBytesInM++;
301 /* Process the word if it is full. */
302 if (pmicdata->nBytesInM >= 4) {
303 pmicdata->L ^= pmicdata->M;
304 pmicdata->R ^= ROL32(pmicdata->L, 17);
305 pmicdata->L += pmicdata->R;
306 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
307 pmicdata->L += pmicdata->R;
308 pmicdata->R ^= ROL32(pmicdata->L, 3);
309 pmicdata->L += pmicdata->R;
310 pmicdata->R ^= ROR32(pmicdata->L, 2);
311 pmicdata->L += pmicdata->R;
312 /* Clear the buffer */
314 pmicdata->nBytesInM = 0;
318 void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
322 rtw_secmicappendbyte(pmicdata, *src++);
327 void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
329 /* Append the minimum padding */
330 rtw_secmicappendbyte(pmicdata, 0x5a);
331 rtw_secmicappendbyte(pmicdata, 0);
332 rtw_secmicappendbyte(pmicdata, 0);
333 rtw_secmicappendbyte(pmicdata, 0);
334 rtw_secmicappendbyte(pmicdata, 0);
335 /* and then zeroes until the length is a multiple of 4 */
336 while (pmicdata->nBytesInM != 0)
337 rtw_secmicappendbyte(pmicdata, 0);
338 /* The appendByte function has already computed the result. */
339 secmicputuint32(dst, pmicdata->L);
340 secmicputuint32(dst + 4, pmicdata->R);
341 /* Reset to the empty message. */
342 secmicclear(pmicdata);
345 void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
347 struct mic_data micdata;
348 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
350 rtw_secmicsetkey(&micdata, key);
353 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
354 if (header[1] & 1) { /* ToDS == 1 */
355 rtw_secmicappend(&micdata, &header[16], 6); /* DA */
356 if (header[1] & 2) /* From Ds == 1 */
357 rtw_secmicappend(&micdata, &header[24], 6);
359 rtw_secmicappend(&micdata, &header[10], 6);
360 } else { /* ToDS == 0 */
361 rtw_secmicappend(&micdata, &header[4], 6); /* DA */
362 if (header[1] & 2) /* From Ds == 1 */
363 rtw_secmicappend(&micdata, &header[16], 6);
365 rtw_secmicappend(&micdata, &header[10], 6);
367 rtw_secmicappend(&micdata, &priority[0], 4);
369 rtw_secmicappend(&micdata, data, data_len);
371 rtw_secgetmic(&micdata, mic_code);
374 /* macros for extraction/creation of unsigned char/unsigned short values */
375 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
376 #define Lo8(v16) ((u8)((v16) & 0x00FF))
377 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
378 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
379 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
380 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
382 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
383 #define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
385 /* S-box lookup: 16 bits --> 16 bits */
386 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
388 /* fixed algorithm "parameters" */
389 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
390 #define TA_SIZE 6 /* 48-bit transmitter address */
391 #define TK_SIZE 16 /* 128-bit temporal key */
392 #define P1K_SIZE 10 /* 80-bit Phase1 key */
393 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
395 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
396 static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
398 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
399 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
400 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
401 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
402 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
403 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
404 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
405 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
406 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
407 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
408 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
409 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
410 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
411 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
412 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
413 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
414 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
415 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
416 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
417 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
418 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
419 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
420 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
421 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
422 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
423 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
424 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
425 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
426 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
427 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
428 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
429 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
432 { /* second half of table is unsigned char-reversed version of first! */
433 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
434 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
435 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
436 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
437 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
438 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
439 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
440 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
441 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
442 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
443 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
444 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
445 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
446 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
447 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
448 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
449 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
450 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
451 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
452 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
453 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
454 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
455 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
456 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
457 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
458 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
459 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
460 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
461 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
462 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
463 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
464 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
469 **********************************************************************
470 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
473 * tk[] = temporal key [128 bits]
474 * ta[] = transmitter's MAC address [ 48 bits]
475 * iv32 = upper 32 bits of IV [ 32 bits]
477 * p1k[] = Phase 1 key [ 80 bits]
480 * This function only needs to be called every 2**16 packets,
481 * although in theory it could be called every packet.
483 **********************************************************************
485 static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
488 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
491 p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
492 p1k[3] = Mk16(ta[3], ta[2]);
493 p1k[4] = Mk16(ta[5], ta[4]);
495 /* Now compute an unbalanced Feistel cipher with 80-bit block */
496 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
497 for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add operation here is mod 2**16 */
498 p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));
499 p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));
500 p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));
501 p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));
502 p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));
503 p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
508 **********************************************************************
509 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
512 * tk[] = Temporal key [128 bits]
513 * p1k[] = Phase 1 output key [ 80 bits]
514 * iv16 = low 16 bits of IV counter [ 16 bits]
516 * rc4key[] = the key used to encrypt the packet [128 bits]
519 * The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
520 * across all packets using the same key TK value. Then, for a
521 * given value of TK[], this TKIP48 construction guarantees that
522 * the final RC4KEY value is unique across all packets.
524 * Suggested implementation optimization: if PPK[] is "overlaid"
525 * appropriately on RC4KEY[], there is no need for the final
526 * for loop below that copies the PPK[] result into RC4KEY[].
528 **********************************************************************
530 static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
533 u16 PPK[6]; /* temporary key for mixing */
534 /* Note: all adds in the PPK[] equations below are mod 2**16 */
535 for (i = 0; i < 5; i++)
536 PPK[i] = p1k[i]; /* first, copy P1K to PPK */
537 PPK[5] = p1k[4] + iv16; /* next, add in IV16 */
539 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
540 PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
541 PPK[1] += _S_(PPK[0] ^ TK16(1));
542 PPK[2] += _S_(PPK[1] ^ TK16(2));
543 PPK[3] += _S_(PPK[2] ^ TK16(3));
544 PPK[4] += _S_(PPK[3] ^ TK16(4));
545 PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
547 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
548 PPK[0] += RotR1(PPK[5] ^ TK16(6));
549 PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
550 PPK[2] += RotR1(PPK[1]);
551 PPK[3] += RotR1(PPK[2]);
552 PPK[4] += RotR1(PPK[3]);
553 PPK[5] += RotR1(PPK[4]);
554 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
555 /* value PPK[0..5] is guaranteed to be unique, as a function */
556 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */
557 /* is now a keyed permutation of {TA, IV32, IV16}. */
559 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
560 rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
561 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
562 rc4key[2] = Lo8(iv16);
563 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
565 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
566 for (i = 0; i < 6; i++) {
567 rc4key[4 + 2 * i] = Lo8(PPK[i]);
568 rc4key[5 + 2 * i] = Hi8(PPK[i]);
572 /* The hlen isn't include the IV */
573 u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
580 u8 hw_hdr_offset = 0;
581 struct arc4context mycontext;
582 int curfragnum, length;
584 u8 *pframe, *payload, *iv, *prwskey;
585 union pn48 dot11txpn;
586 struct sta_info *stainfo;
587 struct pkt_attrib *pattrib = &pxmitframe->attrib;
588 struct security_priv *psecuritypriv = &padapter->securitypriv;
589 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
592 if (!pxmitframe->buf_addr)
595 hw_hdr_offset = TXDESC_SIZE +
596 (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
597 pframe = pxmitframe->buf_addr + hw_hdr_offset;
598 /* 4 start to encrypt each fragment */
599 if (pattrib->encrypt == _TKIP_) {
601 stainfo = pattrib->psta;
603 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
606 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
608 if (is_multicast_ether_addr(pattrib->ra))
609 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
611 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
613 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
614 iv = pframe + pattrib->hdrlen;
615 payload = pframe + pattrib->iv_len + pattrib->hdrlen;
617 GET_TKIP_PN(iv, dot11txpn);
619 pnl = (u16)(dot11txpn.val);
620 pnh = (u32)(dot11txpn.val >> 16);
621 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
622 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
624 if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */
625 length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
626 RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
627 ("pattrib->iv_len=%x, pattrib->icv_len=%x\n",
628 pattrib->iv_len, pattrib->icv_len));
629 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
631 arcfour_init(&mycontext, rc4key, 16);
632 arcfour_encrypt(&mycontext, payload, payload, length);
633 arcfour_encrypt(&mycontext, payload + length, crc, 4);
635 length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
636 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
637 arcfour_init(&mycontext, rc4key, 16);
638 arcfour_encrypt(&mycontext, payload, payload, length);
639 arcfour_encrypt(&mycontext, payload + length, crc, 4);
641 pframe += pxmitpriv->frag_len;
642 pframe = (u8 *)round_up((size_t)(pframe), 4);
646 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo==NULL!!!\n", __func__));
653 /* The hlen isn't include the IV */
654 u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe)
661 struct arc4context mycontext;
663 u8 *pframe, *payload, *iv, *prwskey;
664 union pn48 dot11txpn;
665 struct sta_info *stainfo;
666 struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
667 struct security_priv *psecuritypriv = &padapter->securitypriv;
670 pframe = (unsigned char *)precvframe->pkt->data;
672 /* 4 start to decrypt recvframe */
673 if (prxattrib->encrypt == _TKIP_) {
674 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
676 if (is_multicast_ether_addr(prxattrib->ra)) {
677 if (!psecuritypriv->binstallGrpkey) {
679 DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
682 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
684 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
685 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
688 iv = pframe + prxattrib->hdrlen;
689 payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
690 length = precvframe->pkt->len - prxattrib->hdrlen - prxattrib->iv_len;
692 GET_TKIP_PN(iv, dot11txpn);
694 pnl = (u16)(dot11txpn.val);
695 pnh = (u32)(dot11txpn.val >> 16);
697 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
698 phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
700 /* 4 decrypt payload include icv */
702 arcfour_init(&mycontext, rc4key, 16);
703 arcfour_encrypt(&mycontext, payload, payload, length);
705 *((__le32 *)crc) = getcrc32(payload, length - 4);
707 if (crc[3] != payload[length - 1] ||
708 crc[2] != payload[length - 2] ||
709 crc[1] != payload[length - 3] ||
710 crc[0] != payload[length - 4]) {
711 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
712 ("rtw_wep_decrypt:icv error crc (%4ph)!=payload (%4ph)\n",
713 &crc, &payload[length - 4]));
717 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo==NULL!!!\n", __func__));
725 u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
727 int curfragnum, length;
728 u8 *pframe; /* *payload,*iv */
729 u8 hw_hdr_offset = 0;
730 struct sta_info *stainfo;
731 struct pkt_attrib *pattrib = &pxmitframe->attrib;
732 struct security_priv *psecuritypriv = &padapter->securitypriv;
733 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
735 void *crypto_private;
737 struct lib80211_crypto_ops *crypto_ops;
738 const int key_idx = is_multicast_ether_addr(pattrib->ra) ? psecuritypriv->dot118021XGrpKeyid : 0;
739 const int key_length = 16;
742 if (!pxmitframe->buf_addr)
745 hw_hdr_offset = TXDESC_SIZE +
746 (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
748 pframe = pxmitframe->buf_addr + hw_hdr_offset;
750 /* 4 start to encrypt each fragment */
751 if (pattrib->encrypt != _AES_)
755 stainfo = pattrib->psta;
757 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
760 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo==NULL!!!\n", __func__));
764 crypto_ops = lib80211_get_crypto_ops("CCMP");
766 if (is_multicast_ether_addr(pattrib->ra))
767 key = psecuritypriv->dot118021XGrpKey[key_idx].skey;
769 key = stainfo->dot118021x_UncstKey.skey;
776 crypto_private = crypto_ops->init(key_idx);
777 if (!crypto_private) {
782 if (crypto_ops->set_key(key, key_length, NULL, crypto_private) < 0) {
784 goto exit_crypto_ops_deinit;
787 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
789 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
790 if (curfragnum + 1 == pattrib->nr_frags)
791 length = pattrib->last_txcmdsz;
793 length = pxmitpriv->frag_len;
795 skb = dev_alloc_skb(length);
798 goto exit_crypto_ops_deinit;
801 skb_put_data(skb, pframe, length);
803 memmove(skb->data + pattrib->iv_len, skb->data, pattrib->hdrlen);
804 skb_pull(skb, pattrib->iv_len);
805 skb_trim(skb, skb->len - pattrib->icv_len);
807 if (crypto_ops->encrypt_mpdu(skb, pattrib->hdrlen, crypto_private)) {
810 goto exit_crypto_ops_deinit;
813 memcpy(pframe, skb->data, skb->len);
816 pframe = (u8 *)round_up((size_t)(pframe), 8);
821 exit_crypto_ops_deinit:
822 crypto_ops->deinit(crypto_private);
828 u32 rtw_aes_decrypt(struct adapter *padapter, struct recv_frame *precvframe)
830 struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
833 /* 4 start to encrypt each fragment */
834 if (prxattrib->encrypt == _AES_) {
835 struct sta_info *stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
839 const int key_length = 16, iv_len = 8, icv_len = 8;
840 struct sk_buff *skb = precvframe->pkt;
841 void *crypto_private = NULL;
842 u8 *key, *pframe = skb->data;
843 struct lib80211_crypto_ops *crypto_ops = lib80211_get_crypto_ops("CCMP");
844 struct security_priv *psecuritypriv = &padapter->securitypriv;
847 if (is_multicast_ether_addr(prxattrib->ra)) {
848 /* in concurrent we should use sw descrypt in group key, so we remove this message */
849 if (!psecuritypriv->binstallGrpkey) {
851 DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
854 key_idx = psecuritypriv->dot118021XGrpKeyid;
855 key = psecuritypriv->dot118021XGrpKey[key_idx].skey;
858 key = stainfo->dot118021x_UncstKey.skey;
863 goto exit_lib80211_ccmp;
866 memcpy(iv, pframe + prxattrib->hdrlen, iv_len);
867 memcpy(icv, pframe + skb->len - icv_len, icv_len);
869 crypto_private = crypto_ops->init(key_idx);
870 if (!crypto_private) {
872 goto exit_lib80211_ccmp;
874 if (crypto_ops->set_key(key, key_length, NULL, crypto_private) < 0) {
876 goto exit_lib80211_ccmp;
878 if (crypto_ops->decrypt_mpdu(skb, prxattrib->hdrlen, crypto_private)) {
880 goto exit_lib80211_ccmp;
883 memmove(pframe, pframe + iv_len, prxattrib->hdrlen);
884 skb_push(skb, iv_len);
885 skb_put(skb, icv_len);
887 memcpy(pframe + prxattrib->hdrlen, iv, iv_len);
888 memcpy(pframe + skb->len - icv_len, icv, icv_len);
891 if (crypto_ops && crypto_private)
892 crypto_ops->deinit(crypto_private);
894 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n"));