2 ***************************************************************************
4 * 4F, No. 2 Technology 5th Rd.
5 * Science-based Industrial Park
6 * Hsin-chu, Taiwan, R.O.C.
8 * (c) Copyright 2002, Ralink Technology, Inc.
10 * All rights reserved. Ralink's source code is an unpublished work and the
11 * use of a copyright notice does not imply otherwise. This source code
12 * contains confidential trade secret material of Ralink Tech. Any attemp
13 * or participation in deciphering, decoding, reverse engineering or in any
14 * way altering the source code is stricitly prohibited, unless the prior
15 * written consent of Ralink Technology, Inc. is obtained.
16 ***************************************************************************
25 -------- ---------- ----------------------------------------------
26 Paul Wu 02-25-02 Initial
29 #include "rt_config.h"
31 // Rotation functions on 32 bit values
32 #define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n))) ) )
33 #define ROR32( A, n ) ROL32( (A), 32-(n) )
36 ========================================================================
39 Convert from UCHAR[] to ULONG in a portable way
42 pMICKey pointer to MIC Key
49 ========================================================================
51 ULONG
RTMPTkipGetUInt32(
57 for (i
= 0; i
< 4; i
++)
59 res
|= (*pMICKey
++) << (8 * i
);
66 ========================================================================
69 Convert from ULONG to UCHAR[] in a portable way
72 pDst pointer to destination for convert ULONG to UCHAR[]
73 val the value for convert
80 ========================================================================
82 VOID
RTMPTkipPutUInt32(
88 for(i
= 0; i
< 4; i
++)
90 *pDst
++ = (UCHAR
) val
;
96 ========================================================================
99 Calculate the MIC Value.
102 pAdapter Pointer to our adapter
103 pSrc Pointer to source data for Calculate MIC Value
104 Len Indicate the length of the source data
111 ========================================================================
114 IN PTKIP_KEY_INFO pTkip
,
118 register ULONG M
, L
, R
, nBytesInM
;
120 // load data from memory to register
123 nBytesInM
= pTkip
->nBytesInM
;
127 if((nBytesInM
== 0) && ((((ULONG
)pSrc
) & 0x3) == 0))
132 M
= SWAP32(*(ULONG
*)pSrc
);
142 R
^= ((L
& 0xff00ff00) >> 8) | ((L
& 0x00ff00ff) << 8);
154 M
|= (*pSrc
<< (8* nBytesInM
));
165 R
^= ((L
& 0xff00ff00) >> 8) | ((L
& 0x00ff00ff) << 8);
178 { // misAlignment case
181 M
|= (*pSrc
<< (8* nBytesInM
));
192 R
^= ((L
& 0xff00ff00) >> 8) | ((L
& 0x00ff00ff) << 8);
205 // load data from register to memory
207 pTkip
->nBytesInM
= nBytesInM
;
213 ========================================================================
219 pAdapter Pointer to our adapter
225 the MIC Value is store in pAdapter->PrivateInfo.MIC
226 ========================================================================
229 IN PTKIP_KEY_INFO pTkip
)
231 static unsigned char Last
[] = {"\x5a\x00\x00\x00\x00\x00\x00\x00"};
233 // Append the minimum padding
234 RTMPTkipAppend(pTkip
, Last
, 8 - pTkip
->nBytesInM
);
236 // The appendByte function has already computed the result.
237 RTMPTkipPutUInt32(pTkip
->MIC
, pTkip
->L
);
238 RTMPTkipPutUInt32(pTkip
->MIC
+ 4, pTkip
->R
);
242 ========================================================================
245 Compare MIC value of received MSDU
248 pAdapter Pointer to our adapter
249 pSrc Pointer to the received Plain text data
250 pDA Pointer to DA address
251 pSA Pointer to SA address
252 pMICKey pointer to MIC Key
253 Len the length of the received plain text data exclude MIC value
256 TRUE MIC value matched
257 FALSE MIC value mismatched
261 ========================================================================
263 BOOLEAN
RTMPTkipCompareMICValue(
264 IN PRTMP_ADAPTER pAdapter
,
271 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
273 // Init MIC value calculation and reset the message
274 pAdapter
->PrivateInfo
.Rx
.L
= RTMPTkipGetUInt32(pMICKey
);
275 pAdapter
->PrivateInfo
.Rx
.R
= RTMPTkipGetUInt32(pMICKey
+ 4);
276 pAdapter
->PrivateInfo
.Rx
.nBytesInM
= 0;
277 pAdapter
->PrivateInfo
.Rx
.M
= 0;
280 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pDA
, 6);
282 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSA
, 6);
283 // Priority + 3 bytes of 0
284 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, Priority
, 4);
286 // Calculate MIC value from plain text data
287 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSrc
, Len
);
289 // Get MIC value from decrypted plain data
290 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Rx
);
292 // Move MIC value from MSDU, this steps should move to data path.
293 // Since the MIC value might cross MPDUs.
294 if(!NdisEqualMemory(pAdapter
->PrivateInfo
.Rx
.MIC
, pSrc
+ Len
, 8))
298 DBGPRINT(RT_DEBUG_ERROR
, "! TKIP MIC Error !\n"); //MIC error.
299 DBGPRINT(RT_DEBUG_INFO
, "Orig MIC value ="); //MIC error.
300 for (i
= 0; i
< 8; i
++)
302 DBGPRINT(RT_DEBUG_INFO
, "%02x:", *(UCHAR
*)(pSrc
+ Len
+ i
)); //MIC error.
304 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
305 DBGPRINT(RT_DEBUG_INFO
, "Calculated MIC value ="); //MIC error.
306 for (i
= 0; i
< 8; i
++)
308 DBGPRINT(RT_DEBUG_INFO
, "%02x:", pAdapter
->PrivateInfo
.Rx
.MIC
[i
]); //MIC error.
310 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
317 ========================================================================
320 Compare MIC value of received MSDU
323 pAdapter Pointer to our adapter
325 pSrc Pointer to the received Plain text data
326 pDA Pointer to DA address
327 pSA Pointer to SA address
328 pMICKey pointer to MIC Key
329 Len the length of the received plain text data exclude MIC value
332 TRUE MIC value matched
333 FALSE MIC value mismatched
337 ========================================================================
339 BOOLEAN
RTMPTkipCompareMICValueWithLLC(
340 IN PRTMP_ADAPTER pAdapter
,
348 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
350 // Init MIC value calculation and reset the message
351 pAdapter
->PrivateInfo
.Rx
.L
= RTMPTkipGetUInt32(pMICKey
);
352 pAdapter
->PrivateInfo
.Rx
.R
= RTMPTkipGetUInt32(pMICKey
+ 4);
353 pAdapter
->PrivateInfo
.Rx
.nBytesInM
= 0;
354 pAdapter
->PrivateInfo
.Rx
.M
= 0;
357 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pDA
, 6);
359 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSA
, 6);
360 // Priority + 3 bytes of 0
361 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, Priority
, 4);
363 // Start with LLC header
364 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pLLC
, 8);
366 // Calculate MIC value from plain text data
367 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Rx
, pSrc
, Len
);
369 // Get MIC value from decrypted plain data
370 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Rx
);
372 // Move MIC value from MSDU, this steps should move to data path.
373 // Since the MIC value might cross MPDUs.
374 if(!NdisEqualMemory(pAdapter
->PrivateInfo
.Rx
.MIC
, pSrc
+ Len
, 8))
378 DBGPRINT(RT_DEBUG_ERROR
, "! TKIP MIC Error !\n"); //MIC error.
379 DBGPRINT(RT_DEBUG_INFO
, "Orig MIC value ="); //MIC error.
380 for (i
= 0; i
< 8; i
++)
382 DBGPRINT(RT_DEBUG_INFO
, "%02x:", *(UCHAR
*)(pSrc
+ Len
+ i
)); //MIC error.
385 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
386 DBGPRINT(RT_DEBUG_INFO
, "Calculated MIC value ="); //MIC error.
387 for (i
= 0; i
< 8; i
++)
389 DBGPRINT(RT_DEBUG_INFO
, "%02x:", pAdapter
->PrivateInfo
.Rx
.MIC
[i
]); //MIC error.
392 DBGPRINT(RT_DEBUG_INFO
, "\n"); //MIC error.
399 ========================================================================
402 Copy frame from waiting queue into relative ring buffer and set
403 appropriate ASIC register to kick hardware transmit function
406 pAdapter Pointer to our adapter
407 PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
408 pEncap Pointer to LLC encap data
409 LenEncap Total encap length, might be 0 which indicates no encap
416 ========================================================================
418 VOID
RTMPCalculateMICValue(
419 IN PRTMP_ADAPTER pAdapter
,
420 IN
struct sk_buff
*skb
,
426 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
428 pSrc
= (PUCHAR
) skb
->data
;
430 // Init MIC value calculation and reset the message
431 pAdapter
->PrivateInfo
.Tx
.L
= RTMPTkipGetUInt32(pWpaKey
->TxMic
);
432 pAdapter
->PrivateInfo
.Tx
.R
= RTMPTkipGetUInt32(pWpaKey
->TxMic
+ 4);
433 pAdapter
->PrivateInfo
.Tx
.nBytesInM
= 0;
434 pAdapter
->PrivateInfo
.Tx
.M
= 0;
437 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
, 12);
439 // Priority + 3 bytes of 0
440 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, Priority
, 4);
445 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pEncap
, LenEncap
);
447 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
+ 12, skb
->len
- 12);
450 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
+ 14, skb
->len
- 14);
452 // Compute the final MIC Value
453 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Tx
);