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 Jan Lee 03-07-22 Initial
35 Paul Lin 03-11-28 Modify for supplicant
37 #include "rt_config.h"
39 UCHAR CipherWpaPskTkip
[] = {
41 0x00, 0x50, 0xf2, 0x01, // oui
42 0x01, 0x00, // Version
43 0x00, 0x50, 0xf2, 0x02, // Multicast
44 0x01, 0x00, // Number of unicast
45 0x00, 0x50, 0xf2, 0x02, // unicast
46 0x01, 0x00, // number of authentication method
47 0x00, 0x50, 0xf2, 0x02 // authentication
49 UCHAR CipherWpaPskTkipLen
= (sizeof(CipherWpaPskTkip
) / sizeof(UCHAR
));
51 UCHAR CipherWpaPskAes
[] = {
53 0x00, 0x50, 0xf2, 0x01, // oui
54 0x01, 0x00, // Version
55 0x00, 0x50, 0xf2, 0x04, // Multicast
56 0x01, 0x00, // Number of unicast
57 0x00, 0x50, 0xf2, 0x04, // unicast
58 0x01, 0x00, // number of authentication method
59 0x00, 0x50, 0xf2, 0x02 // authentication
61 UCHAR CipherWpaPskAesLen
= (sizeof(CipherWpaPskAes
) / sizeof(UCHAR
));
64 ========================================================================
67 Classify WPA EAP message type
70 EAPType Value of EAP message type
71 MsgType Internal Message definition for MLME state machine
74 TRUE Found appropriate message type
75 FALSE No appropriate message type
78 All these constants are defined in wpa.h
79 For supplicant, there is only EAPOL Key message avaliable
81 ========================================================================
83 BOOLEAN
WpaMsgTypeSubst(
90 *MsgType
= EAP_MSG_TYPE_EAPPacket
;
93 *MsgType
= EAP_MSG_TYPE_EAPOLStart
;
96 *MsgType
= EAP_MSG_TYPE_EAPOLLogoff
;
99 *MsgType
= EAP_MSG_TYPE_EAPOLKey
;
102 *MsgType
= EAP_MSG_TYPE_EAPOLASFAlert
;
105 DBGPRINT(RT_DEBUG_INFO
, "WpaMsgTypeSubst : return FALSE; \n");
112 ==========================================================================
114 association state machine init, including state transition and timer init
116 S - pointer to the association state machine
117 ==========================================================================
119 VOID
WpaPskStateMachineInit(
120 IN PRTMP_ADAPTER pAd
,
122 OUT STATE_MACHINE_FUNC Trans
[])
124 StateMachineInit(S
, (STATE_MACHINE_FUNC
*)Trans
, MAX_WPA_PSK_STATE
, MAX_WPA_PSK_MSG
, (STATE_MACHINE_FUNC
)Drop
, WPA_PSK_IDLE
, WPA_MACHINE_BASE
);
125 StateMachineSetAction(S
, WPA_PSK_IDLE
, EAP_MSG_TYPE_EAPOLKey
, (STATE_MACHINE_FUNC
)WpaEAPOLKeyAction
);
129 ==========================================================================
131 This is state machine function.
132 When receiving EAPOL packets which is for 802.1x key management.
133 Use both in WPA, and WPAPSK case.
134 In this function, further dispatch to different functions according to the received packet. 3 categories are :
135 1. normal 4-way pairwisekey and 2-way groupkey handshake
136 2. MIC error (Countermeasures attack) report packet from STA.
137 3. Request for pairwise/group key update from STA
139 ==========================================================================
141 VOID
WpaEAPOLKeyAction(
142 IN PRTMP_ADAPTER pAdapter
,
143 IN MLME_QUEUE_ELEM
*Elem
)
146 UCHAR ZeroReplay
[LEN_KEY_DESC_REPLAY
];
147 PKEY_DESCRIPTER pKeyDesc
;
149 DBGPRINT(RT_DEBUG_TRACE
, "-----> WpaEAPOLKeyAction\n");
150 // Get 802.11 header first
151 pKeyDesc
= (PKEY_DESCRIPTER
) &Elem
->Msg
[(LENGTH_802_11
+ LENGTH_802_1_H
+ LENGTH_EAPOL_H
)];
154 *(USHORT
*)((UCHAR
*)pKeyDesc
+1) = SWAP16(*(USHORT
*)((UCHAR
*)pKeyDesc
+1));
156 // Sanity check, this should only happen in WPA-PSK mode
157 if (pAdapter
->PortCfg
.AuthMode
!= Ndis802_11AuthModeWPAPSK
)
160 // 0. Debug print all bit information
161 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Description Version %d\n", pKeyDesc
->KeyInfo
.KeyDescVer
);
162 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Type %d\n", pKeyDesc
->KeyInfo
.KeyType
);
163 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Index %d\n", pKeyDesc
->KeyInfo
.KeyIndex
);
164 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Install %d\n", pKeyDesc
->KeyInfo
.Install
);
165 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Ack %d\n", pKeyDesc
->KeyInfo
.KeyAck
);
166 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key MIC %d\n", pKeyDesc
->KeyInfo
.KeyMic
);
167 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Secure %d\n", pKeyDesc
->KeyInfo
.Secure
);
168 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Error %d\n", pKeyDesc
->KeyInfo
.Error
);
169 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Request %d\n", pKeyDesc
->KeyInfo
.Request
);
170 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo DL %d\n", pKeyDesc
->KeyInfo
.DL
);
172 // 1. Check EAPOL frame version and type
173 if ((Elem
->Msg
[LENGTH_802_11
+LENGTH_802_1_H
] != EAPOL_VER
) || (pKeyDesc
->Type
!= RSN_KEY_DESC
))
175 DBGPRINT(RT_DEBUG_ERROR
, " Key descripter does not match with WPA rule \n");
179 // 2.Check Version for AES & TKIP
180 if ((pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
) && (pKeyDesc
->KeyInfo
.KeyDescVer
!= DESC_TYPE_AES
))
182 DBGPRINT(RT_DEBUG_ERROR
, " Key descripter version not match AES \n");
185 else if ((pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) && (pKeyDesc
->KeyInfo
.KeyDescVer
!= DESC_TYPE_TKIP
))
187 DBGPRINT(RT_DEBUG_ERROR
, " Key descripter version not match TKIP \n");
191 // First validate replay counter, only accept message with larger replay counter
192 // Let equal pass, some AP start with all zero replay counter
193 NdisZeroMemory(ZeroReplay
, LEN_KEY_DESC_REPLAY
);
194 if ((RTMPCompareMemory(pKeyDesc
->ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1) &&
195 (RTMPCompareMemory(pKeyDesc
->ReplayCounter
, ZeroReplay
, LEN_KEY_DESC_REPLAY
) != 0))
198 // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
199 MsgType
= EAPOL_MSG_INVALID
;
200 if ((pKeyDesc
->KeyInfo
.KeyType
== 1) &&
201 (pKeyDesc
->KeyInfo
.KeyIndex
== 0) &&
202 (pKeyDesc
->KeyInfo
.KeyAck
== 1) &&
203 (pKeyDesc
->KeyInfo
.KeyMic
== 0) &&
204 (pKeyDesc
->KeyInfo
.Secure
== 0) &&
205 (pKeyDesc
->KeyInfo
.Error
== 0) &&
206 (pKeyDesc
->KeyInfo
.Request
== 0))
208 MsgType
= EAPOL_PAIR_MSG_1
;
209 DBGPRINT(RT_DEBUG_TRACE
, "Receive EAPOL Key Pairwise Message 1\n");
211 else if ((pKeyDesc
->KeyInfo
.KeyType
== 1) &&
212 (pKeyDesc
->KeyInfo
.KeyIndex
== 0) &&
213 (pKeyDesc
->KeyInfo
.KeyAck
== 1) &&
214 (pKeyDesc
->KeyInfo
.KeyMic
== 1) &&
215 (pKeyDesc
->KeyInfo
.Secure
== 0) &&
216 (pKeyDesc
->KeyInfo
.Error
== 0) &&
217 (pKeyDesc
->KeyInfo
.Request
== 0))
219 MsgType
= EAPOL_PAIR_MSG_3
;
220 DBGPRINT(RT_DEBUG_TRACE
, "Receive EAPOL Key Pairwise Message 3\n");
222 else if ((pKeyDesc
->KeyInfo
.KeyType
== 0) &&
223 (pKeyDesc
->KeyInfo
.KeyIndex
!= 0) &&
224 (pKeyDesc
->KeyInfo
.KeyAck
== 1) &&
225 (pKeyDesc
->KeyInfo
.KeyMic
== 1) &&
226 (pKeyDesc
->KeyInfo
.Secure
== 1) &&
227 (pKeyDesc
->KeyInfo
.Error
== 0) &&
228 (pKeyDesc
->KeyInfo
.Request
== 0))
230 MsgType
= EAPOL_GROUP_MSG_1
;
231 DBGPRINT(RT_DEBUG_TRACE
, "Receive EAPOL Key Group Message 1\n");
234 DBGPRINT(RT_DEBUG_TRACE
, "Receive INVALID EAPOL Key Message\n");
237 *(USHORT
*)((UCHAR
*)pKeyDesc
+1) = SWAP16(*(USHORT
*)((UCHAR
*)pKeyDesc
+1));
240 // We will assume link is up (assoc suceess and port not secured).
241 // All state has to be able to process message from previous state
242 switch (pAdapter
->PortCfg
.WpaState
)
245 if (MsgType
== EAPOL_PAIR_MSG_1
)
247 WpaPairMsg1Action(pAdapter
, Elem
);
248 pAdapter
->PortCfg
.WpaState
= SS_WAIT_MSG_3
;
253 if (MsgType
== EAPOL_PAIR_MSG_1
)
255 WpaPairMsg1Action(pAdapter
, Elem
);
256 pAdapter
->PortCfg
.WpaState
= SS_WAIT_MSG_3
;
258 else if (MsgType
== EAPOL_PAIR_MSG_3
)
260 WpaPairMsg3Action(pAdapter
, Elem
);
261 pAdapter
->PortCfg
.WpaState
= SS_WAIT_GROUP
;
265 case SS_WAIT_GROUP
: // When doing group key exchange
266 case SS_FINISH
: // This happened when update group key
267 if (MsgType
== EAPOL_PAIR_MSG_1
)
269 WpaPairMsg1Action(pAdapter
, Elem
);
270 pAdapter
->PortCfg
.WpaState
= SS_WAIT_MSG_3
;
271 // Reset port secured variable
272 pAdapter
->PortCfg
.PortSecured
= WPA_802_1X_PORT_NOT_SECURED
;
274 else if (MsgType
== EAPOL_PAIR_MSG_3
)
276 WpaPairMsg3Action(pAdapter
, Elem
);
277 pAdapter
->PortCfg
.WpaState
= SS_WAIT_GROUP
;
278 // Reset port secured variable
279 pAdapter
->PortCfg
.PortSecured
= WPA_802_1X_PORT_NOT_SECURED
;
281 else if (MsgType
== EAPOL_GROUP_MSG_1
)
283 WpaGroupMsg1Action(pAdapter
, Elem
);
284 pAdapter
->PortCfg
.WpaState
= SS_FINISH
;
292 DBGPRINT(RT_DEBUG_TRACE
, "<----- WpaEAPOLKeyAction\n");
296 ========================================================================
299 Process Pairwise key 4-way handshaking
302 pAdapter Pointer to our adapter
310 ========================================================================
312 VOID
WpaPairMsg1Action(
313 IN PRTMP_ADAPTER pAdapter
,
314 IN MLME_QUEUE_ELEM
*Elem
)
316 PHEADER_802_11 pHeader
;
318 UCHAR
*OutBuffer
= NULL
;
319 HEADER_802_11 Header_802_11
;
321 UCHAR AckRate
= RATE_2
;
322 USHORT AckDuration
= 0;
324 UCHAR EAPHEAD
[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
329 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg1Action ----->\n");
331 pHeader
= (PHEADER_802_11
) Elem
->Msg
;
333 // Save Data Length to pDesc for receiving packet, then put in outgoing frame Data Len fields.
334 pMsg1
= (PEAPOL_PACKET
) &Elem
->Msg
[LENGTH_802_11
+ LENGTH_802_1_H
];
336 // Process message 1 from authenticator
337 // Key must be Pairwise key, already verified at callee.
338 // 1. Save Replay counter, it will use to verify message 3 and construct message 2
339 NdisMoveMemory(pAdapter
->PortCfg
.ReplayCounter
, pMsg1
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
342 NdisMoveMemory(pAdapter
->PortCfg
.ANonce
, pMsg1
->KeyDesc
.KeyNonce
, LEN_KEY_DESC_NONCE
);
344 // TSNonce <--- SNonce
345 // Generate random SNonce
346 GenRandom(pAdapter
, pAdapter
->PortCfg
.SNonce
);
348 // TPTK <--- Calc PTK(ANonce, TSNonce)
349 WpaCountPTK(pAdapter
->PortCfg
.PskKey
.Key
,
350 pAdapter
->PortCfg
.ANonce
,
351 pAdapter
->PortCfg
.Bssid
.Octet
,
352 pAdapter
->PortCfg
.SNonce
,
353 pAdapter
->CurrentAddress
,
357 // Save key to PTK entry
358 NdisMoveMemory(pAdapter
->PortCfg
.PTK
, PTK
, LEN_PTK
);
360 // =====================================
361 // Use Priority Ring & MiniportMMRequest
362 // =====================================
363 pAdapter
->Sequence
= ((pAdapter
->Sequence
) + 1) & (MAX_SEQ_NUMBER
);
364 WpaMacHeaderInit(pAdapter
, &Header_802_11
, 0, &pAdapter
->PortCfg
.Bssid
);
366 // ACK size is 14 include CRC, and its rate is based on real time information
367 AckRate
= pAdapter
->PortCfg
.ExpectedACKRate
[pAdapter
->PortCfg
.TxRate
];
368 AckDuration
= RTMPCalcDuration(pAdapter
, AckRate
, 14);
369 Header_802_11
.Controlhead
.Duration
= pAdapter
->PortCfg
.Dsifs
+ AckDuration
;
371 // Zero message 2 body
372 NdisZeroMemory(&Packet
, sizeof(Packet
));
373 Packet
.Version
= EAPOL_VER
;
374 Packet
.Type
= EAPOLKey
;
376 // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
378 Packet
.KeyDesc
.Type
= RSN_KEY_DESC
;
379 // 1. Key descriptor version and appropriate RSN IE
380 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
382 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= 2;
383 Packet
.KeyDesc
.KeyDataLen
[1] = CipherWpaPskAesLen
;
384 NdisMoveMemory(Packet
.KeyDesc
.KeyData
, CipherWpaPskAes
, CipherWpaPskAesLen
);
388 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= 1;
389 Packet
.KeyDesc
.KeyDataLen
[1] = CipherWpaPskTkipLen
;
390 NdisMoveMemory(Packet
.KeyDesc
.KeyData
, CipherWpaPskTkip
, CipherWpaPskTkipLen
);
392 // Update packet length after decide Key data payload
393 Packet
.Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
+ Packet
.KeyDesc
.KeyDataLen
[1];
395 // 2. Key Type PeerKey
396 Packet
.KeyDesc
.KeyInfo
.KeyType
= 1;
398 // 3. KeyMic field presented
399 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
402 NdisMoveMemory(Packet
.KeyDesc
.KeyNonce
, pAdapter
->PortCfg
.SNonce
, LEN_KEY_DESC_NONCE
);
404 // 5. Key Replay Count
405 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
408 *(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)));
411 // Send EAPOL(0, 1, 0, 0, 0, K, 0, TSNonce, 0, MIC(TPTK), 0)
412 // Out buffer for transmitting message 2
413 NStatus
= MlmeAllocateMemory(pAdapter
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
414 if (NStatus
!= NDIS_STATUS_SUCCESS
)
417 // Prepare EAPOL frame for MIC calculation
418 // Be careful, only EAPOL frame is counted for MIC calculation
419 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
420 Packet
.Len
[1] + 4, &Packet
,
423 // 5. Prepare and Fill MIC value
424 NdisZeroMemory(Mic
, sizeof(Mic
));
425 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
430 HMAC_SHA1(OutBuffer
, FrameLen
, PTK
, LEN_EAP_MICK
, digest
);
431 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
436 DBGPRINT(RT_DEBUG_INFO
, " PMK = ");
437 for (i
= 0; i
< 16; i
++)
438 DBGPRINT(RT_DEBUG_INFO
, "%2x-", pAdapter
->PortCfg
.PskKey
.Key
[i
]);
440 DBGPRINT(RT_DEBUG_INFO
, "\n PTK = ");
441 for (i
= 0; i
< 64; i
++)
442 DBGPRINT(RT_DEBUG_INFO
, "%2x-", pAdapter
->PortCfg
.PTK
[i
]);
443 DBGPRINT(RT_DEBUG_INFO
, "\n FrameLen = %d\n", FrameLen
);
445 hmac_md5(PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, Mic
);
447 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
450 // Make Transmitting frame
451 MakeOutgoingFrame(OutBuffer
, &FrameLen
, sizeof(MACHDR
), &Header_802_11
,
452 sizeof(EAPHEAD
), EAPHEAD
,
453 Packet
.Len
[1] + 4, &Packet
,
456 // Send using priority queue
457 MiniportMMRequest(pAdapter
, OutBuffer
, FrameLen
);
459 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg1Action <-----\n");
463 ========================================================================
466 Process Pairwise key 4-way handshaking
469 pAdapter Pointer to our adapter
477 ========================================================================
479 VOID
WpaPairMsg3Action(
480 IN PRTMP_ADAPTER pAdapter
,
481 IN MLME_QUEUE_ELEM
*Elem
)
483 PHEADER_802_11 pHeader
;
484 UCHAR
*OutBuffer
= NULL
;
485 HEADER_802_11 Header_802_11
;
487 UCHAR AckRate
= RATE_2
;
488 USHORT AckDuration
= 0;
490 UCHAR EAPHEAD
[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
494 UCHAR Mic
[16], OldMic
[16];
495 NDIS_802_11_KEY PeerKey
;
498 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg3Action ----->\n");
500 pHeader
= (PHEADER_802_11
) Elem
->Msg
;
502 // Process message 3 frame.
503 pMsg3
= (PEAPOL_PACKET
) &Elem
->Msg
[LENGTH_802_11
+ LENGTH_802_1_H
];
506 *(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)));
509 // 1. Verify RSN IE & cipher type match
510 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
512 if (pMsg3
->KeyDesc
.KeyInfo
.KeyDescVer
!= 2)
514 pTmp
= (PUCHAR
) &CipherWpaPskAes
;
518 if (pMsg3
->KeyDesc
.KeyInfo
.KeyDescVer
!= 1)
520 pTmp
= (PUCHAR
) &CipherWpaPskTkip
;
523 // Fix compatibility issue, when AP append nonsense data after auth mode with different size.
524 // We should qualify this kind of RSN as acceptable
525 if (!NdisEqualMemory((PUCHAR
) &pMsg3
->KeyDesc
.KeyData
[2], pTmp
+ 2, CipherWpaPskTkipLen
- 2))
527 DBGPRINT(RT_DEBUG_ERROR
, " RSN IE mismatched msg 3 of 4-way handshake!!!!!!!!!! \n");
531 DBGPRINT(RT_DEBUG_TRACE
, " RSN IE matched in msg 3 of 4-way handshake!!!!!!!!!! \n");
534 *(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)));
537 // 2. Check MIC value
538 // Save the MIC and replace with zero
539 NdisMoveMemory(OldMic
, pMsg3
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
540 NdisZeroMemory(pMsg3
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
541 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
546 HMAC_SHA1((PUCHAR
) pMsg3
, pMsg3
->Len
[1] + 4, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
547 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
551 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, (PUCHAR
) pMsg3
, pMsg3
->Len
[1] + 4, Mic
);
554 if (!NdisEqualMemory(OldMic
, Mic
, LEN_KEY_DESC_MIC
))
556 DBGPRINT(RT_DEBUG_ERROR
, " MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n");
560 DBGPRINT(RT_DEBUG_TRACE
, " MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n");
562 // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
563 if (RTMPCompareMemory(pMsg3
->KeyDesc
.ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1)
566 // Update new replay counter
567 NdisMoveMemory(pAdapter
->PortCfg
.ReplayCounter
, pMsg3
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
569 // 4. Double check ANonce
570 if (!NdisEqualMemory(pAdapter
->PortCfg
.ANonce
, pMsg3
->KeyDesc
.KeyNonce
, LEN_KEY_DESC_NONCE
))
573 // 5. Construct Message 4
574 // =====================================
575 // Use Priority Ring & MiniportMMRequest
576 // =====================================
577 pAdapter
->Sequence
= ((pAdapter
->Sequence
) + 1) & (MAX_SEQ_NUMBER
);
578 WpaMacHeaderInit(pAdapter
, &Header_802_11
, 0, &pAdapter
->PortCfg
.Bssid
);
580 // ACK size is 14 include CRC, and its rate is based on real time information
581 AckRate
= pAdapter
->PortCfg
.ExpectedACKRate
[pAdapter
->PortCfg
.TxRate
];
582 AckDuration
= RTMPCalcDuration(pAdapter
, AckRate
, 14);
583 Header_802_11
.Controlhead
.Duration
= pAdapter
->PortCfg
.Dsifs
+ AckDuration
;
585 // Zero message 4 body
586 NdisZeroMemory(&Packet
, sizeof(Packet
));
587 Packet
.Version
= EAPOL_VER
;
588 Packet
.Type
= EAPOLKey
;
589 Packet
.Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
; // No data field
592 // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
594 Packet
.KeyDesc
.Type
= RSN_KEY_DESC
;
597 *(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)));
600 // Key descriptor version and appropriate RSN IE
601 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= pMsg3
->KeyDesc
.KeyInfo
.KeyDescVer
;
604 Packet
.KeyDesc
.KeyInfo
.KeyType
= 1;
606 // KeyMic field presented
607 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
610 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pMsg3
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
612 *(USHORT
*)&Packet
.KeyDesc
.KeyInfo
= SWAP16(*(USHORT
*)&Packet
.KeyDesc
.KeyInfo
);
615 // Out buffer for transmitting message 4
616 NStatus
= MlmeAllocateMemory(pAdapter
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
617 if (NStatus
!= NDIS_STATUS_SUCCESS
)
620 // Prepare EAPOL frame for MIC calculation
621 // Be careful, only EAPOL frame is counted for MIC calculation
622 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
623 Packet
.Len
[1] + 4, &Packet
,
626 // Prepare and Fill MIC value
627 NdisZeroMemory(Mic
, sizeof(Mic
));
628 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
633 HMAC_SHA1(OutBuffer
, FrameLen
, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
634 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
638 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, Mic
);
640 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
644 // Make Transmitting frame
645 MakeOutgoingFrame(OutBuffer
, &FrameLen
, sizeof(MACHDR
), &Header_802_11
,
646 sizeof(EAPHEAD
), EAPHEAD
,
647 Packet
.Len
[1] + 4, &Packet
,
650 // 6. Send Message 4 to authenticator
651 // Send using priority queue
652 MiniportMMRequest(pAdapter
, OutBuffer
, FrameLen
);
655 NdisZeroMemory(&PeerKey
, sizeof(PeerKey
));
656 PeerKey
.Length
= sizeof(PeerKey
);
657 PeerKey
.KeyIndex
= 0xe0000000;
658 PeerKey
.KeyLength
= 16;
659 NdisMoveMemory(PeerKey
.BSSID
, pAdapter
->PortCfg
.Bssid
.Octet
, 6);
660 NdisMoveMemory(&PeerKey
.KeyRSC
, pMsg3
->KeyDesc
.KeyRsc
, LEN_KEY_DESC_RSC
);
661 NdisMoveMemory(PeerKey
.KeyMaterial
, &pAdapter
->PortCfg
.PTK
[32], 32);
662 // Call Add peer key function
663 RTMPWPAAddKeyProc(pAdapter
, &PeerKey
);
665 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg3Action <-----\n");
670 ========================================================================
673 Process Group key 2-way handshaking
676 pAdapter Pointer to our adapter
684 ========================================================================
686 VOID
WpaGroupMsg1Action(
687 IN PRTMP_ADAPTER pAdapter
,
688 IN MLME_QUEUE_ELEM
*Elem
)
690 PHEADER_802_11 pHeader
;
691 UCHAR
*OutBuffer
= NULL
;
692 HEADER_802_11 Header_802_11
;
694 UCHAR AckRate
= RATE_2
;
695 USHORT AckDuration
= 0;
697 UCHAR EAPHEAD
[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
699 PEAPOL_PACKET pGroup
;
700 UCHAR Mic
[16], OldMic
[16];
701 UCHAR GTK
[32], Key
[32];
702 NDIS_802_11_KEY GroupKey
;
705 DBGPRINT(RT_DEBUG_TRACE
, "WpaGroupMsg1Action ----->\n");
707 pHeader
= (PHEADER_802_11
) Elem
->Msg
;
709 // Process Group message 1 frame.
710 pGroup
= (PEAPOL_PACKET
) &Elem
->Msg
[LENGTH_802_11
+ LENGTH_802_1_H
];
712 // 1. Verify Replay counter
713 // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
714 if (RTMPCompareMemory(pGroup
->KeyDesc
.ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1)
717 // Update new replay counter
718 NdisMoveMemory(pAdapter
->PortCfg
.ReplayCounter
, pGroup
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
720 // 2. Verify MIC is valid
721 // Save the MIC and replace with zero
722 NdisMoveMemory(OldMic
, pGroup
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
723 NdisZeroMemory(pGroup
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
724 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
729 HMAC_SHA1((PUCHAR
) pGroup
, pGroup
->Len
[1] + 4, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
730 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
734 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, (PUCHAR
) pGroup
, pGroup
->Len
[1] + 4, Mic
);
737 if (!NdisEqualMemory(OldMic
, Mic
, LEN_KEY_DESC_MIC
))
739 DBGPRINT(RT_DEBUG_ERROR
, " MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n");
743 DBGPRINT(RT_DEBUG_TRACE
, " MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n");
746 *(USHORT
*)(&(pGroup
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pGroup
->KeyDesc
.KeyInfo
)));
749 // 3. Decrypt GTK from Key Data
750 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
752 if (pGroup
->KeyDesc
.KeyInfo
.KeyDescVer
!= 2)
755 AES_GTK_KEY_UNWRAP(&pAdapter
->PortCfg
.PTK
[16], GTK
, pGroup
->KeyDesc
.KeyData
);
761 if (pGroup
->KeyDesc
.KeyInfo
.KeyDescVer
!= 1)
764 // Construct 32 bytes RC4 Key
765 NdisMoveMemory(Key
, pGroup
->KeyDesc
.KeyIv
, 16);
766 NdisMoveMemory(&Key
[16], &pAdapter
->PortCfg
.PTK
[16], 16);
767 ARCFOUR_INIT(&pAdapter
->PrivateInfo
.WEPCONTEXT
, Key
, 32);
768 //discard first 256 bytes
769 for (i
= 0; i
< 256; i
++)
770 ARCFOUR_BYTE(&pAdapter
->PrivateInfo
.WEPCONTEXT
);
771 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
772 ARCFOUR_DECRYPT(&pAdapter
->PrivateInfo
.WEPCONTEXT
, GTK
, pGroup
->KeyDesc
.KeyData
, 32);
775 // 4. Construct Group Message 2
776 pAdapter
->Sequence
= ((pAdapter
->Sequence
) + 1) & (MAX_SEQ_NUMBER
);
777 WpaMacHeaderInit(pAdapter
, &Header_802_11
, 1, &pAdapter
->PortCfg
.Bssid
);
779 // ACK size is 14 include CRC, and its rate is based on real time information
780 AckRate
= pAdapter
->PortCfg
.ExpectedACKRate
[pAdapter
->PortCfg
.TxRate
];
781 AckDuration
= RTMPCalcDuration(pAdapter
, AckRate
, 14);
782 Header_802_11
.Controlhead
.Duration
= pAdapter
->PortCfg
.Dsifs
+ AckDuration
;
784 // Zero Group message 1 body
785 NdisZeroMemory(&Packet
, sizeof(Packet
));
786 Packet
.Version
= EAPOL_VER
;
787 Packet
.Type
= EAPOLKey
;
788 Packet
.Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
; // No data field
791 // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
793 Packet
.KeyDesc
.Type
= RSN_KEY_DESC
;
795 // Key descriptor version and appropriate RSN IE
796 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= pGroup
->KeyDesc
.KeyInfo
.KeyDescVer
;
798 // Key Type Group key
799 Packet
.KeyDesc
.KeyInfo
.KeyType
= 0;
801 // KeyMic field presented
802 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
805 Packet
.KeyDesc
.KeyInfo
.Secure
= 1;
808 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pGroup
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
811 *(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)));
814 // Out buffer for transmitting group message 2
815 NStatus
= MlmeAllocateMemory(pAdapter
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
816 if (NStatus
!= NDIS_STATUS_SUCCESS
)
819 // Prepare EAPOL frame for MIC calculation
820 // Be careful, only EAPOL frame is counted for MIC calculation
821 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
822 Packet
.Len
[1] + 4, &Packet
,
825 // Prepare and Fill MIC value
826 NdisZeroMemory(Mic
, sizeof(Mic
));
827 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
832 HMAC_SHA1(OutBuffer
, FrameLen
, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
833 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
838 DBGPRINT(RT_DEBUG_INFO
, "PTK = ");
839 for (i
= 0; i
< 64; i
++)
840 DBGPRINT(RT_DEBUG_INFO
, "%2x-", pAdapter
->PortCfg
.PTK
[i
]);
841 DBGPRINT(RT_DEBUG_INFO
, "\n FrameLen = %d\n", FrameLen
);
843 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, Mic
);
845 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
848 // Make Transmitting frame
849 MakeOutgoingFrame(OutBuffer
, &FrameLen
, sizeof(MACHDR
), &Header_802_11
,
850 sizeof(EAPHEAD
), EAPHEAD
,
851 Packet
.Len
[1] + 4, &Packet
,
854 // 5. Copy frame to Tx ring and prepare for encryption
855 WpaHardEncrypt(pAdapter
, OutBuffer
, FrameLen
);
857 // 6 Free allocated memory
858 MlmeFreeMemory(pAdapter
, OutBuffer
);
861 NdisZeroMemory(&GroupKey
, sizeof(GroupKey
));
862 GroupKey
.Length
= sizeof(GroupKey
);
863 GroupKey
.KeyIndex
= 0x20000000 | pGroup
->KeyDesc
.KeyInfo
.KeyIndex
;
864 GroupKey
.KeyLength
= 16;
865 NdisMoveMemory(GroupKey
.BSSID
, pAdapter
->PortCfg
.Bssid
.Octet
, 6);
866 NdisMoveMemory(GroupKey
.KeyMaterial
, GTK
, 32);
867 // Call Add peer key function
868 RTMPWPAAddKeyProc(pAdapter
, &GroupKey
);
870 DBGPRINT(RT_DEBUG_TRACE
, "WpaGroupMsg1Action <-----\n");
873 ========================================================================
879 pAdapter Pointer to our adapter
886 ========================================================================
888 VOID
WpaMacHeaderInit(
889 IN PRTMP_ADAPTER pAd
,
890 IN OUT PHEADER_802_11 Hdr
,
894 NdisZeroMemory(Hdr
, sizeof(HEADER_802_11
));
895 Hdr
->Controlhead
.Frame
.Type
= BTYPE_DATA
;
896 Hdr
->Controlhead
.Frame
.ToDs
= 1;
898 Hdr
->Controlhead
.Frame
.Wep
= 1;
900 // Addr1: DA, Addr2: BSSID, Addr3: SA
901 COPY_MAC_ADDR(&Hdr
->Controlhead
.Addr1
, pAddr1
);
902 COPY_MAC_ADDR(&Hdr
->Controlhead
.Addr2
, &pAd
->CurrentAddress
);
903 COPY_MAC_ADDR(&Hdr
->Addr3
, &pAd
->PortCfg
.Bssid
);
904 Hdr
->Sequence
= pAd
->Sequence
;
908 ========================================================================
911 Copy frame from waiting queue into relative ring buffer and set
912 appropriate ASIC register to kick hardware encryption before really
916 pAdapter Pointer to our adapter
917 PNDIS_PACKET Pointer to outgoing Ndis frame
918 NumberOfFrag Number of fragment required
925 ========================================================================
928 IN PRTMP_ADAPTER pAdapter
,
935 UCHAR CipherAlg
= CIPHER_NONE
;
944 PWPA_KEY pWpaKey
= NULL
;
945 UCHAR RetryMode
= SHORT_RETRY
;
946 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
948 PHEADER_802_11 pHeader
;
951 // Make sure Tx ring resource won't be used by other threads
952 NdisAcquireSpinLock(&pAdapter
->TxRingLock
, IrqFlags
);
954 FrameGap
= IFS_BACKOFF
; // Default frame gap mode
956 // outgoing frame always wakeup PHY to prevent frame lost and
957 // turn off PSM bit to improve performance
958 if (pAdapter
->PortCfg
.Psm
== PWR_SAVE
)
960 MlmeSetPsmBit(pAdapter
, PWR_ACTIVE
);
962 AsicForceWakeup(pAdapter
);
964 pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].FrameType
= BTYPE_DATA
;
966 pSrc
= pPacket
; // Point to start of MSDU
969 pWpaKey
= (PWPA_KEY
) &pAdapter
->PortCfg
.PairwiseKey
[0];
970 pWpaKey
->Type
= PAIRWISE_KEY
;
972 pHeader
= (PHEADER_802_11
) pSrc
;
974 for (idx
= 0; idx
< PAIRWISE_KEY_NO
; idx
++)
976 if ((NdisEqualMemory(&pHeader
->Controlhead
.Addr1
, pAdapter
->PortCfg
.PairwiseKey
[idx
].BssId
, 6)) &&
977 (pAdapter
->PortCfg
.PairwiseKey
[idx
].KeyLen
!= 0))
979 pWpaKey
= (PWPA_KEY
) &pAdapter
->PortCfg
.PairwiseKey
[idx
];
980 pWpaKey
->Type
= PAIRWISE_KEY
;
981 DBGPRINT(RT_DEBUG_TRACE
, "WpaHardEncrypt:(U) Tx Use Pairwise Key(%d)\n", idx
);
989 // No pairwise key, this should not happen
990 DBGPRINT(RT_DEBUG_ERROR
, "WpaHardEncrypt: No pairwise key!!!!!!!!!!!\n");
991 NdisReleaseSpinLock(&pAdapter
->TxRingLock
, IrqFlags
);
995 // Get the Tx Ring descriptor & Dma Buffer address
996 pDest
= (PUCHAR
) pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].va_data_addr
;
998 pTxD
= (PTXD_STRUC
) pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].va_addr
;
1000 pOriginDest
= pDest
;
1001 pDestTxD
= (PTXD_STRUC
) pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].va_addr
;
1004 RTMPDescriptorEndianChange((PUCHAR
)pTxD
, TYPE_TXD
);
1007 if ((pTxD
->Owner
== DESC_OWN_NIC
) || (pTxD
->CipherOwn
== DESC_OWN_NIC
))
1009 // Descriptor owned by NIC. No descriptor avaliable
1010 // This should not happen since caller guaranteed.
1011 // Make sure to release Tx ring resource
1012 DBGPRINT(RT_DEBUG_ERROR
, "WpaHardEncrypt: Descriptor owned by NIC. No descriptor avaliable!!!!!!!!!!!\n");
1013 pAdapter
->RalinkCounters
.TxRingErrCount
++;
1014 NdisReleaseSpinLock(&pAdapter
->TxRingLock
, IrqFlags
);
1017 if (pTxD
->Valid
== TRUE
)
1019 // Ndis packet of last round did not cleared.
1020 // This should not happen since caller guaranteed.
1021 // Make sure to release Tx ring resource
1022 pTxD
->Valid
= FALSE
;
1025 RTMPDescriptorEndianChange((PUCHAR
)pTxD
, TYPE_TXD
);
1028 DBGPRINT(RT_DEBUG_ERROR
, "WpaHardEncrypt: Ndis packet of last round did not cleared!!!!!!!!!!!\n");
1029 pAdapter
->RalinkCounters
.TxRingErrCount
++;
1030 NdisReleaseSpinLock(&pAdapter
->TxRingLock
, IrqFlags
);
1034 // Copy whole frame to Tx ring buffer
1035 NdisMoveMemory(pDest
, pPacket
, Len
);
1038 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
)
1043 // Prepare 8 bytes TKIP encapsulation for MPDU
1047 tkipIv
.IV16
.field
.rc0
= *(pWpaKey
->TxTsc
+ 1);
1048 tkipIv
.IV16
.field
.rc1
= (tkipIv
.IV16
.field
.rc0
| 0x20) & 0x7f;
1049 tkipIv
.IV16
.field
.rc2
= *pWpaKey
->TxTsc
;
1051 tkipIv
.IV16
.field
.Rsvd
= 0;
1052 tkipIv
.IV16
.field
.ExtIV
= 1; // 0: non-extended IV, 1: an extended IV
1053 tkipIv
.IV16
.field
.KeyID
= 0;
1055 //tkipIv.IV32 = *(PULONG)(pWpaKey->TxTsc + 2);
1056 NdisMoveMemory(&tkipIv
.IV32
, &pWpaKey
->TxTsc
[2], 4);
1059 pTxD
->Iv
= SWAP32(tkipIv
.IV16
.word
);
1061 pTxD
->Iv
= tkipIv
.IV16
.word
;
1064 *((PUCHAR
) &pTxD
->Eiv
) = *((PUCHAR
) &tkipIv
.IV32
+ 3);
1065 *((PUCHAR
) &pTxD
->Eiv
+ 1) = *((PUCHAR
) &tkipIv
.IV32
+ 2);
1066 *((PUCHAR
) &pTxD
->Eiv
+ 2) = *((PUCHAR
) &tkipIv
.IV32
+ 1);
1067 *((PUCHAR
) &pTxD
->Eiv
+ 3) = *((PUCHAR
) &tkipIv
.IV32
);
1070 // Increase TxTsc value for next transmission
1071 while (++pWpaKey
->TxTsc
[i
] == 0x0)
1079 pTxD
->IvOffset
= LENGTH_802_11
;
1082 NdisMoveMemory(pTxD
->Key
, pWpaKey
->Key
, 16);
1085 CipherAlg
= CIPHER_TKIP
;
1087 // Calculate MIC value
1088 // Init MIC value calculation and reset the message
1089 pAdapter
->PrivateInfo
.Tx
.L
= RTMPTkipGetUInt32(pWpaKey
->TxMic
);
1090 pAdapter
->PrivateInfo
.Tx
.R
= RTMPTkipGetUInt32(pWpaKey
->TxMic
+ 4);
1091 pAdapter
->PrivateInfo
.Tx
.nBytesInM
= 0;
1092 pAdapter
->PrivateInfo
.Tx
.M
= 0;
1095 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
+ 4, 12);
1097 // Priority + 3 bytes of 0
1098 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, Priority
, 4);
1100 pSrc
+= LENGTH_802_11
;
1101 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
, Len
- LENGTH_802_11
);
1102 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Tx
);
1104 NdisMoveMemory(pDest
, pAdapter
->PrivateInfo
.Tx
.MIC
, 8);
1106 // IV + EIV + ICV which ASIC added after encryption done
1109 else if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1115 pTmp
= (PUCHAR
) &Iv16
;
1116 *pTmp
= pWpaKey
->TxTsc
[0];
1117 *(pTmp
+ 1) = pWpaKey
->TxTsc
[1];
1121 Iv32
= *(PULONG
)(&pWpaKey
->TxTsc
[2]);
1123 // Increase TxTsc value for next transmission
1124 while (++pWpaKey
->TxTsc
[i
] == 0x0)
1132 NdisMoveMemory(&pTxD
->Iv
, &Iv16
, 4);
1135 NdisMoveMemory(&pTxD
->Eiv
, &Iv32
, 4);
1138 pTxD
->IvOffset
= LENGTH_802_11
;
1141 NdisMoveMemory(pTxD
->Key
, pWpaKey
->Key
, 16);
1144 CipherAlg
= CIPHER_AES
;
1146 // IV + EIV + HW MIC
1151 RTMPFrameEndianChange(pAdapter
, pOriginDest
, DIR_WRITE
, FALSE
);
1152 RTMPDescriptorEndianChange((PUCHAR
)pTxD
, TYPE_TXD
);
1157 RTMPWriteTxDescriptor(pTxD
, TRUE
, CipherAlg
, TRUE
, FALSE
, FALSE
, RetryMode
, FrameGap
,
1158 pAdapter
->PortCfg
.TxRate
, 4, Len
, pAdapter
->PortCfg
.TxPreambleInUsed
, 0);
1160 // Increase & maintain Tx Ring Index
1161 pAdapter
->CurEncryptIndex
++;
1162 if (pAdapter
->CurEncryptIndex
>= TX_RING_SIZE
)
1164 pAdapter
->CurEncryptIndex
= 0;
1166 pAdapter
->RalinkCounters
.EncryptCount
++;
1168 // Kick Encrypt Control Register at the end of all ring buffer preparation
1169 RTMP_IO_WRITE32(pAdapter
, SECCSR1
, 0x1);
1171 // Make sure to release Tx ring resource
1172 NdisReleaseSpinLock(&pAdapter
->TxRingLock
, IrqFlags
);
1176 ========================================================================
1178 Routine Description:
1187 ========================================================================
1197 UCHAR k_ipad
[65]; /* inner padding - key XORd with ipad */
1198 UCHAR k_opad
[65]; /* outer padding - key XORd with opad */
1201 // if key is longer than 64 bytes reset it to key=SHA1(key)
1206 SHAUpdate(&tctx
, key
, key_len
);
1207 SHAFinal(&tctx
, key
);
1210 NdisZeroMemory(k_ipad
, sizeof(k_ipad
));
1211 NdisZeroMemory(k_opad
, sizeof(k_opad
));
1212 NdisMoveMemory(k_ipad
, key
, key_len
);
1213 NdisMoveMemory(k_opad
, key
, key_len
);
1215 // XOR key with ipad and opad values
1216 for (i
= 0; i
< 64; i
++)
1222 // perform inner SHA1
1223 SHAInit(&context
); /* init context for 1st pass */
1224 SHAUpdate(&context
, k_ipad
, 64); /* start with inner pad */
1225 SHAUpdate(&context
, text
, text_len
); /* then text of datagram */
1226 SHAFinal(&context
, digest
); /* finish up 1st pass */
1228 //perform outer SHA1
1229 SHAInit(&context
); /* init context for 2nd pass */
1230 SHAUpdate(&context
, k_opad
, 64); /* start with outer pad */
1231 SHAUpdate(&context
, digest
, 20); /* then results of 1st hash */
1232 SHAFinal(&context
, digest
); /* finish up 2nd pass */
1236 ========================================================================
1238 Routine Description:
1248 ========================================================================
1262 INT currentindex
= 0;
1265 NdisMoveMemory(input
, prefix
, prefix_len
);
1266 input
[prefix_len
] = 0;
1267 NdisMoveMemory(&input
[prefix_len
+ 1], data
, data_len
);
1268 total_len
= prefix_len
+ 1 + data_len
;
1269 input
[total_len
] = 0;
1271 for (i
= 0; i
< (len
+ 19) / 20; i
++)
1273 HMAC_SHA1(input
, total_len
, key
, key_len
, &output
[currentindex
]);
1275 input
[total_len
- 1]++;
1280 ========================================================================
1282 Routine Description:
1288 Output Store the TPTK
1292 ========================================================================
1303 UCHAR concatenation
[76];
1306 UCHAR Prefix
[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
1307 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
1309 NdisZeroMemory(temp
, sizeof(temp
));
1311 // Get smaller address
1312 if (RTMPCompareMemory(SA
, AA
, 6) == 1)
1313 NdisMoveMemory(concatenation
, AA
, 6);
1315 NdisMoveMemory(concatenation
, SA
, 6);
1318 // Get larger address
1319 if (RTMPCompareMemory(SA
, AA
, 6) == 1)
1320 NdisMoveMemory(&concatenation
[CurrPos
], SA
, 6);
1322 NdisMoveMemory(&concatenation
[CurrPos
], AA
, 6);
1325 // Get smaller address
1326 if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 1)
1327 NdisMoveMemory(&concatenation
[CurrPos
], SNonce
, 32);
1329 NdisMoveMemory(&concatenation
[CurrPos
], ANonce
, 32);
1332 // Get larger address
1333 if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 1)
1334 NdisMoveMemory(&concatenation
[CurrPos
], ANonce
, 32);
1336 NdisMoveMemory(&concatenation
[CurrPos
], SNonce
, 32);
1339 PRF(PMK
, LEN_MASTER_KEY
, Prefix
, 22, concatenation
, 76 , output
, len
);
1343 ========================================================================
1345 Routine Description:
1346 Misc function to Generate random number
1355 ========================================================================
1358 IN PRTMP_ADAPTER pAd
,
1362 UCHAR local
[80], KeyCounter
[32];
1365 UCHAR prefix
[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
1367 NdisZeroMemory(result
, 80);
1368 NdisZeroMemory(local
, 80);
1369 NdisZeroMemory(KeyCounter
, 32);
1370 NdisMoveMemory(local
, pAd
->CurrentAddress
, ETH_LENGTH_OF_ADDRESS
);
1372 for (i
= 0; i
< 32; i
++)
1374 curr
= ETH_LENGTH_OF_ADDRESS
;
1375 CurrentTime
= jiffies
;
1376 NdisMoveMemory(local
, pAd
->CurrentAddress
, ETH_LENGTH_OF_ADDRESS
);
1377 curr
+= ETH_LENGTH_OF_ADDRESS
;
1378 NdisMoveMemory(&local
[curr
], &CurrentTime
, sizeof(CurrentTime
));
1379 curr
+= sizeof(CurrentTime
);
1380 NdisMoveMemory(&local
[curr
], result
, 32);
1382 NdisMoveMemory(&local
[curr
], &i
, 2);
1384 PRF(KeyCounter
, 32, prefix
,12, local
, curr
, result
, 32);
1386 NdisMoveMemory(random
, result
, 32);
1390 ========================================================================
1392 Routine Description:
1393 Misc function to decrypt AES body
1400 This function references to RFC 3394 for aes key unwrap algorithm.
1402 ========================================================================
1404 VOID
AES_GTK_KEY_UNWRAP(
1406 OUT UCHAR
*plaintext
,
1407 IN UCHAR
*ciphertext
)
1409 UCHAR A
[8], BIN
[16], BOUT
[16];
1418 NdisMoveMemory(A
, ciphertext
, 8);
1420 NdisMoveMemory(R1
, &ciphertext
[8], 8);
1422 NdisMoveMemory(R2
, &ciphertext
[16], 8);
1424 aes_set_key(&aesctx
, key
, 128);
1426 for (j
= 5; j
>= 0; j
--)
1428 xor = num_blocks
* j
+ 2;
1429 NdisMoveMemory(BIN
, A
, 8);
1430 BIN
[7] = A
[7] ^ xor;
1431 NdisMoveMemory(&BIN
[8], R2
, 8);
1432 aes_decrypt(&aesctx
, BIN
, BOUT
);
1433 NdisMoveMemory(A
, &BOUT
[0], 8);
1434 NdisMoveMemory(R2
, &BOUT
[8], 8);
1436 xor = num_blocks
* j
+ 1;
1437 NdisMoveMemory(BIN
, A
, 8);
1438 BIN
[7] = A
[7] ^ xor;
1439 NdisMoveMemory(&BIN
[8], R1
, 8);
1440 aes_decrypt(&aesctx
, BIN
, BOUT
);
1441 NdisMoveMemory(A
, &BOUT
[0], 8);
1442 NdisMoveMemory(R1
, &BOUT
[8], 8);
1446 NdisMoveMemory(&plaintext
[0], R1
, 8);
1447 NdisMoveMemory(&plaintext
[8], R2
, 8);