MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink.org / rtmp_tkip.c
blobc77ce9a7258541e6ad8a8448f0ddd018fd880bb9
1 /*
2 ***************************************************************************
3 * Ralink Tech Inc.
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 ***************************************************************************
18 Module Name:
19 rtmp_tkip.c
21 Abstract:
23 Revision History:
24 Who When What
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 ========================================================================
38 Routine Description:
39 Convert from UCHAR[] to ULONG in a portable way
41 Arguments:
42 pMICKey pointer to MIC Key
44 Return Value:
45 None
47 Note:
49 ========================================================================
51 ULONG RTMPTkipGetUInt32(
52 IN PUCHAR pMICKey)
54 ULONG res = 0;
55 int i;
57 for (i = 0; i < 4; i++)
59 res |= (*pMICKey++) << (8 * i);
62 return res;
66 ========================================================================
68 Routine Description:
69 Convert from ULONG to UCHAR[] in a portable way
71 Arguments:
72 pDst pointer to destination for convert ULONG to UCHAR[]
73 val the value for convert
75 Return Value:
76 None
78 Note:
80 ========================================================================
82 VOID RTMPTkipPutUInt32(
83 IN OUT PUCHAR pDst,
84 IN ULONG val)
86 int i;
88 for(i = 0; i < 4; i++)
90 *pDst++ = (UCHAR) val;
91 val >>= 8;
96 ========================================================================
98 Routine Description:
99 Calculate the MIC Value.
101 Arguments:
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
106 Return Value:
107 None
109 Note:
111 ========================================================================
113 VOID RTMPTkipAppend(
114 IN PTKIP_KEY_INFO pTkip,
115 IN PUCHAR pSrc,
116 IN UINT nBytes)
118 register ULONG M, L, R, nBytesInM;
120 // load data from memory to register
121 L = pTkip->L;
122 R = pTkip->R;
123 nBytesInM = pTkip->nBytesInM;
124 M = pTkip->M;
126 // Alignment case
127 if((nBytesInM == 0) && ((((ULONG)pSrc) & 0x3) == 0))
129 while(nBytes >= 4)
131 #ifdef BIG_ENDIAN
132 M = SWAP32(*(ULONG *)pSrc);
133 #else
134 M = *(ULONG *)pSrc;
135 #endif
136 pSrc += 4;
137 nBytes -= 4;
139 L ^= M;
140 R ^= ROL32( L, 17 );
141 L += R;
142 R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
143 L += R;
144 R ^= ROL32( L, 3 );
145 L += R;
146 R ^= ROR32( L, 2 );
147 L += R;
149 nBytesInM = 0;
150 M = 0;
152 while(nBytes > 0)
154 M |= (*pSrc << (8* nBytesInM));
156 nBytesInM++;
157 pSrc++;
158 nBytes--;
160 if( nBytesInM >= 4 )
162 L ^= M;
163 R ^= ROL32( L, 17 );
164 L += R;
165 R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
166 L += R;
167 R ^= ROL32( L, 3 );
168 L += R;
169 R ^= ROR32( L, 2 );
170 L += R;
171 // Clear the buffer
172 M = 0;
173 nBytesInM = 0;
177 else
178 { // misAlignment case
179 while(nBytes > 0)
181 M |= (*pSrc << (8* nBytesInM));
182 nBytesInM++;
184 pSrc++;
185 nBytes--;
187 if( nBytesInM >= 4 )
189 L ^= M;
190 R ^= ROL32( L, 17 );
191 L += R;
192 R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
193 L += R;
194 R ^= ROL32( L, 3 );
195 L += R;
196 R ^= ROR32( L, 2 );
197 L += R;
198 // Clear the buffer
199 M = 0;
200 nBytesInM = 0;
205 // load data from register to memory
206 pTkip->M = M;
207 pTkip->nBytesInM = nBytesInM;
208 pTkip->L = L;
209 pTkip->R = R;
213 ========================================================================
215 Routine Description:
216 Get the MIC Value.
218 Arguments:
219 pAdapter Pointer to our adapter
221 Return Value:
222 None
224 Note:
225 the MIC Value is store in pAdapter->PrivateInfo.MIC
226 ========================================================================
228 VOID RTMPTkipGetMIC(
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 ========================================================================
244 Routine Description:
245 Compare MIC value of received MSDU
247 Arguments:
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
255 Return Value:
256 TRUE MIC value matched
257 FALSE MIC value mismatched
259 Note:
261 ========================================================================
263 BOOLEAN RTMPTkipCompareMICValue(
264 IN PRTMP_ADAPTER pAdapter,
265 IN PUCHAR pSrc,
266 IN PUCHAR pDA,
267 IN PUCHAR pSA,
268 IN PUCHAR pMICKey,
269 IN UINT Len)
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;
279 // DA
280 RTMPTkipAppend(&pAdapter->PrivateInfo.Rx, pDA, 6);
281 // SA
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))
296 INT i;
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.
311 return (FALSE);
313 return (TRUE);
317 ========================================================================
319 Routine Description:
320 Compare MIC value of received MSDU
322 Arguments:
323 pAdapter Pointer to our adapter
324 pLLC LLC header
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
331 Return Value:
332 TRUE MIC value matched
333 FALSE MIC value mismatched
335 Note:
337 ========================================================================
339 BOOLEAN RTMPTkipCompareMICValueWithLLC(
340 IN PRTMP_ADAPTER pAdapter,
341 IN PUCHAR pLLC,
342 IN PUCHAR pSrc,
343 IN PUCHAR pDA,
344 IN PUCHAR pSA,
345 IN PUCHAR pMICKey,
346 IN UINT Len)
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;
356 // DA
357 RTMPTkipAppend(&pAdapter->PrivateInfo.Rx, pDA, 6);
358 // SA
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))
376 INT i;
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.
393 return (FALSE);
395 return (TRUE);
399 ========================================================================
401 Routine Description:
402 Copy frame from waiting queue into relative ring buffer and set
403 appropriate ASIC register to kick hardware transmit function
405 Arguments:
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
411 Return Value:
412 None
414 Note:
416 ========================================================================
418 VOID RTMPCalculateMICValue(
419 IN PRTMP_ADAPTER pAdapter,
420 IN struct sk_buff *skb,
421 IN PUCHAR pEncap,
422 IN INT LenEncap,
423 IN PWPA_KEY pWpaKey)
425 PUCHAR pSrc;
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;
436 // DA & SA field
437 RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pSrc, 12);
439 // Priority + 3 bytes of 0
440 RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, Priority, 4);
442 if (LenEncap > 0)
444 // LLC encapsulation
445 RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pEncap, LenEncap);
446 // Protocol Type
447 RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pSrc + 12, skb->len - 12);
449 else
450 RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pSrc + 14, skb->len - 14);
452 // Compute the final MIC Value
453 RTMPTkipGetMIC(&pAdapter->PrivateInfo.Tx);