1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 #include <linux/crc32.h>
8 #include <drv_types.h>
9 #include <crypto/aes.h>
10
11 static const char * const _security_type_str[] = {
12 "N/A",
13 "WEP40",
14 "TKIP",
15 "TKIP_WM",
16 "AES",
17 "WEP104",
18 "SMS4",
19 "WEP_WPA",
20 "BIP",
21 };
22
security_type_str(u8 value)23 const char *security_type_str(u8 value)
24 {
25 if (value <= _BIP_)
26 return _security_type_str[value];
27 return NULL;
28 }
29
30 /* WEP related ===== */
31
32 /*
33 Need to consider the fragment situation
34 */
rtw_wep_encrypt(struct adapter * padapter,u8 * pxmitframe)35 void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
36 { /* exclude ICV */
37 union {
38 __le32 f0;
39 unsigned char f1[4];
40 } crc;
41
42 signed int curfragnum, length;
43 u32 keylength;
44
45 u8 *pframe, *payload, *iv; /* wepkey */
46 u8 wepkey[16];
47 u8 hw_hdr_offset = 0;
48 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
49 struct security_priv *psecuritypriv = &padapter->securitypriv;
50 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
51 struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx;
52
53 if (!((struct xmit_frame *)pxmitframe)->buf_addr)
54 return;
55
56 hw_hdr_offset = TXDESC_OFFSET;
57 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
58
59 /* start to encrypt each fragment */
60 if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
61 keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
62
63 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
64 iv = pframe+pattrib->hdrlen;
65 memcpy(&wepkey[0], iv, 3);
66 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
67 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
68
69 if ((curfragnum+1) == pattrib->nr_frags) { /* the last fragment */
70
71 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
72
73 crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
74
75 arc4_setkey(ctx, wepkey, 3 + keylength);
76 arc4_crypt(ctx, payload, payload, length);
77 arc4_crypt(ctx, payload + length, crc.f1, 4);
78
79 } else {
80 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
81 crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
82 arc4_setkey(ctx, wepkey, 3 + keylength);
83 arc4_crypt(ctx, payload, payload, length);
84 arc4_crypt(ctx, payload + length, crc.f1, 4);
85
86 pframe += pxmitpriv->frag_len;
87 pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
88 }
89 }
90 }
91 }
92
rtw_wep_decrypt(struct adapter * padapter,u8 * precvframe)93 void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
94 {
95 /* exclude ICV */
96 u8 crc[4];
97 signed int length;
98 u32 keylength;
99 u8 *pframe, *payload, *iv, wepkey[16];
100 u8 keyindex;
101 struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);
102 struct security_priv *psecuritypriv = &padapter->securitypriv;
103 struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx;
104
105 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
106
107 /* start to decrypt recvframe */
108 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
109 iv = pframe+prxattrib->hdrlen;
110 /* keyindex =(iv[3]&0x3); */
111 keyindex = prxattrib->key_index;
112 keylength = psecuritypriv->dot11DefKeylen[keyindex];
113 memcpy(&wepkey[0], iv, 3);
114 /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
115 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
116 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
117
118 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
119
120 /* decrypt payload include icv */
121 arc4_setkey(ctx, wepkey, 3 + keylength);
122 arc4_crypt(ctx, payload, payload, length);
123
124 /* calculate icv and compare the icv */
125 *((u32 *)crc) = ~crc32_le(~0, payload, length - 4);
126
127 }
128 }
129
130 /* 3 =====TKIP related ===== */
131
secmicgetuint32(u8 * p)132 static u32 secmicgetuint32(u8 *p)
133 /* Convert from Byte[] to Us3232 in a portable way */
134 {
135 s32 i;
136 u32 res = 0;
137
138 for (i = 0; i < 4; i++)
139 res |= ((u32)(*p++)) << (8 * i);
140
141 return res;
142 }
143
secmicputuint32(u8 * p,u32 val)144 static void secmicputuint32(u8 *p, u32 val)
145 /* Convert from Us3232 to Byte[] in a portable way */
146 {
147 long i;
148
149 for (i = 0; i < 4; i++) {
150 *p++ = (u8) (val & 0xff);
151 val >>= 8;
152 }
153 }
154
secmicclear(struct mic_data * pmicdata)155 static void secmicclear(struct mic_data *pmicdata)
156 {
157 /* Reset the state to the empty message. */
158 pmicdata->L = pmicdata->K0;
159 pmicdata->R = pmicdata->K1;
160 pmicdata->nBytesInM = 0;
161 pmicdata->M = 0;
162 }
163
rtw_secmicsetkey(struct mic_data * pmicdata,u8 * key)164 void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
165 {
166 /* Set the key */
167 pmicdata->K0 = secmicgetuint32(key);
168 pmicdata->K1 = secmicgetuint32(key + 4);
169 /* and reset the message */
170 secmicclear(pmicdata);
171 }
172
rtw_secmicappendbyte(struct mic_data * pmicdata,u8 b)173 void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
174 {
175 /* Append the byte to our word-sized buffer */
176 pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
177 pmicdata->nBytesInM++;
178 /* Process the word if it is full. */
179 if (pmicdata->nBytesInM >= 4) {
180 pmicdata->L ^= pmicdata->M;
181 pmicdata->R ^= ROL32(pmicdata->L, 17);
182 pmicdata->L += pmicdata->R;
183 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
184 pmicdata->L += pmicdata->R;
185 pmicdata->R ^= ROL32(pmicdata->L, 3);
186 pmicdata->L += pmicdata->R;
187 pmicdata->R ^= ROR32(pmicdata->L, 2);
188 pmicdata->L += pmicdata->R;
189 /* Clear the buffer */
190 pmicdata->M = 0;
191 pmicdata->nBytesInM = 0;
192 }
193 }
194
rtw_secmicappend(struct mic_data * pmicdata,u8 * src,u32 nbytes)195 void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
196 {
197 /* This is simple */
198 while (nbytes > 0) {
199 rtw_secmicappendbyte(pmicdata, *src++);
200 nbytes--;
201 }
202 }
203
rtw_secgetmic(struct mic_data * pmicdata,u8 * dst)204 void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
205 {
206 /* Append the minimum padding */
207 rtw_secmicappendbyte(pmicdata, 0x5a);
208 rtw_secmicappendbyte(pmicdata, 0);
209 rtw_secmicappendbyte(pmicdata, 0);
210 rtw_secmicappendbyte(pmicdata, 0);
211 rtw_secmicappendbyte(pmicdata, 0);
212 /* and then zeroes until the length is a multiple of 4 */
213 while (pmicdata->nBytesInM != 0)
214 rtw_secmicappendbyte(pmicdata, 0);
215 /* The appendByte function has already computed the result. */
216 secmicputuint32(dst, pmicdata->L);
217 secmicputuint32(dst + 4, pmicdata->R);
218 /* Reset to the empty message. */
219 secmicclear(pmicdata);
220 }
221
222
rtw_seccalctkipmic(u8 * key,u8 * header,u8 * data,u32 data_len,u8 * mic_code,u8 pri)223 void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
224 {
225
226 struct mic_data micdata;
227 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
228
229 rtw_secmicsetkey(&micdata, key);
230 priority[0] = pri;
231
232 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
233 if (header[1] & 1) { /* ToDS == 1 */
234 rtw_secmicappend(&micdata, &header[16], 6); /* DA */
235 if (header[1] & 2) /* From Ds == 1 */
236 rtw_secmicappend(&micdata, &header[24], 6);
237 else
238 rtw_secmicappend(&micdata, &header[10], 6);
239 } else { /* ToDS == 0 */
240 rtw_secmicappend(&micdata, &header[4], 6); /* DA */
241 if (header[1] & 2) /* From Ds == 1 */
242 rtw_secmicappend(&micdata, &header[16], 6);
243 else
244 rtw_secmicappend(&micdata, &header[10], 6);
245 }
246 rtw_secmicappend(&micdata, &priority[0], 4);
247
248
249 rtw_secmicappend(&micdata, data, data_len);
250
251 rtw_secgetmic(&micdata, mic_code);
252 }
253
254 /* macros for extraction/creation of unsigned char/unsigned short values */
255 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
256 #define Lo8(v16) ((u8)((v16) & 0x00FF))
257 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
258 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
259 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
260 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
261
262 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
263 #define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])
264
265 /* S-box lookup: 16 bits --> 16 bits */
266 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
267
268 /* fixed algorithm "parameters" */
269 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
270
271 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
272 static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
273 {
274 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
275 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
276 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
277 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
278 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
279 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
280 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
281 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
282 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
283 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
284 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
285 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
286 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
287 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
288 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
289 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
290 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
291 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
292 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
293 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
294 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
295 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
296 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
297 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
298 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
299 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
300 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
301 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
302 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
303 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
304 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
305 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
306 },
307
308
309 { /* second half of table is unsigned char-reversed version of first! */
310 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
311 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
312 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
313 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
314 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
315 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
316 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
317 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
318 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
319 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
320 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
321 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
322 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
323 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
324 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
325 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
326 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
327 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
328 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
329 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
330 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
331 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
332 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
333 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
334 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
335 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
336 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
337 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
338 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
339 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
340 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
341 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
342 }
343 };
344
345 /*
346 **********************************************************************
347 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
348 *
349 * Inputs:
350 * tk[] = temporal key [128 bits]
351 * ta[] = transmitter's MAC address [ 48 bits]
352 * iv32 = upper 32 bits of IV [ 32 bits]
353 * Output:
354 * p1k[] = Phase 1 key [ 80 bits]
355 *
356 * Note:
357 * This function only needs to be called every 2**16 packets,
358 * although in theory it could be called every packet.
359 *
360 **********************************************************************
361 */
phase1(u16 * p1k,const u8 * tk,const u8 * ta,u32 iv32)362 static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
363 {
364 signed int i;
365
366 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
367 p1k[0] = Lo16(iv32);
368 p1k[1] = Hi16(iv32);
369 p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
370 p1k[3] = Mk16(ta[3], ta[2]);
371 p1k[4] = Mk16(ta[5], ta[4]);
372
373 /* Now compute an unbalanced Feistel cipher with 80-bit block */
374 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
375 for (i = 0; i < PHASE1_LOOP_CNT; i++) {
376 /* Each add operation here is mod 2**16 */
377 p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0));
378 p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2));
379 p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4));
380 p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6));
381 p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0));
382 p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
383 }
384 }
385
386
387 /*
388 **********************************************************************
389 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
390 *
391 * Inputs:
392 * tk[] = Temporal key [128 bits]
393 * p1k[] = Phase 1 output key [ 80 bits]
394 * iv16 = low 16 bits of IV counter [ 16 bits]
395 * Output:
396 * rc4key[] = the key used to encrypt the packet [128 bits]
397 *
398 * Note:
399 * The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
400 * across all packets using the same key TK value. Then, for a
401 * given value of TK[], this TKIP48 construction guarantees that
402 * the final RC4KEY value is unique across all packets.
403 *
404 * Suggested implementation optimization: if PPK[] is "overlaid"
405 * appropriately on RC4KEY[], there is no need for the final
406 * for loop below that copies the PPK[] result into RC4KEY[].
407 *
408 **********************************************************************
409 */
phase2(u8 * rc4key,const u8 * tk,const u16 * p1k,u16 iv16)410 static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
411 {
412 signed int i;
413 u16 PPK[6]; /* temporary key for mixing */
414
415 /* Note: all adds in the PPK[] equations below are mod 2**16 */
416 for (i = 0; i < 5; i++)
417 PPK[i] = p1k[i]; /* first, copy P1K to PPK */
418
419 PPK[5] = p1k[4]+iv16; /* next, add in IV16 */
420
421 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
422 PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
423 PPK[1] += _S_(PPK[0] ^ TK16(1));
424 PPK[2] += _S_(PPK[1] ^ TK16(2));
425 PPK[3] += _S_(PPK[2] ^ TK16(3));
426 PPK[4] += _S_(PPK[3] ^ TK16(4));
427 PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
428
429 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
430 PPK[0] += RotR1(PPK[5] ^ TK16(6));
431 PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
432 PPK[2] += RotR1(PPK[1]);
433 PPK[3] += RotR1(PPK[2]);
434 PPK[4] += RotR1(PPK[3]);
435 PPK[5] += RotR1(PPK[4]);
436 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
437 /* value PPK[0..5] is guaranteed to be unique, as a function */
438 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */
439 /* is now a keyed permutation of {TA, IV32, IV16}. */
440
441 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
442 rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
443 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
444 rc4key[2] = Lo8(iv16);
445 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
446
447
448 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
449 for (i = 0; i < 6; i++) {
450 rc4key[4+2*i] = Lo8(PPK[i]);
451 rc4key[5+2*i] = Hi8(PPK[i]);
452 }
453 }
454
455
456 /* The hlen isn't include the IV */
rtw_tkip_encrypt(struct adapter * padapter,u8 * pxmitframe)457 u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
458 { /* exclude ICV */
459 u16 pnl;
460 u32 pnh;
461 u8 rc4key[16];
462 u8 ttkey[16];
463 union {
464 __le32 f0;
465 u8 f1[4];
466 } crc;
467 u8 hw_hdr_offset = 0;
468 signed int curfragnum, length;
469
470 u8 *pframe, *payload, *iv, *prwskey;
471 union pn48 dot11txpn;
472 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
473 struct security_priv *psecuritypriv = &padapter->securitypriv;
474 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
475 struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx;
476 u32 res = _SUCCESS;
477
478 if (!((struct xmit_frame *)pxmitframe)->buf_addr)
479 return _FAIL;
480
481 hw_hdr_offset = TXDESC_OFFSET;
482 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
483
484 /* 4 start to encrypt each fragment */
485 if (pattrib->encrypt == _TKIP_) {
486
487 {
488 if (is_multicast_ether_addr(pattrib->ra))
489 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
490 else
491 prwskey = pattrib->dot118021x_UncstKey.skey;
492
493 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
494 iv = pframe+pattrib->hdrlen;
495 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
496
497 GET_TKIP_PN(iv, dot11txpn);
498
499 pnl = (u16)(dot11txpn.val);
500 pnh = (u32)(dot11txpn.val>>16);
501
502 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
503
504 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
505
506 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
507 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
508 crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
509
510 arc4_setkey(ctx, rc4key, 16);
511 arc4_crypt(ctx, payload, payload, length);
512 arc4_crypt(ctx, payload + length, crc.f1, 4);
513
514 } else {
515 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
516 crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
517
518 arc4_setkey(ctx, rc4key, 16);
519 arc4_crypt(ctx, payload, payload, length);
520 arc4_crypt(ctx, payload + length, crc.f1, 4);
521
522 pframe += pxmitpriv->frag_len;
523 pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
524 }
525 }
526 }
527 }
528 return res;
529 }
530
531
532 /* The hlen isn't include the IV */
rtw_tkip_decrypt(struct adapter * padapter,u8 * precvframe)533 u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
534 { /* exclude ICV */
535 u16 pnl;
536 u32 pnh;
537 u8 rc4key[16];
538 u8 ttkey[16];
539 u8 crc[4];
540 signed int length;
541
542 u8 *pframe, *payload, *iv, *prwskey;
543 union pn48 dot11txpn;
544 struct sta_info *stainfo;
545 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
546 struct security_priv *psecuritypriv = &padapter->securitypriv;
547 struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx;
548 u32 res = _SUCCESS;
549
550 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
551
552 /* 4 start to decrypt recvframe */
553 if (prxattrib->encrypt == _TKIP_) {
554 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
555 if (stainfo) {
556 if (is_multicast_ether_addr(prxattrib->ra)) {
557 static unsigned long start;
558 static u32 no_gkey_bc_cnt;
559 static u32 no_gkey_mc_cnt;
560
561 if (!psecuritypriv->binstallGrpkey) {
562 res = _FAIL;
563
564 if (start == 0)
565 start = jiffies;
566
567 if (is_broadcast_mac_addr(prxattrib->ra))
568 no_gkey_bc_cnt++;
569 else
570 no_gkey_mc_cnt++;
571
572 if (jiffies_to_msecs(jiffies - start) > 1000) {
573 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
574 netdev_dbg(padapter->pnetdev,
575 FUNC_ADPT_FMT " no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
576 FUNC_ADPT_ARG(padapter),
577 no_gkey_bc_cnt,
578 no_gkey_mc_cnt);
579 }
580 start = jiffies;
581 no_gkey_bc_cnt = 0;
582 no_gkey_mc_cnt = 0;
583 }
584 goto exit;
585 }
586
587 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
588 netdev_dbg(padapter->pnetdev,
589 FUNC_ADPT_FMT " gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
590 FUNC_ADPT_ARG(padapter),
591 no_gkey_bc_cnt,
592 no_gkey_mc_cnt);
593 }
594 start = 0;
595 no_gkey_bc_cnt = 0;
596 no_gkey_mc_cnt = 0;
597
598 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
599 } else {
600 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
601 }
602
603 iv = pframe+prxattrib->hdrlen;
604 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
605 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
606
607 GET_TKIP_PN(iv, dot11txpn);
608
609 pnl = (u16)(dot11txpn.val);
610 pnh = (u32)(dot11txpn.val>>16);
611
612 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
613 phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
614
615 /* 4 decrypt payload include icv */
616
617 arc4_setkey(ctx, rc4key, 16);
618 arc4_crypt(ctx, payload, payload, length);
619
620 *((u32 *)crc) = ~crc32_le(~0, payload, length - 4);
621
622 if (crc[3] != payload[length - 1] || crc[2] != payload[length - 2] ||
623 crc[1] != payload[length - 3] || crc[0] != payload[length - 4])
624 res = _FAIL;
625 } else {
626 res = _FAIL;
627 }
628 }
629 exit:
630 return res;
631 }
632
633
634 /* 3 =====AES related ===== */
635
636
637
638 #define MAX_MSG_SIZE 2048
639
640 /*****************************/
641 /**** Function Prototypes ****/
642 /*****************************/
643
644 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
645 static void construct_mic_iv(u8 *mic_header1,
646 signed int qc_exists,
647 signed int a4_exists,
648 u8 *mpdu,
649 uint payload_length,
650 u8 *pn_vector,
651 uint frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */
652 static void construct_mic_header1(u8 *mic_header1,
653 signed int header_length,
654 u8 *mpdu,
655 uint frtype); /* for CONFIG_IEEE80211W, none 11w also can use */
656 static void construct_mic_header2(u8 *mic_header2,
657 u8 *mpdu,
658 signed int a4_exists,
659 signed int qc_exists);
660 static void construct_ctr_preload(u8 *ctr_preload,
661 signed int a4_exists,
662 signed int qc_exists,
663 u8 *mpdu,
664 u8 *pn_vector,
665 signed int c,
666 uint frtype); /* for CONFIG_IEEE80211W, none 11w also can use */
667
668 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
669
670
671 /****************************************/
672 /* aes128k128d() */
673 /* Performs a 128 bit AES encrypt with */
674 /* 128 bit data. */
675 /****************************************/
aes128k128d(u8 * key,u8 * data,u8 * ciphertext)676 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
677 {
678 struct crypto_aes_ctx ctx;
679
680 aes_expandkey(&ctx, key, 16);
681 aes_encrypt(&ctx, ciphertext, data);
682 memzero_explicit(&ctx, sizeof(ctx));
683 }
684
685 /************************************************/
686 /* construct_mic_iv() */
687 /* Builds the MIC IV from header fields and PN */
688 /* Baron think the function is construct CCM */
689 /* nonce */
690 /************************************************/
construct_mic_iv(u8 * mic_iv,signed int qc_exists,signed int a4_exists,u8 * mpdu,uint payload_length,u8 * pn_vector,uint frtype)691 static void construct_mic_iv(u8 *mic_iv,
692 signed int qc_exists,
693 signed int a4_exists,
694 u8 *mpdu,
695 uint payload_length,
696 u8 *pn_vector,
697 uint frtype) /* add for CONFIG_IEEE80211W, none 11w also can use */
698 {
699 signed int i;
700
701 mic_iv[0] = 0x59;
702
703 if (qc_exists && a4_exists)
704 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
705
706 if (qc_exists && !a4_exists)
707 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
708
709 if (!qc_exists)
710 mic_iv[1] = 0x00;
711
712 /* 802.11w management frame should set management bit(4) */
713 if (frtype == WIFI_MGT_TYPE)
714 mic_iv[1] |= BIT(4);
715
716 for (i = 2; i < 8; i++)
717 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
718 #ifdef CONSISTENT_PN_ORDER
719 for (i = 8; i < 14; i++)
720 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
721 #else
722 for (i = 8; i < 14; i++)
723 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
724 #endif
725 mic_iv[14] = (unsigned char) (payload_length / 256);
726 mic_iv[15] = (unsigned char) (payload_length % 256);
727 }
728
729 /************************************************/
730 /* construct_mic_header1() */
731 /* Builds the first MIC header block from */
732 /* header fields. */
733 /* Build AAD SC, A1, A2 */
734 /************************************************/
construct_mic_header1(u8 * mic_header1,signed int header_length,u8 * mpdu,uint frtype)735 static void construct_mic_header1(u8 *mic_header1,
736 signed int header_length,
737 u8 *mpdu,
738 uint frtype) /* for CONFIG_IEEE80211W, none 11w also can use */
739 {
740 mic_header1[0] = (u8)((header_length - 2) / 256);
741 mic_header1[1] = (u8)((header_length - 2) % 256);
742
743 /* 802.11w management frame don't AND subtype bits 4, 5, 6 of frame control field */
744 if (frtype == WIFI_MGT_TYPE)
745 mic_header1[2] = mpdu[0];
746 else
747 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
748
749 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
750 mic_header1[4] = mpdu[4]; /* A1 */
751 mic_header1[5] = mpdu[5];
752 mic_header1[6] = mpdu[6];
753 mic_header1[7] = mpdu[7];
754 mic_header1[8] = mpdu[8];
755 mic_header1[9] = mpdu[9];
756 mic_header1[10] = mpdu[10]; /* A2 */
757 mic_header1[11] = mpdu[11];
758 mic_header1[12] = mpdu[12];
759 mic_header1[13] = mpdu[13];
760 mic_header1[14] = mpdu[14];
761 mic_header1[15] = mpdu[15];
762 }
763
764 /************************************************/
765 /* construct_mic_header2() */
766 /* Builds the last MIC header block from */
767 /* header fields. */
768 /************************************************/
construct_mic_header2(u8 * mic_header2,u8 * mpdu,signed int a4_exists,signed int qc_exists)769 static void construct_mic_header2(u8 *mic_header2,
770 u8 *mpdu,
771 signed int a4_exists,
772 signed int qc_exists)
773 {
774 signed int i;
775
776 for (i = 0; i < 16; i++)
777 mic_header2[i] = 0x00;
778
779 mic_header2[0] = mpdu[16]; /* A3 */
780 mic_header2[1] = mpdu[17];
781 mic_header2[2] = mpdu[18];
782 mic_header2[3] = mpdu[19];
783 mic_header2[4] = mpdu[20];
784 mic_header2[5] = mpdu[21];
785
786 mic_header2[6] = 0x00;
787 mic_header2[7] = 0x00; /* mpdu[23]; */
788
789 if (!qc_exists && a4_exists) {
790 for (i = 0; i < 6; i++)
791 mic_header2[8+i] = mpdu[24+i]; /* A4 */
792 }
793
794 if (qc_exists && !a4_exists) {
795 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
796 mic_header2[9] = mpdu[25] & 0x00;
797 }
798
799 if (qc_exists && a4_exists) {
800 for (i = 0; i < 6; i++)
801 mic_header2[8+i] = mpdu[24+i]; /* A4 */
802
803 mic_header2[14] = mpdu[30] & 0x0f;
804 mic_header2[15] = mpdu[31] & 0x00;
805 }
806 }
807
808 /************************************************/
809 /* construct_mic_header2() */
810 /* Builds the last MIC header block from */
811 /* header fields. */
812 /* Baron think the function is construct CCM */
813 /* nonce */
814 /************************************************/
construct_ctr_preload(u8 * ctr_preload,signed int a4_exists,signed int qc_exists,u8 * mpdu,u8 * pn_vector,signed int c,uint frtype)815 static void construct_ctr_preload(u8 *ctr_preload,
816 signed int a4_exists,
817 signed int qc_exists,
818 u8 *mpdu,
819 u8 *pn_vector,
820 signed int c,
821 uint frtype) /* for CONFIG_IEEE80211W, none 11w also can use */
822 {
823 signed int i = 0;
824
825 for (i = 0; i < 16; i++)
826 ctr_preload[i] = 0x00;
827 i = 0;
828
829 ctr_preload[0] = 0x01; /* flag */
830 if (qc_exists && a4_exists)
831 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
832 if (qc_exists && !a4_exists)
833 ctr_preload[1] = mpdu[24] & 0x0f;
834
835 /* 802.11w management frame should set management bit(4) */
836 if (frtype == WIFI_MGT_TYPE)
837 ctr_preload[1] |= BIT(4);
838
839 for (i = 2; i < 8; i++)
840 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
841 #ifdef CONSISTENT_PN_ORDER
842 for (i = 8; i < 14; i++)
843 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
844 #else
845 for (i = 8; i < 14; i++)
846 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
847 #endif
848 ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
849 ctr_preload[15] = (unsigned char) (c % 256);
850 }
851
852 /************************************/
853 /* bitwise_xor() */
854 /* A 128 bit, bitwise exclusive or */
855 /************************************/
bitwise_xor(u8 * ina,u8 * inb,u8 * out)856 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
857 {
858 signed int i;
859
860 for (i = 0; i < 16; i++)
861 out[i] = ina[i] ^ inb[i];
862 }
863
aes_cipher(u8 * key,uint hdrlen,u8 * pframe,uint plen)864 static signed int aes_cipher(u8 *key, uint hdrlen,
865 u8 *pframe, uint plen)
866 {
867 uint qc_exists, a4_exists, i, j, payload_remainder,
868 num_blocks, payload_index;
869
870 u8 pn_vector[6];
871 u8 mic_iv[16] = {};
872 u8 mic_header1[16] = {};
873 u8 mic_header2[16] = {};
874 u8 ctr_preload[16] = {};
875
876 /* Intermediate Buffers */
877 u8 chain_buffer[16] = {};
878 u8 aes_out[16] = {};
879 u8 padded_buffer[16] = {};
880 u8 mic[8];
881 uint frtype = GetFrameType(pframe);
882 uint frsubtype = GetFrameSubType(pframe);
883
884 frsubtype = frsubtype>>4;
885
886 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
887 a4_exists = 0;
888 else
889 a4_exists = 1;
890
891 if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
892 ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
893 ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
894 qc_exists = 1;
895 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
896 hdrlen += 2;
897
898 } else if ((frtype == WIFI_DATA) && /* add for CONFIG_IEEE80211W, none 11w also can use */
899 ((frsubtype == 0x08) ||
900 (frsubtype == 0x09) ||
901 (frsubtype == 0x0a) ||
902 (frsubtype == 0x0b))) {
903 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
904 hdrlen += 2;
905
906 qc_exists = 1;
907 } else {
908 qc_exists = 0;
909 }
910
911 pn_vector[0] = pframe[hdrlen];
912 pn_vector[1] = pframe[hdrlen+1];
913 pn_vector[2] = pframe[hdrlen+4];
914 pn_vector[3] = pframe[hdrlen+5];
915 pn_vector[4] = pframe[hdrlen+6];
916 pn_vector[5] = pframe[hdrlen+7];
917
918 construct_mic_iv(mic_iv,
919 qc_exists,
920 a4_exists,
921 pframe, /* message, */
922 plen,
923 pn_vector,
924 frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */
925
926 construct_mic_header1(mic_header1,
927 hdrlen,
928 pframe, /* message */
929 frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */
930
931 construct_mic_header2(mic_header2,
932 pframe, /* message, */
933 a4_exists,
934 qc_exists);
935
936 payload_remainder = plen % 16;
937 num_blocks = plen / 16;
938
939 /* Find start of payload */
940 payload_index = (hdrlen + 8);
941
942 /* Calculate MIC */
943 aes128k128d(key, mic_iv, aes_out);
944 bitwise_xor(aes_out, mic_header1, chain_buffer);
945 aes128k128d(key, chain_buffer, aes_out);
946 bitwise_xor(aes_out, mic_header2, chain_buffer);
947 aes128k128d(key, chain_buffer, aes_out);
948
949 for (i = 0; i < num_blocks; i++) {
950 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
951
952 payload_index += 16;
953 aes128k128d(key, chain_buffer, aes_out);
954 }
955
956 /* Add on the final payload block if it needs padding */
957 if (payload_remainder > 0) {
958 for (j = 0; j < 16; j++)
959 padded_buffer[j] = 0x00;
960 for (j = 0; j < payload_remainder; j++)
961 padded_buffer[j] = pframe[payload_index++];
962
963 bitwise_xor(aes_out, padded_buffer, chain_buffer);
964 aes128k128d(key, chain_buffer, aes_out);
965 }
966
967 for (j = 0 ; j < 8; j++)
968 mic[j] = aes_out[j];
969
970 /* Insert MIC into payload */
971 for (j = 0; j < 8; j++)
972 pframe[payload_index+j] = mic[j];
973
974 payload_index = hdrlen + 8;
975 for (i = 0; i < num_blocks; i++) {
976 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, /* message, */
977 pn_vector, i+1, frtype);
978 /* add for CONFIG_IEEE80211W, none 11w also can use */
979 aes128k128d(key, ctr_preload, aes_out);
980 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
981 for (j = 0; j < 16; j++)
982 pframe[payload_index++] = chain_buffer[j];
983 }
984
985 if (payload_remainder > 0) {
986 /* If there is a short final block, then pad it,*/
987 /* encrypt it and copy the unpadded part back */
988 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, /* message, */
989 pn_vector, num_blocks+1, frtype);
990 /* add for CONFIG_IEEE80211W, none 11w also can use */
991
992 for (j = 0; j < 16; j++)
993 padded_buffer[j] = 0x00;
994 for (j = 0; j < payload_remainder; j++)
995 padded_buffer[j] = pframe[payload_index+j];
996
997 aes128k128d(key, ctr_preload, aes_out);
998 bitwise_xor(aes_out, padded_buffer, chain_buffer);
999 for (j = 0; j < payload_remainder; j++)
1000 pframe[payload_index++] = chain_buffer[j];
1001 }
1002
1003 /* Encrypt the MIC */
1004 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, /* message, */
1005 pn_vector, 0, frtype);
1006 /* add for CONFIG_IEEE80211W, none 11w also can use */
1007
1008 for (j = 0; j < 16; j++)
1009 padded_buffer[j] = 0x00;
1010 for (j = 0; j < 8; j++)
1011 padded_buffer[j] = pframe[j+hdrlen+8+plen];
1012
1013 aes128k128d(key, ctr_preload, aes_out);
1014 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1015 for (j = 0; j < 8; j++)
1016 pframe[payload_index++] = chain_buffer[j];
1017
1018 return _SUCCESS;
1019 }
1020
rtw_aes_encrypt(struct adapter * padapter,u8 * pxmitframe)1021 u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
1022 { /* exclude ICV */
1023
1024 /*static*/
1025 /* unsigned char message[MAX_MSG_SIZE]; */
1026
1027 /* Intermediate Buffers */
1028 signed int curfragnum, length;
1029 u8 *pframe, *prwskey; /* *payload,*iv */
1030 u8 hw_hdr_offset = 0;
1031 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
1032 struct security_priv *psecuritypriv = &padapter->securitypriv;
1033 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1034
1035 u32 res = _SUCCESS;
1036
1037 if (!((struct xmit_frame *)pxmitframe)->buf_addr)
1038 return _FAIL;
1039
1040 hw_hdr_offset = TXDESC_OFFSET;
1041 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
1042
1043 /* 4 start to encrypt each fragment */
1044 if (pattrib->encrypt == _AES_) {
1045 if (is_multicast_ether_addr(pattrib->ra))
1046 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1047 else
1048 prwskey = pattrib->dot118021x_UncstKey.skey;
1049
1050 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1051 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
1052 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1053
1054 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1055 } else {
1056 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1057
1058 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1059 pframe += pxmitpriv->frag_len;
1060 pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
1061 }
1062 }
1063 }
1064 return res;
1065 }
1066
aes_decipher(u8 * key,uint hdrlen,u8 * pframe,uint plen)1067 static signed int aes_decipher(u8 *key, uint hdrlen,
1068 u8 *pframe, uint plen)
1069 {
1070 static u8 message[MAX_MSG_SIZE];
1071 uint qc_exists, a4_exists, i, j, payload_remainder,
1072 num_blocks, payload_index;
1073 signed int res = _SUCCESS;
1074 u8 pn_vector[6];
1075 u8 mic_iv[16] = {};
1076 u8 mic_header1[16] = {};
1077 u8 mic_header2[16] = {};
1078 u8 ctr_preload[16] = {};
1079
1080 /* Intermediate Buffers */
1081 u8 chain_buffer[16] = {};
1082 u8 aes_out[16] = {};
1083 u8 padded_buffer[16] = {};
1084 u8 mic[8];
1085
1086 uint frtype = GetFrameType(pframe);
1087 uint frsubtype = GetFrameSubType(pframe);
1088
1089 frsubtype = frsubtype>>4;
1090
1091 /* start to decrypt the payload */
1092
1093 num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */
1094
1095 payload_remainder = (plen-8) % 16;
1096
1097 pn_vector[0] = pframe[hdrlen];
1098 pn_vector[1] = pframe[hdrlen + 1];
1099 pn_vector[2] = pframe[hdrlen + 4];
1100 pn_vector[3] = pframe[hdrlen + 5];
1101 pn_vector[4] = pframe[hdrlen + 6];
1102 pn_vector[5] = pframe[hdrlen + 7];
1103
1104 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1105 a4_exists = 0;
1106 else
1107 a4_exists = 1;
1108
1109 if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1110 ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1111 ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1112 qc_exists = 1;
1113 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1114 hdrlen += 2;
1115
1116 } else if ((frtype == WIFI_DATA) && /* only for data packet . add for CONFIG_IEEE80211W, none 11w also can use */
1117 ((frsubtype == 0x08) ||
1118 (frsubtype == 0x09) ||
1119 (frsubtype == 0x0a) ||
1120 (frsubtype == 0x0b))) {
1121 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1122 hdrlen += 2;
1123
1124 qc_exists = 1;
1125 } else {
1126 qc_exists = 0;
1127 }
1128
1129 /* now, decrypt pframe with hdrlen offset and plen long */
1130
1131 payload_index = hdrlen + 8; /* 8 is for extiv */
1132
1133 for (i = 0; i < num_blocks; i++) {
1134 construct_ctr_preload(ctr_preload, a4_exists,
1135 qc_exists, pframe,
1136 pn_vector, i + 1,
1137 frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */
1138
1139 aes128k128d(key, ctr_preload, aes_out);
1140 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1141
1142 for (j = 0; j < 16; j++)
1143 pframe[payload_index++] = chain_buffer[j];
1144 }
1145
1146 if (payload_remainder > 0) {
1147 /* If there is a short final block, then pad it,*/
1148 /* encrypt it and copy the unpadded part back */
1149 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector,
1150 num_blocks+1, frtype);
1151 /* add for CONFIG_IEEE80211W, none 11w also can use */
1152
1153 for (j = 0; j < 16; j++)
1154 padded_buffer[j] = 0x00;
1155 for (j = 0; j < payload_remainder; j++)
1156 padded_buffer[j] = pframe[payload_index+j];
1157
1158 aes128k128d(key, ctr_preload, aes_out);
1159 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1160 for (j = 0; j < payload_remainder; j++)
1161 pframe[payload_index++] = chain_buffer[j];
1162 }
1163
1164 /* start to calculate the mic */
1165 if ((hdrlen + plen+8) <= MAX_MSG_SIZE)
1166 memcpy((void *)message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
1167
1168 pn_vector[0] = pframe[hdrlen];
1169 pn_vector[1] = pframe[hdrlen+1];
1170 pn_vector[2] = pframe[hdrlen+4];
1171 pn_vector[3] = pframe[hdrlen+5];
1172 pn_vector[4] = pframe[hdrlen+6];
1173 pn_vector[5] = pframe[hdrlen+7];
1174
1175 construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8, pn_vector, frtype);
1176 /* add for CONFIG_IEEE80211W, none 11w also can use */
1177
1178 construct_mic_header1(mic_header1, hdrlen, message, frtype);
1179 /* add for CONFIG_IEEE80211W, none 11w also can use */
1180 construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
1181
1182 payload_remainder = (plen-8) % 16;
1183 num_blocks = (plen-8) / 16;
1184
1185 /* Find start of payload */
1186 payload_index = (hdrlen + 8);
1187
1188 /* Calculate MIC */
1189 aes128k128d(key, mic_iv, aes_out);
1190 bitwise_xor(aes_out, mic_header1, chain_buffer);
1191 aes128k128d(key, chain_buffer, aes_out);
1192 bitwise_xor(aes_out, mic_header2, chain_buffer);
1193 aes128k128d(key, chain_buffer, aes_out);
1194
1195 for (i = 0; i < num_blocks; i++) {
1196 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1197
1198 payload_index += 16;
1199 aes128k128d(key, chain_buffer, aes_out);
1200 }
1201
1202 /* Add on the final payload block if it needs padding */
1203 if (payload_remainder > 0) {
1204 for (j = 0; j < 16; j++)
1205 padded_buffer[j] = 0x00;
1206 for (j = 0; j < payload_remainder; j++)
1207 padded_buffer[j] = message[payload_index++];
1208
1209 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1210 aes128k128d(key, chain_buffer, aes_out);
1211 }
1212
1213 for (j = 0; j < 8; j++)
1214 mic[j] = aes_out[j];
1215
1216 /* Insert MIC into payload */
1217 for (j = 0; j < 8; j++)
1218 message[payload_index+j] = mic[j];
1219
1220 payload_index = hdrlen + 8;
1221 for (i = 0; i < num_blocks; i++) {
1222 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i+1,
1223 frtype);
1224 /* add for CONFIG_IEEE80211W, none 11w also can use */
1225 aes128k128d(key, ctr_preload, aes_out);
1226 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1227 for (j = 0; j < 16; j++)
1228 message[payload_index++] = chain_buffer[j];
1229 }
1230
1231 if (payload_remainder > 0) {
1232 /* If there is a short final block, then pad it,*/
1233 /* encrypt it and copy the unpadded part back */
1234 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector,
1235 num_blocks+1, frtype);
1236 /* add for CONFIG_IEEE80211W, none 11w also can use */
1237
1238 for (j = 0; j < 16; j++)
1239 padded_buffer[j] = 0x00;
1240 for (j = 0; j < payload_remainder; j++)
1241 padded_buffer[j] = message[payload_index+j];
1242
1243 aes128k128d(key, ctr_preload, aes_out);
1244 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1245 for (j = 0; j < payload_remainder; j++)
1246 message[payload_index++] = chain_buffer[j];
1247 }
1248
1249 /* Encrypt the MIC */
1250 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0, frtype);
1251 /* add for CONFIG_IEEE80211W, none 11w also can use */
1252
1253 for (j = 0; j < 16; j++)
1254 padded_buffer[j] = 0x00;
1255 for (j = 0; j < 8; j++)
1256 padded_buffer[j] = message[j+hdrlen+8+plen-8];
1257
1258 aes128k128d(key, ctr_preload, aes_out);
1259 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1260 for (j = 0; j < 8; j++)
1261 message[payload_index++] = chain_buffer[j];
1262
1263 /* compare the mic */
1264 for (i = 0; i < 8; i++) {
1265 if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i])
1266 res = _FAIL;
1267 }
1268 return res;
1269 }
1270
rtw_aes_decrypt(struct adapter * padapter,u8 * precvframe)1271 u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
1272 { /* exclude ICV */
1273
1274 /*static*/
1275 /* unsigned char message[MAX_MSG_SIZE]; */
1276
1277 /* Intermediate Buffers */
1278
1279 signed int length;
1280 u8 *pframe, *prwskey; /* *payload,*iv */
1281 struct sta_info *stainfo;
1282 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1283 struct security_priv *psecuritypriv = &padapter->securitypriv;
1284 u32 res = _SUCCESS;
1285
1286 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1287 /* 4 start to encrypt each fragment */
1288 if (prxattrib->encrypt == _AES_) {
1289 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
1290 if (stainfo) {
1291 if (is_multicast_ether_addr(prxattrib->ra)) {
1292 static unsigned long start;
1293 static u32 no_gkey_bc_cnt;
1294 static u32 no_gkey_mc_cnt;
1295
1296 if (!psecuritypriv->binstallGrpkey) {
1297 res = _FAIL;
1298
1299 if (start == 0)
1300 start = jiffies;
1301
1302 if (is_broadcast_mac_addr(prxattrib->ra))
1303 no_gkey_bc_cnt++;
1304 else
1305 no_gkey_mc_cnt++;
1306
1307 if (jiffies_to_msecs(jiffies - start) > 1000) {
1308 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1309 netdev_dbg(padapter->pnetdev,
1310 FUNC_ADPT_FMT " no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1311 FUNC_ADPT_ARG(padapter),
1312 no_gkey_bc_cnt,
1313 no_gkey_mc_cnt);
1314 }
1315 start = jiffies;
1316 no_gkey_bc_cnt = 0;
1317 no_gkey_mc_cnt = 0;
1318 }
1319
1320 goto exit;
1321 }
1322
1323 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1324 netdev_dbg(padapter->pnetdev,
1325 FUNC_ADPT_FMT " gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1326 FUNC_ADPT_ARG(padapter),
1327 no_gkey_bc_cnt,
1328 no_gkey_mc_cnt);
1329 }
1330 start = 0;
1331 no_gkey_bc_cnt = 0;
1332 no_gkey_mc_cnt = 0;
1333
1334 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1335 if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1336 res = _FAIL;
1337 goto exit;
1338 }
1339 } else {
1340 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1341 }
1342
1343 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
1344
1345 res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1346
1347 } else {
1348 res = _FAIL;
1349 }
1350 }
1351 exit:
1352 return res;
1353 }
1354
rtw_BIP_verify(struct adapter * padapter,u8 * precvframe)1355 u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe)
1356 {
1357 struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1358 u8 *pframe;
1359 u8 *BIP_AAD, *p;
1360 u32 res = _FAIL;
1361 uint len, ori_len;
1362 struct ieee80211_hdr *pwlanhdr;
1363 u8 mic[16];
1364 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1365 __le16 le_tmp;
1366 __le64 le_tmp64;
1367
1368 ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE;
1369 BIP_AAD = rtw_zmalloc(ori_len);
1370
1371 if (!BIP_AAD)
1372 return _FAIL;
1373
1374 /* PKT start */
1375 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1376 /* mapping to wlan header */
1377 pwlanhdr = (struct ieee80211_hdr *)pframe;
1378 /* save the frame body + MME */
1379 memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1380 /* find MME IE pointer */
1381 p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, WLAN_EID_MMIE, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1382 /* Baron */
1383 if (p) {
1384 u16 keyid = 0;
1385 u64 temp_ipn = 0;
1386 /* save packet number */
1387 memcpy(&le_tmp64, p+4, 6);
1388 temp_ipn = le64_to_cpu(le_tmp64);
1389 /* BIP packet number should bigger than previous BIP packet */
1390 if (temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx)
1391 goto BIP_exit;
1392
1393 /* copy key index */
1394 memcpy(&le_tmp, p+2, 2);
1395 keyid = le16_to_cpu(le_tmp);
1396 if (keyid != padapter->securitypriv.dot11wBIPKeyid)
1397 goto BIP_exit;
1398
1399 /* clear the MIC field of MME to zero */
1400 memset(p+2+len-8, 0, 8);
1401
1402 /* conscruct AAD, copy frame control field */
1403 memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
1404 ClearRetry(BIP_AAD);
1405 ClearPwrMgt(BIP_AAD);
1406 ClearMData(BIP_AAD);
1407 /* conscruct AAD, copy address 1 to address 3 */
1408 memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
1409
1410 if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
1411 , BIP_AAD, ori_len, mic))
1412 goto BIP_exit;
1413
1414 /* MIC field should be last 8 bytes of packet (packet without FCS) */
1415 if (!memcmp(mic, pframe+pattrib->pkt_len-8, 8)) {
1416 pmlmeext->mgnt_80211w_IPN_rx = temp_ipn;
1417 res = _SUCCESS;
1418 } else {
1419 }
1420
1421 } else {
1422 res = RTW_RX_HANDLED;
1423 }
1424 BIP_exit:
1425
1426 kfree(BIP_AAD);
1427 return res;
1428 }
1429
gf_mulx(u8 * pad)1430 static void gf_mulx(u8 *pad)
1431 {
1432 int i, carry;
1433
1434 carry = pad[0] & 0x80;
1435 for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
1436 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
1437
1438 pad[AES_BLOCK_SIZE - 1] <<= 1;
1439 if (carry)
1440 pad[AES_BLOCK_SIZE - 1] ^= 0x87;
1441 }
1442
1443 /**
1444 * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
1445 * @key: 128-bit key for the hash operation
1446 * @num_elem: Number of elements in the data vector
1447 * @addr: Pointers to the data areas
1448 * @len: Lengths of the data blocks
1449 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
1450 * Returns: 0 on success, -1 on failure
1451 *
1452 * This is a mode for using block cipher (AES in this case) for authentication.
1453 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
1454 * (SP) 800-38B.
1455 */
omac1_aes_128_vector(u8 * key,size_t num_elem,u8 * addr[],size_t * len,u8 * mac)1456 static int omac1_aes_128_vector(u8 *key, size_t num_elem,
1457 u8 *addr[], size_t *len, u8 *mac)
1458 {
1459 struct crypto_aes_ctx ctx;
1460 u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
1461 u8 *pos, *end;
1462 size_t i, e, left, total_len;
1463 int ret;
1464
1465 ret = aes_expandkey(&ctx, key, 16);
1466 if (ret)
1467 return -1;
1468 memset(cbc, 0, AES_BLOCK_SIZE);
1469
1470 total_len = 0;
1471 for (e = 0; e < num_elem; e++)
1472 total_len += len[e];
1473 left = total_len;
1474
1475 e = 0;
1476 pos = addr[0];
1477 end = pos + len[0];
1478
1479 while (left >= AES_BLOCK_SIZE) {
1480 for (i = 0; i < AES_BLOCK_SIZE; i++) {
1481 cbc[i] ^= *pos++;
1482 if (pos >= end) {
1483 e++;
1484 pos = addr[e];
1485 end = pos + len[e];
1486 }
1487 }
1488 if (left > AES_BLOCK_SIZE)
1489 aes_encrypt(&ctx, cbc, cbc);
1490 left -= AES_BLOCK_SIZE;
1491 }
1492
1493 memset(pad, 0, AES_BLOCK_SIZE);
1494 aes_encrypt(&ctx, pad, pad);
1495 gf_mulx(pad);
1496
1497 if (left || total_len == 0) {
1498 for (i = 0; i < left; i++) {
1499 cbc[i] ^= *pos++;
1500 if (pos >= end) {
1501 e++;
1502 pos = addr[e];
1503 end = pos + len[e];
1504 }
1505 }
1506 cbc[left] ^= 0x80;
1507 gf_mulx(pad);
1508 }
1509
1510 for (i = 0; i < AES_BLOCK_SIZE; i++)
1511 pad[i] ^= cbc[i];
1512 aes_encrypt(&ctx, pad, mac);
1513 memzero_explicit(&ctx, sizeof(ctx));
1514 return 0;
1515 }
1516
1517 /**
1518 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
1519 * @key: 128-bit key for the hash operation
1520 * @data: Data buffer for which a MAC is determined
1521 * @data_len: Length of data buffer in bytes
1522 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
1523 * Returns: 0 on success, -1 on failure
1524 *
1525 * This is a mode for using block cipher (AES in this case) for authentication.
1526 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
1527 * (SP) 800-38B.
1528 * modify for CONFIG_IEEE80211W */
omac1_aes_128(u8 * key,u8 * data,size_t data_len,u8 * mac)1529 int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
1530 {
1531 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1532 }
1533
1534 /* Restore HW wep key setting according to key_mask */
rtw_sec_restore_wep_key(struct adapter * adapter)1535 void rtw_sec_restore_wep_key(struct adapter *adapter)
1536 {
1537 struct security_priv *securitypriv = &(adapter->securitypriv);
1538 signed int keyid;
1539
1540 if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) {
1541 for (keyid = 0; keyid < 4; keyid++) {
1542 if (securitypriv->key_mask & BIT(keyid)) {
1543 if (keyid == securitypriv->dot11PrivacyKeyIndex)
1544 rtw_set_key(adapter, securitypriv, keyid, 1, false);
1545 else
1546 rtw_set_key(adapter, securitypriv, keyid, 0, false);
1547 }
1548 }
1549 }
1550 }
1551
rtw_handle_tkip_countermeasure(struct adapter * adapter,const char * caller)1552 u8 rtw_handle_tkip_countermeasure(struct adapter *adapter, const char *caller)
1553 {
1554 struct security_priv *securitypriv = &(adapter->securitypriv);
1555 u8 status = _SUCCESS;
1556
1557 if (securitypriv->btkip_countermeasure) {
1558 unsigned long passing_ms = jiffies_to_msecs(jiffies - securitypriv->btkip_countermeasure_time);
1559
1560 if (passing_ms > 60*1000) {
1561 netdev_dbg(adapter->pnetdev,
1562 "%s(%s) countermeasure time:%lus > 60s\n",
1563 caller, ADPT_ARG(adapter),
1564 passing_ms / 1000);
1565 securitypriv->btkip_countermeasure = false;
1566 securitypriv->btkip_countermeasure_time = 0;
1567 } else {
1568 netdev_dbg(adapter->pnetdev,
1569 "%s(%s) countermeasure time:%lus < 60s\n",
1570 caller, ADPT_ARG(adapter),
1571 passing_ms / 1000);
1572 status = _FAIL;
1573 }
1574 }
1575
1576 return status;
1577 }
1578