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

source code of linux/drivers/staging/rtl8723bs/core/rtw_security.c