1 /*************************************************************************
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 *************************************************************************
33 -------- ---------- ----------------------------------------------
34 Paul Wu 02-25-02 Initial
37 #include "rt_config.h"
39 // Rotation functions on 32 bit values
40 #define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n))) ) )
41 #define ROR32( A, n ) ROL32( (A), 32-(n) )
44 ========================================================================
47 Convert from UCHAR[] to ULONG in a portable way
50 pMICKey pointer to MIC Key
57 ========================================================================
59 ULONG
RTMPTkipGetUInt32(
65 for (i
= 0; i
< 4; i
++)
67 res
|= (*pMICKey
++) << (8 * i
);
74 ========================================================================
77 Convert from ULONG to UCHAR[] in a portable way
80 pDst pointer to destination for convert ULONG to UCHAR[]
81 val the value for convert
88 ========================================================================
90 VOID
RTMPTkipPutUInt32(
96 for(i
= 0; i
< 4; i
++)
98 *pDst
++ = (UCHAR
) val
;
104 ========================================================================
107 Calculate the MIC Value.
110 pAdapter Pointer to our adapter
111 pSrc Pointer to source data for Calculate MIC Value
112 Len Indicate the length of the source data
119 ========================================================================
122 IN PTKIP_KEY_INFO pTkip
,
126 register ULONG M
, L
, R
, nBytesInM
;
128 // load data from memory to register
131 nBytesInM
= pTkip
->nBytesInM
;
135 if((nBytesInM
== 0) && ((((unsigned long)pSrc
) & 0x3) == 0))
140 M
= SWAP32(*(ULONG
*)pSrc
);
150 R
^= ((L
& 0xff00ff00) >> 8) | ((L
& 0x00ff00ff) << 8);
162 M
|= (*pSrc
<< (8* nBytesInM
));
173 R
^= ((L
& 0xff00ff00) >> 8) | ((L
& 0x00ff00ff) << 8);
186 { // misAlignment case
189 M
|= (*pSrc
<< (8* nBytesInM
));
200 R
^= ((L
& 0xff00ff00) >> 8) | ((L
& 0x00ff00ff) << 8);
213 // load data from register to memory
215 pTkip
->nBytesInM
= nBytesInM
;
221 ========================================================================
227 pAdapter Pointer to our adapter
233 the MIC Value is store in pAdapter->PrivateInfo.MIC
234 ========================================================================
237 IN PTKIP_KEY_INFO pTkip
)
239 static unsigned char Last
[] = {"\x5a\x00\x00\x00\x00\x00\x00\x00"};
241 // Append the minimum padding
242 RTMPTkipAppend(pTkip
, Last
, 8 - pTkip
->nBytesInM
);
244 // The appendByte function has already computed the result.
245 RTMPTkipPutUInt32(pTkip
->MIC
, pTkip
->L
);
246 RTMPTkipPutUInt32(pTkip
->MIC
+ 4, pTkip
->R
);
250 ========================================================================
253 Compare MIC value of received MSDU
256 pAdapter Pointer to our adapter
257 pSrc Pointer to the received Plain text data
258 pDA Pointer to DA address
259 pSA Pointer to SA address
260 pMICKey pointer to MIC Key
261 Len the length of the received plain text data exclude MIC value
264 TRUE MIC value matched
265 FALSE MIC value mismatched
269 ========================================================================
271 BOOLEAN
RTMPTkipCompareMICValue(
272 IN PRTMP_ADAPTER pAdapter
,
279 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
281 // Init MIC value calculation and reset the message
282 pAdapter
->PrivateInfo
.Rx
.L
= RTMPTkipGetUInt32(pMICKey
);
283 pAdapter
->PrivateInfo
.Rx
.R
= RTMPTkipGetUInt32(pMICKey
+ 4);
284 pAdapter
->PrivateInfo
.Rx
.nBytesInM
= 0;
285 pAdapter
->PrivateInfo
.Rx
.M
= 0;
288 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pDA
, 6);
290 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSA
, 6);
291 // Priority + 3 bytes of 0
292 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, Priority
, 4);
294 // Calculate MIC value from plain text data
295 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSrc
, Len
);
297 // Get MIC value from decrypted plain data
298 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Rx
);
300 // Move MIC value from MSDU, this steps should move to data path.
301 // Since the MIC value might cross MPDUs.
302 if(!NdisEqualMemory(pAdapter
->PrivateInfo
.Rx
.MIC
, pSrc
+ Len
, 8))
306 DBGPRINT(RT_DEBUG_ERROR
, "! TKIP MIC Error !\n"); //MIC error.
307 DBGPRINT(RT_DEBUG_INFO
, "Orig MIC value ="); //MIC error.
308 for (i
= 0; i
< 8; i
++)
310 DBGPRINT(RT_DEBUG_INFO
, "%02x:", *(UCHAR
*)(pSrc
+ Len
+ i
)); //MIC error.
312 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
313 DBGPRINT(RT_DEBUG_INFO
, "Calculated MIC value ="); //MIC error.
314 for (i
= 0; i
< 8; i
++)
316 DBGPRINT(RT_DEBUG_INFO
, "%02x:", pAdapter
->PrivateInfo
.Rx
.MIC
[i
]); //MIC error.
318 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
325 ========================================================================
328 Compare MIC value of received MSDU
331 pAdapter Pointer to our adapter
333 pSrc Pointer to the received Plain text data
334 pDA Pointer to DA address
335 pSA Pointer to SA address
336 pMICKey pointer to MIC Key
337 Len the length of the received plain text data exclude MIC value
340 TRUE MIC value matched
341 FALSE MIC value mismatched
345 ========================================================================
347 BOOLEAN
RTMPTkipCompareMICValueWithLLC(
348 IN PRTMP_ADAPTER pAdapter
,
356 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
358 // Init MIC value calculation and reset the message
359 pAdapter
->PrivateInfo
.Rx
.L
= RTMPTkipGetUInt32(pMICKey
);
360 pAdapter
->PrivateInfo
.Rx
.R
= RTMPTkipGetUInt32(pMICKey
+ 4);
361 pAdapter
->PrivateInfo
.Rx
.nBytesInM
= 0;
362 pAdapter
->PrivateInfo
.Rx
.M
= 0;
365 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pDA
, 6);
367 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSA
, 6);
368 // Priority + 3 bytes of 0
369 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, Priority
, 4);
371 // Start with LLC header
372 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pLLC
, 8);
374 // Calculate MIC value from plain text data
375 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSrc
, Len
);
377 // Get MIC value from decrypted plain data
378 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Rx
);
380 // Move MIC value from MSDU, this steps should move to data path.
381 // Since the MIC value might cross MPDUs.
382 if(!NdisEqualMemory(pAdapter
->PrivateInfo
.Rx
.MIC
, pSrc
+ Len
, 8))
386 DBGPRINT(RT_DEBUG_ERROR
, "! TKIP MIC Error !\n"); //MIC error.
387 DBGPRINT(RT_DEBUG_INFO
, "Orig MIC value ="); //MIC error.
388 for (i
= 0; i
< 8; i
++)
390 DBGPRINT(RT_DEBUG_INFO
, "%02x:", *(UCHAR
*)(pSrc
+ Len
+ i
)); //MIC error.
393 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
394 DBGPRINT(RT_DEBUG_INFO
, "Calculated MIC value ="); //MIC error.
395 for (i
= 0; i
< 8; i
++)
397 DBGPRINT(RT_DEBUG_INFO
, "%02x:", pAdapter
->PrivateInfo
.Rx
.MIC
[i
]); //MIC error.
400 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
407 ========================================================================
410 Copy frame from waiting queue into relative ring buffer and set
411 appropriate ASIC register to kick hardware transmit function
414 pAdapter Pointer to our adapter
415 PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
416 pEncap Pointer to LLC encap data
417 LenEncap Total encap length, might be 0 which indicates no encap
424 ========================================================================
426 VOID
RTMPCalculateMICValue(
427 IN PRTMP_ADAPTER pAdapter
,
428 IN
struct sk_buff
*skb
,
434 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
436 pSrc
= (PUCHAR
) skb
->data
;
438 // Init MIC value calculation and reset the message
439 pAdapter
->PrivateInfo
.Tx
.L
= RTMPTkipGetUInt32(pWpaKey
->TxMic
);
440 pAdapter
->PrivateInfo
.Tx
.R
= RTMPTkipGetUInt32(pWpaKey
->TxMic
+ 4);
441 pAdapter
->PrivateInfo
.Tx
.nBytesInM
= 0;
442 pAdapter
->PrivateInfo
.Tx
.M
= 0;
445 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
, 12);
447 // Priority + 3 bytes of 0
448 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, Priority
, 4);
453 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pEncap
, LenEncap
);
455 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
+ 12, skb
->len
- 12);
458 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
+ 14, skb
->len
- 14);
460 // Compute the final MIC Value
461 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Tx
);