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 Jan Lee 03-07-22 Initial
27 Paul Lin 03-11-28 Modify for supplicant
29 #include "rt_config.h"
31 UCHAR CipherWpaPskTkip
[] = {
33 0x00, 0x50, 0xf2, 0x01, // oui
34 0x01, 0x00, // Version
35 0x00, 0x50, 0xf2, 0x02, // Multicast
36 0x01, 0x00, // Number of unicast
37 0x00, 0x50, 0xf2, 0x02, // unicast
38 0x01, 0x00, // number of authentication method
39 0x00, 0x50, 0xf2, 0x02 // authentication
41 UCHAR CipherWpaPskTkipLen
= (sizeof(CipherWpaPskTkip
) / sizeof(UCHAR
));
43 UCHAR CipherWpaPskAes
[] = {
45 0x00, 0x50, 0xf2, 0x01, // oui
46 0x01, 0x00, // Version
47 0x00, 0x50, 0xf2, 0x04, // Multicast
48 0x01, 0x00, // Number of unicast
49 0x00, 0x50, 0xf2, 0x04, // unicast
50 0x01, 0x00, // number of authentication method
51 0x00, 0x50, 0xf2, 0x02 // authentication
53 UCHAR CipherWpaPskAesLen
= (sizeof(CipherWpaPskAes
) / sizeof(UCHAR
));
56 ========================================================================
59 Classify WPA EAP message type
62 EAPType Value of EAP message type
63 MsgType Internal Message definition for MLME state machine
66 TRUE Found appropriate message type
67 FALSE No appropriate message type
70 All these constants are defined in wpa.h
71 For supplicant, there is only EAPOL Key message avaliable
73 ========================================================================
75 BOOLEAN
WpaMsgTypeSubst(
82 *MsgType
= EAP_MSG_TYPE_EAPPacket
;
85 *MsgType
= EAP_MSG_TYPE_EAPOLStart
;
88 *MsgType
= EAP_MSG_TYPE_EAPOLLogoff
;
91 *MsgType
= EAP_MSG_TYPE_EAPOLKey
;
94 *MsgType
= EAP_MSG_TYPE_EAPOLASFAlert
;
97 DBGPRINT(RT_DEBUG_INFO
, "WpaMsgTypeSubst : return FALSE; \n");
104 ==========================================================================
106 association state machine init, including state transition and timer init
108 S - pointer to the association state machine
109 ==========================================================================
111 VOID
WpaPskStateMachineInit(
112 IN PRTMP_ADAPTER pAd
,
114 OUT STATE_MACHINE_FUNC Trans
[])
116 StateMachineInit(S
, (STATE_MACHINE_FUNC
*)Trans
, MAX_WPA_PSK_STATE
, MAX_WPA_PSK_MSG
, (STATE_MACHINE_FUNC
)Drop
, WPA_PSK_IDLE
, WPA_MACHINE_BASE
);
117 StateMachineSetAction(S
, WPA_PSK_IDLE
, EAP_MSG_TYPE_EAPOLKey
, (STATE_MACHINE_FUNC
)WpaEAPOLKeyAction
);
121 ==========================================================================
123 This is state machine function.
124 When receiving EAPOL packets which is for 802.1x key management.
125 Use both in WPA, and WPAPSK case.
126 In this function, further dispatch to different functions according to the received packet. 3 categories are :
127 1. normal 4-way pairwisekey and 2-way groupkey handshake
128 2. MIC error (Countermeasures attack) report packet from STA.
129 3. Request for pairwise/group key update from STA
131 ==========================================================================
133 VOID
WpaEAPOLKeyAction(
134 IN PRTMP_ADAPTER pAdapter
,
135 IN MLME_QUEUE_ELEM
*Elem
)
138 UCHAR ZeroReplay
[LEN_KEY_DESC_REPLAY
];
139 PKEY_DESCRIPTER pKeyDesc
;
141 DBGPRINT(RT_DEBUG_TRACE
, "-----> WpaEAPOLKeyAction\n");
142 // Get 802.11 header first
143 pKeyDesc
= (PKEY_DESCRIPTER
) &Elem
->Msg
[(LENGTH_802_11
+ LENGTH_802_1_H
+ LENGTH_EAPOL_H
)];
146 *(USHORT
*)((UCHAR
*)pKeyDesc
+1) = SWAP16(*(USHORT
*)((UCHAR
*)pKeyDesc
+1));
148 // Sanity check, this should only happen in WPA-PSK mode
149 if (pAdapter
->PortCfg
.AuthMode
!= Ndis802_11AuthModeWPAPSK
)
152 // 0. Debug print all bit information
153 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Description Version %d\n", pKeyDesc
->KeyInfo
.KeyDescVer
);
154 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Type %d\n", pKeyDesc
->KeyInfo
.KeyType
);
155 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Index %d\n", pKeyDesc
->KeyInfo
.KeyIndex
);
156 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Install %d\n", pKeyDesc
->KeyInfo
.Install
);
157 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key Ack %d\n", pKeyDesc
->KeyInfo
.KeyAck
);
158 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Key MIC %d\n", pKeyDesc
->KeyInfo
.KeyMic
);
159 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Secure %d\n", pKeyDesc
->KeyInfo
.Secure
);
160 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Error %d\n", pKeyDesc
->KeyInfo
.Error
);
161 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo Request %d\n", pKeyDesc
->KeyInfo
.Request
);
162 DBGPRINT(RT_DEBUG_INFO
, "KeyInfo DL %d\n", pKeyDesc
->KeyInfo
.DL
);
164 // 1. Check EAPOL frame version and type
165 if ((Elem
->Msg
[LENGTH_802_11
+LENGTH_802_1_H
] != EAPOL_VER
) || (pKeyDesc
->Type
!= RSN_KEY_DESC
))
167 DBGPRINT(RT_DEBUG_ERROR
, " Key descripter does not match with WPA rule \n");
171 // 2.Check Version for AES & TKIP
172 if ((pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
) && (pKeyDesc
->KeyInfo
.KeyDescVer
!= DESC_TYPE_AES
))
174 DBGPRINT(RT_DEBUG_ERROR
, " Key descripter version not match AES \n");
177 else if ((pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) && (pKeyDesc
->KeyInfo
.KeyDescVer
!= DESC_TYPE_TKIP
))
179 DBGPRINT(RT_DEBUG_ERROR
, " Key descripter version not match TKIP \n");
183 // First validate replay counter, only accept message with larger replay counter
184 // Let equal pass, some AP start with all zero replay counter
185 NdisZeroMemory(ZeroReplay
, LEN_KEY_DESC_REPLAY
);
186 if ((RTMPCompareMemory(pKeyDesc
->ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1) &&
187 (RTMPCompareMemory(pKeyDesc
->ReplayCounter
, ZeroReplay
, LEN_KEY_DESC_REPLAY
) != 0))
190 // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
191 MsgType
= EAPOL_MSG_INVALID
;
192 if ((pKeyDesc
->KeyInfo
.KeyType
== 1) &&
193 (pKeyDesc
->KeyInfo
.KeyIndex
== 0) &&
194 (pKeyDesc
->KeyInfo
.KeyAck
== 1) &&
195 (pKeyDesc
->KeyInfo
.KeyMic
== 0) &&
196 (pKeyDesc
->KeyInfo
.Secure
== 0) &&
197 (pKeyDesc
->KeyInfo
.Error
== 0) &&
198 (pKeyDesc
->KeyInfo
.Request
== 0))
200 MsgType
= EAPOL_PAIR_MSG_1
;
201 DBGPRINT(RT_DEBUG_TRACE
, "Receive EAPOL Key Pairwise Message 1\n");
203 else if ((pKeyDesc
->KeyInfo
.KeyType
== 1) &&
204 (pKeyDesc
->KeyInfo
.KeyIndex
== 0) &&
205 (pKeyDesc
->KeyInfo
.KeyAck
== 1) &&
206 (pKeyDesc
->KeyInfo
.KeyMic
== 1) &&
207 (pKeyDesc
->KeyInfo
.Secure
== 0) &&
208 (pKeyDesc
->KeyInfo
.Error
== 0) &&
209 (pKeyDesc
->KeyInfo
.Request
== 0))
211 MsgType
= EAPOL_PAIR_MSG_3
;
212 DBGPRINT(RT_DEBUG_TRACE
, "Receive EAPOL Key Pairwise Message 3\n");
214 else if ((pKeyDesc
->KeyInfo
.KeyType
== 0) &&
215 (pKeyDesc
->KeyInfo
.KeyIndex
!= 0) &&
216 (pKeyDesc
->KeyInfo
.KeyAck
== 1) &&
217 (pKeyDesc
->KeyInfo
.KeyMic
== 1) &&
218 (pKeyDesc
->KeyInfo
.Secure
== 1) &&
219 (pKeyDesc
->KeyInfo
.Error
== 0) &&
220 (pKeyDesc
->KeyInfo
.Request
== 0))
222 MsgType
= EAPOL_GROUP_MSG_1
;
223 DBGPRINT(RT_DEBUG_TRACE
, "Receive EAPOL Key Group Message 1\n");
227 *(USHORT
*)((UCHAR
*)pKeyDesc
+1) = SWAP16(*(USHORT
*)((UCHAR
*)pKeyDesc
+1));
230 // We will assume link is up (assoc suceess and port not secured).
231 // All state has to be able to process message from previous state
232 switch (pAdapter
->PortCfg
.WpaState
)
235 if (MsgType
== EAPOL_PAIR_MSG_1
)
237 WpaPairMsg1Action(pAdapter
, Elem
);
238 pAdapter
->PortCfg
.WpaState
= SS_WAIT_MSG_3
;
243 if (MsgType
== EAPOL_PAIR_MSG_1
)
245 WpaPairMsg1Action(pAdapter
, Elem
);
246 pAdapter
->PortCfg
.WpaState
= SS_WAIT_MSG_3
;
248 else if (MsgType
== EAPOL_PAIR_MSG_3
)
250 WpaPairMsg3Action(pAdapter
, Elem
);
251 pAdapter
->PortCfg
.WpaState
= SS_WAIT_GROUP
;
255 case SS_WAIT_GROUP
: // When doing group key exchange
256 case SS_FINISH
: // This happened when update group key
257 if (MsgType
== EAPOL_PAIR_MSG_1
)
259 WpaPairMsg1Action(pAdapter
, Elem
);
260 pAdapter
->PortCfg
.WpaState
= SS_WAIT_MSG_3
;
261 // Reset port secured variable
262 pAdapter
->PortCfg
.PortSecured
= WPA_802_1X_PORT_NOT_SECURED
;
264 else if (MsgType
== EAPOL_PAIR_MSG_3
)
266 WpaPairMsg3Action(pAdapter
, Elem
);
267 pAdapter
->PortCfg
.WpaState
= SS_WAIT_GROUP
;
268 // Reset port secured variable
269 pAdapter
->PortCfg
.PortSecured
= WPA_802_1X_PORT_NOT_SECURED
;
271 else if (MsgType
== EAPOL_GROUP_MSG_1
)
273 WpaGroupMsg1Action(pAdapter
, Elem
);
274 pAdapter
->PortCfg
.WpaState
= SS_FINISH
;
282 DBGPRINT(RT_DEBUG_TRACE
, "<----- WpaEAPOLKeyAction\n");
286 ========================================================================
289 Process Pairwise key 4-way handshaking
292 pAdapter Pointer to our adapter
300 ========================================================================
302 VOID
WpaPairMsg1Action(
303 IN PRTMP_ADAPTER pAdapter
,
304 IN MLME_QUEUE_ELEM
*Elem
)
306 PHEADER_802_11 pHeader
;
308 UCHAR
*OutBuffer
= NULL
;
309 HEADER_802_11 Header_802_11
;
311 UCHAR AckRate
= RATE_2
;
312 USHORT AckDuration
= 0;
314 UCHAR EAPHEAD
[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
319 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg1Action ----->\n");
321 pHeader
= (PHEADER_802_11
) Elem
->Msg
;
323 // Save Data Length to pDesc for receiving packet, then put in outgoing frame Data Len fields.
324 pMsg1
= (PEAPOL_PACKET
) &Elem
->Msg
[LENGTH_802_11
+ LENGTH_802_1_H
];
326 // Process message 1 from authenticator
327 // Key must be Pairwise key, already verified at callee.
328 // 1. Save Replay counter, it will use to verify message 3 and construct message 2
329 NdisMoveMemory(pAdapter
->PortCfg
.ReplayCounter
, pMsg1
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
332 NdisMoveMemory(pAdapter
->PortCfg
.ANonce
, pMsg1
->KeyDesc
.KeyNonce
, LEN_KEY_DESC_NONCE
);
334 // TSNonce <--- SNonce
335 // Generate random SNonce
336 GenRandom(pAdapter
, pAdapter
->PortCfg
.SNonce
);
338 // TPTK <--- Calc PTK(ANonce, TSNonce)
339 WpaCountPTK(pAdapter
->PortCfg
.PskKey
.Key
,
340 pAdapter
->PortCfg
.ANonce
,
341 pAdapter
->PortCfg
.Bssid
.Octet
,
342 pAdapter
->PortCfg
.SNonce
,
343 pAdapter
->CurrentAddress
,
347 // Save key to PTK entry
348 NdisMoveMemory(pAdapter
->PortCfg
.PTK
, PTK
, LEN_PTK
);
350 // =====================================
351 // Use Priority Ring & MiniportMMRequest
352 // =====================================
353 pAdapter
->Sequence
= ((pAdapter
->Sequence
) + 1) & (MAX_SEQ_NUMBER
);
354 WpaMacHeaderInit(pAdapter
, &Header_802_11
, 0, &pAdapter
->PortCfg
.Bssid
);
356 // ACK size is 14 include CRC, and its rate is based on real time information
357 AckRate
= pAdapter
->PortCfg
.ExpectedACKRate
[pAdapter
->PortCfg
.TxRate
];
358 AckDuration
= RTMPCalcDuration(pAdapter
, AckRate
, 14);
359 Header_802_11
.Controlhead
.Duration
= pAdapter
->PortCfg
.Dsifs
+ AckDuration
;
361 // Zero message 2 body
362 NdisZeroMemory(&Packet
, sizeof(Packet
));
363 Packet
.Version
= EAPOL_VER
;
364 Packet
.Type
= EAPOLKey
;
366 // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
368 Packet
.KeyDesc
.Type
= RSN_KEY_DESC
;
369 // 1. Key descriptor version and appropriate RSN IE
370 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
372 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= 2;
373 Packet
.KeyDesc
.KeyDataLen
[1] = CipherWpaPskAesLen
;
374 NdisMoveMemory(Packet
.KeyDesc
.KeyData
, CipherWpaPskAes
, CipherWpaPskAesLen
);
378 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= 1;
379 Packet
.KeyDesc
.KeyDataLen
[1] = CipherWpaPskTkipLen
;
380 NdisMoveMemory(Packet
.KeyDesc
.KeyData
, CipherWpaPskTkip
, CipherWpaPskTkipLen
);
382 // Update packet length after decide Key data payload
383 Packet
.Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
+ Packet
.KeyDesc
.KeyDataLen
[1];
385 // 2. Key Type PeerKey
386 Packet
.KeyDesc
.KeyInfo
.KeyType
= 1;
388 // 3. KeyMic field presented
389 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
392 NdisMoveMemory(Packet
.KeyDesc
.KeyNonce
, pAdapter
->PortCfg
.SNonce
, LEN_KEY_DESC_NONCE
);
394 // 5. Key Replay Count
395 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
398 *(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)));
401 // Send EAPOL(0, 1, 0, 0, 0, K, 0, TSNonce, 0, MIC(TPTK), 0)
402 // Out buffer for transmitting message 2
403 NStatus
= MlmeAllocateMemory(pAdapter
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
404 if (NStatus
!= NDIS_STATUS_SUCCESS
)
407 // Prepare EAPOL frame for MIC calculation
408 // Be careful, only EAPOL frame is counted for MIC calculation
409 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
410 Packet
.Len
[1] + 4, &Packet
,
413 // 5. Prepare and Fill MIC value
414 NdisZeroMemory(Mic
, sizeof(Mic
));
415 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
420 HMAC_SHA1(OutBuffer
, FrameLen
, PTK
, LEN_EAP_MICK
, digest
);
421 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
426 DBGPRINT(RT_DEBUG_INFO
, " PMK = ");
427 for (i
= 0; i
< 16; i
++)
428 DBGPRINT(RT_DEBUG_INFO
, "%2x-", pAdapter
->PortCfg
.PskKey
.Key
[i
]);
430 DBGPRINT(RT_DEBUG_INFO
, "\n PTK = ");
431 for (i
= 0; i
< 64; i
++)
432 DBGPRINT(RT_DEBUG_INFO
, "%2x-", pAdapter
->PortCfg
.PTK
[i
]);
433 DBGPRINT(RT_DEBUG_INFO
, "\n FrameLen = %d\n", FrameLen
);
435 hmac_md5(PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, Mic
);
437 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
440 // Make Transmitting frame
441 MakeOutgoingFrame(OutBuffer
, &FrameLen
, sizeof(MACHDR
), &Header_802_11
,
442 sizeof(EAPHEAD
), EAPHEAD
,
443 Packet
.Len
[1] + 4, &Packet
,
446 // Send using priority queue
447 MiniportMMRequest(pAdapter
, OutBuffer
, FrameLen
);
449 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg1Action <-----\n");
453 ========================================================================
456 Process Pairwise key 4-way handshaking
459 pAdapter Pointer to our adapter
467 ========================================================================
469 VOID
WpaPairMsg3Action(
470 IN PRTMP_ADAPTER pAdapter
,
471 IN MLME_QUEUE_ELEM
*Elem
)
473 PHEADER_802_11 pHeader
;
474 UCHAR
*OutBuffer
= NULL
;
475 HEADER_802_11 Header_802_11
;
477 UCHAR AckRate
= RATE_2
;
478 USHORT AckDuration
= 0;
480 UCHAR EAPHEAD
[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
484 UCHAR Mic
[16], OldMic
[16];
485 NDIS_802_11_KEY PeerKey
;
488 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg3Action ----->\n");
490 pHeader
= (PHEADER_802_11
) Elem
->Msg
;
492 // Process message 3 frame.
493 pMsg3
= (PEAPOL_PACKET
) &Elem
->Msg
[LENGTH_802_11
+ LENGTH_802_1_H
];
496 *(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)));
499 // 1. Verify RSN IE & cipher type match
500 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
502 if (pMsg3
->KeyDesc
.KeyInfo
.KeyDescVer
!= 2)
504 pTmp
= (PUCHAR
) &CipherWpaPskAes
;
508 if (pMsg3
->KeyDesc
.KeyInfo
.KeyDescVer
!= 1)
510 pTmp
= (PUCHAR
) &CipherWpaPskTkip
;
513 // Fix compatibility issue, when AP append nonsense data after auth mode with different size.
514 // We should qualify this kind of RSN as acceptable
515 if (!NdisEqualMemory((PUCHAR
) &pMsg3
->KeyDesc
.KeyData
[2], pTmp
+ 2, CipherWpaPskTkipLen
- 2))
517 DBGPRINT(RT_DEBUG_ERROR
, " RSN IE mismatched msg 3 of 4-way handshake!!!!!!!!!! \n");
521 DBGPRINT(RT_DEBUG_TRACE
, " RSN IE matched in msg 3 of 4-way handshake!!!!!!!!!! \n");
524 *(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)));
527 // 2. Check MIC value
528 // Save the MIC and replace with zero
529 NdisMoveMemory(OldMic
, pMsg3
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
530 NdisZeroMemory(pMsg3
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
531 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
536 HMAC_SHA1((PUCHAR
) pMsg3
, pMsg3
->Len
[1] + 4, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
537 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
541 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, (PUCHAR
) pMsg3
, pMsg3
->Len
[1] + 4, Mic
);
544 if (!NdisEqualMemory(OldMic
, Mic
, LEN_KEY_DESC_MIC
))
546 DBGPRINT(RT_DEBUG_ERROR
, " MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n");
550 DBGPRINT(RT_DEBUG_TRACE
, " MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n");
552 // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
553 if (RTMPCompareMemory(pMsg3
->KeyDesc
.ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1)
556 // Update new replay counter
557 NdisMoveMemory(pAdapter
->PortCfg
.ReplayCounter
, pMsg3
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
559 // 4. Double check ANonce
560 if (!NdisEqualMemory(pAdapter
->PortCfg
.ANonce
, pMsg3
->KeyDesc
.KeyNonce
, LEN_KEY_DESC_NONCE
))
563 // 5. Construct Message 4
564 // =====================================
565 // Use Priority Ring & MiniportMMRequest
566 // =====================================
567 pAdapter
->Sequence
= ((pAdapter
->Sequence
) + 1) & (MAX_SEQ_NUMBER
);
568 WpaMacHeaderInit(pAdapter
, &Header_802_11
, 0, &pAdapter
->PortCfg
.Bssid
);
570 // ACK size is 14 include CRC, and its rate is based on real time information
571 AckRate
= pAdapter
->PortCfg
.ExpectedACKRate
[pAdapter
->PortCfg
.TxRate
];
572 AckDuration
= RTMPCalcDuration(pAdapter
, AckRate
, 14);
573 Header_802_11
.Controlhead
.Duration
= pAdapter
->PortCfg
.Dsifs
+ AckDuration
;
575 // Zero message 4 body
576 NdisZeroMemory(&Packet
, sizeof(Packet
));
577 Packet
.Version
= EAPOL_VER
;
578 Packet
.Type
= EAPOLKey
;
579 Packet
.Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
; // No data field
582 // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
584 Packet
.KeyDesc
.Type
= RSN_KEY_DESC
;
587 *(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pMsg3
->KeyDesc
.KeyInfo
)));
590 // Key descriptor version and appropriate RSN IE
591 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= pMsg3
->KeyDesc
.KeyInfo
.KeyDescVer
;
594 Packet
.KeyDesc
.KeyInfo
.KeyType
= 1;
596 // KeyMic field presented
597 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
600 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pMsg3
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
602 *(USHORT
*)&Packet
.KeyDesc
.KeyInfo
= SWAP16(*(USHORT
*)&Packet
.KeyDesc
.KeyInfo
);
605 // Out buffer for transmitting message 4
606 NStatus
= MlmeAllocateMemory(pAdapter
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
607 if (NStatus
!= NDIS_STATUS_SUCCESS
)
610 // Prepare EAPOL frame for MIC calculation
611 // Be careful, only EAPOL frame is counted for MIC calculation
612 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
613 Packet
.Len
[1] + 4, &Packet
,
616 // Prepare and Fill MIC value
617 NdisZeroMemory(Mic
, sizeof(Mic
));
618 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
623 HMAC_SHA1(OutBuffer
, FrameLen
, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
624 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
628 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, Mic
);
630 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
634 // Make Transmitting frame
635 MakeOutgoingFrame(OutBuffer
, &FrameLen
, sizeof(MACHDR
), &Header_802_11
,
636 sizeof(EAPHEAD
), EAPHEAD
,
637 Packet
.Len
[1] + 4, &Packet
,
640 // 6. Send Message 4 to authenticator
641 // Send using priority queue
642 MiniportMMRequest(pAdapter
, OutBuffer
, FrameLen
);
645 NdisZeroMemory(&PeerKey
, sizeof(PeerKey
));
646 PeerKey
.Length
= sizeof(PeerKey
);
647 PeerKey
.KeyIndex
= 0xe0000000;
648 PeerKey
.KeyLength
= 16;
649 NdisMoveMemory(PeerKey
.BSSID
, pAdapter
->PortCfg
.Bssid
.Octet
, 6);
650 NdisMoveMemory(&PeerKey
.KeyRSC
, pMsg3
->KeyDesc
.KeyRsc
, LEN_KEY_DESC_RSC
);
651 NdisMoveMemory(PeerKey
.KeyMaterial
, &pAdapter
->PortCfg
.PTK
[32], 32);
652 // Call Add peer key function
653 RTMPWPAAddKeyProc(pAdapter
, &PeerKey
);
655 DBGPRINT(RT_DEBUG_TRACE
, "WpaPairMsg3Action <-----\n");
660 ========================================================================
663 Process Group key 2-way handshaking
666 pAdapter Pointer to our adapter
674 ========================================================================
676 VOID
WpaGroupMsg1Action(
677 IN PRTMP_ADAPTER pAdapter
,
678 IN MLME_QUEUE_ELEM
*Elem
)
680 PHEADER_802_11 pHeader
;
681 UCHAR
*OutBuffer
= NULL
;
682 HEADER_802_11 Header_802_11
;
684 UCHAR AckRate
= RATE_2
;
685 USHORT AckDuration
= 0;
687 UCHAR EAPHEAD
[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
689 PEAPOL_PACKET pGroup
;
690 UCHAR Mic
[16], OldMic
[16];
691 UCHAR GTK
[32], Key
[32];
692 NDIS_802_11_KEY GroupKey
;
695 DBGPRINT(RT_DEBUG_TRACE
, "WpaGroupMsg1Action ----->\n");
697 pHeader
= (PHEADER_802_11
) Elem
->Msg
;
699 // Process Group message 1 frame.
700 pGroup
= (PEAPOL_PACKET
) &Elem
->Msg
[LENGTH_802_11
+ LENGTH_802_1_H
];
702 // 1. Verify Replay counter
703 // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
704 if (RTMPCompareMemory(pGroup
->KeyDesc
.ReplayCounter
, pAdapter
->PortCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1)
707 // Update new replay counter
708 NdisMoveMemory(pAdapter
->PortCfg
.ReplayCounter
, pGroup
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
710 // 2. Verify MIC is valid
711 // Save the MIC and replace with zero
712 NdisMoveMemory(OldMic
, pGroup
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
713 NdisZeroMemory(pGroup
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
714 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
719 HMAC_SHA1((PUCHAR
) pGroup
, pGroup
->Len
[1] + 4, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
720 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
724 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, (PUCHAR
) pGroup
, pGroup
->Len
[1] + 4, Mic
);
727 if (!NdisEqualMemory(OldMic
, Mic
, LEN_KEY_DESC_MIC
))
729 DBGPRINT(RT_DEBUG_ERROR
, " MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n");
733 DBGPRINT(RT_DEBUG_TRACE
, " MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n");
736 *(USHORT
*)(&(pGroup
->KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(pGroup
->KeyDesc
.KeyInfo
)));
739 // 3. Decrypt GTK from Key Data
740 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
742 if (pGroup
->KeyDesc
.KeyInfo
.KeyDescVer
!= 2)
745 AES_GTK_KEY_UNWRAP(&pAdapter
->PortCfg
.PTK
[16], GTK
, pGroup
->KeyDesc
.KeyData
);
751 if (pGroup
->KeyDesc
.KeyInfo
.KeyDescVer
!= 1)
754 // Construct 32 bytes RC4 Key
755 NdisMoveMemory(Key
, pGroup
->KeyDesc
.KeyIv
, 16);
756 NdisMoveMemory(&Key
[16], &pAdapter
->PortCfg
.PTK
[16], 16);
757 ARCFOUR_INIT(&pAdapter
->PrivateInfo
.WEPCONTEXT
, Key
, 32);
758 //discard first 256 bytes
759 for (i
= 0; i
< 256; i
++)
760 ARCFOUR_BYTE(&pAdapter
->PrivateInfo
.WEPCONTEXT
);
761 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
762 ARCFOUR_DECRYPT(&pAdapter
->PrivateInfo
.WEPCONTEXT
, GTK
, pGroup
->KeyDesc
.KeyData
, 32);
765 // 4. Construct Group Message 2
766 pAdapter
->Sequence
= ((pAdapter
->Sequence
) + 1) & (MAX_SEQ_NUMBER
);
767 WpaMacHeaderInit(pAdapter
, &Header_802_11
, 1, &pAdapter
->PortCfg
.Bssid
);
769 // ACK size is 14 include CRC, and its rate is based on real time information
770 AckRate
= pAdapter
->PortCfg
.ExpectedACKRate
[pAdapter
->PortCfg
.TxRate
];
771 AckDuration
= RTMPCalcDuration(pAdapter
, AckRate
, 14);
772 Header_802_11
.Controlhead
.Duration
= pAdapter
->PortCfg
.Dsifs
+ AckDuration
;
774 // Zero Group message 1 body
775 NdisZeroMemory(&Packet
, sizeof(Packet
));
776 Packet
.Version
= EAPOL_VER
;
777 Packet
.Type
= EAPOLKey
;
778 Packet
.Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
; // No data field
781 // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
783 Packet
.KeyDesc
.Type
= RSN_KEY_DESC
;
785 // Key descriptor version and appropriate RSN IE
786 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
= pGroup
->KeyDesc
.KeyInfo
.KeyDescVer
;
788 // Key Type Group key
789 Packet
.KeyDesc
.KeyInfo
.KeyType
= 0;
791 // KeyMic field presented
792 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
795 Packet
.KeyDesc
.KeyInfo
.Secure
= 1;
798 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pGroup
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
801 *(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)) = SWAP16(*(USHORT
*)(&(Packet
.KeyDesc
.KeyInfo
)));
804 // Out buffer for transmitting group message 2
805 NStatus
= MlmeAllocateMemory(pAdapter
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
806 if (NStatus
!= NDIS_STATUS_SUCCESS
)
809 // Prepare EAPOL frame for MIC calculation
810 // Be careful, only EAPOL frame is counted for MIC calculation
811 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
812 Packet
.Len
[1] + 4, &Packet
,
815 // Prepare and Fill MIC value
816 NdisZeroMemory(Mic
, sizeof(Mic
));
817 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
822 HMAC_SHA1(OutBuffer
, FrameLen
, pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, digest
);
823 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
828 DBGPRINT(RT_DEBUG_INFO
, "PTK = ");
829 for (i
= 0; i
< 64; i
++)
830 DBGPRINT(RT_DEBUG_INFO
, "%2x-", pAdapter
->PortCfg
.PTK
[i
]);
831 DBGPRINT(RT_DEBUG_INFO
, "\n FrameLen = %d\n", FrameLen
);
833 hmac_md5(pAdapter
->PortCfg
.PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, Mic
);
835 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
838 // Make Transmitting frame
839 MakeOutgoingFrame(OutBuffer
, &FrameLen
, sizeof(MACHDR
), &Header_802_11
,
840 sizeof(EAPHEAD
), EAPHEAD
,
841 Packet
.Len
[1] + 4, &Packet
,
844 // 5. Copy frame to Tx ring and prepare for encryption
845 WpaHardEncrypt(pAdapter
, OutBuffer
, FrameLen
);
847 // 6 Free allocated memory
848 MlmeFreeMemory(pAdapter
, OutBuffer
);
851 NdisZeroMemory(&GroupKey
, sizeof(GroupKey
));
852 GroupKey
.Length
= sizeof(GroupKey
);
853 GroupKey
.KeyIndex
= 0x20000000 | pGroup
->KeyDesc
.KeyInfo
.KeyIndex
;
854 GroupKey
.KeyLength
= 16;
855 NdisMoveMemory(GroupKey
.BSSID
, pAdapter
->PortCfg
.Bssid
.Octet
, 6);
856 NdisMoveMemory(GroupKey
.KeyMaterial
, GTK
, 32);
857 // Call Add peer key function
858 RTMPWPAAddKeyProc(pAdapter
, &GroupKey
);
860 DBGPRINT(RT_DEBUG_TRACE
, "WpaGroupMsg1Action <-----\n");
863 ========================================================================
869 pAdapter Pointer to our adapter
876 ========================================================================
878 VOID
WpaMacHeaderInit(
879 IN PRTMP_ADAPTER pAd
,
880 IN OUT PHEADER_802_11 Hdr
,
884 NdisZeroMemory(Hdr
, sizeof(HEADER_802_11
));
885 Hdr
->Controlhead
.Frame
.Type
= BTYPE_DATA
;
886 Hdr
->Controlhead
.Frame
.ToDs
= 1;
888 Hdr
->Controlhead
.Frame
.Wep
= 1;
890 // Addr1: DA, Addr2: BSSID, Addr3: SA
891 COPY_MAC_ADDR(&Hdr
->Controlhead
.Addr1
, pAddr1
);
892 COPY_MAC_ADDR(&Hdr
->Controlhead
.Addr2
, &pAd
->CurrentAddress
);
893 COPY_MAC_ADDR(&Hdr
->Addr3
, &pAd
->PortCfg
.Bssid
);
894 Hdr
->Sequence
= pAd
->Sequence
;
898 ========================================================================
901 Copy frame from waiting queue into relative ring buffer and set
902 appropriate ASIC register to kick hardware encryption before really
906 pAdapter Pointer to our adapter
907 PNDIS_PACKET Pointer to outgoing Ndis frame
908 NumberOfFrag Number of fragment required
915 ========================================================================
918 IN PRTMP_ADAPTER pAdapter
,
925 UCHAR CipherAlg
= CIPHER_NONE
;
935 UCHAR RetryMode
= SHORT_RETRY
;
936 static UCHAR Priority
[4] = {"\x00\x00\x00\x00"};
937 unsigned long IrqFlags
;
939 // Make sure Tx ring resource won't be used by other threads
940 NdisAcquireSpinLock(&pAdapter
->TxRingLock
);
942 FrameGap
= IFS_BACKOFF
; // Default frame gap mode
944 // outgoing frame always wakeup PHY to prevent frame lost and
945 // turn off PSM bit to improve performance
946 if (pAdapter
->PortCfg
.Psm
== PWR_SAVE
)
948 MlmeSetPsmBit(pAdapter
, PWR_ACTIVE
);
950 AsicForceWakeup(pAdapter
);
952 pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].FrameType
= BTYPE_DATA
;
954 pSrc
= pPacket
; // Point to start of MSDU
956 pWpaKey
= (PWPA_KEY
) &pAdapter
->PortCfg
.PairwiseKey
[0];
957 pWpaKey
->Type
= PAIRWISE_KEY
;
960 // No pairwise key, this should not happen
961 NdisReleaseSpinLock(&pAdapter
->TxRingLock
);
965 // Get the Tx Ring descriptor & Dma Buffer address
966 pDest
= (PUCHAR
) pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].va_data_addr
;
968 pTxD
= (PTXD_STRUC
) pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].va_addr
;
971 pDestTxD
= (PTXD_STRUC
) pAdapter
->TxRing
[pAdapter
->CurEncryptIndex
].va_addr
;
974 RTMPDescriptorEndianChange((PUCHAR
)pTxD
, TYPE_TXD
);
977 if ((pTxD
->Owner
== DESC_OWN_NIC
) || (pTxD
->CipherOwn
== DESC_OWN_NIC
))
979 // Descriptor owned by NIC. No descriptor avaliable
980 // This should not happen since caller guaranteed.
981 // Make sure to release Tx ring resource
982 pAdapter
->RalinkCounters
.TxRingErrCount
++;
983 NdisReleaseSpinLock(&pAdapter
->TxRingLock
);
986 if (pTxD
->Valid
== TRUE
)
988 // Ndis packet of last round did not cleared.
989 // This should not happen since caller guaranteed.
990 // Make sure to release Tx ring resource
994 RTMPDescriptorEndianChange((PUCHAR
)pTxD
, TYPE_TXD
);
998 pAdapter
->RalinkCounters
.TxRingErrCount
++;
999 NdisReleaseSpinLock(&pAdapter
->TxRingLock
);
1003 // Copy whole frame to Tx ring buffer
1004 NdisMoveMemory(pDest
, pPacket
, Len
);
1007 if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
)
1012 // Prepare 8 bytes TKIP encapsulation for MPDU
1016 tkipIv
.IV16
.field
.rc0
= *(pWpaKey
->TxTsc
+ 1);
1017 tkipIv
.IV16
.field
.rc1
= (tkipIv
.IV16
.field
.rc0
| 0x20) & 0x7f;
1018 tkipIv
.IV16
.field
.rc2
= *pWpaKey
->TxTsc
;
1019 tkipIv
.IV16
.field
.CONTROL
.field
.ExtIV
= 1; // 0: non-extended IV, 1: an extended IV
1020 tkipIv
.IV16
.field
.CONTROL
.field
.KeyID
= 0;
1021 tkipIv
.IV32
= *(PULONG
)(pWpaKey
->TxTsc
+ 2);
1023 pTxD
->Iv
= tkipIv
.IV16
.word
;
1025 *((PUCHAR
) &pTxD
->Eiv
) = *((PUCHAR
) &tkipIv
.IV32
+ 3);
1026 *((PUCHAR
) &pTxD
->Eiv
+ 1) = *((PUCHAR
) &tkipIv
.IV32
+ 2);
1027 *((PUCHAR
) &pTxD
->Eiv
+ 2) = *((PUCHAR
) &tkipIv
.IV32
+ 1);
1028 *((PUCHAR
) &pTxD
->Eiv
+ 3) = *((PUCHAR
) &tkipIv
.IV32
);
1031 // Increase TxTsc value for next transmission
1032 while (++pWpaKey
->TxTsc
[i
] == 0x0)
1040 pTxD
->IvOffset
= LENGTH_802_11
;
1043 NdisMoveMemory(pTxD
->Key
, pWpaKey
->Key
, 16);
1046 CipherAlg
= CIPHER_TKIP
;
1048 // Calculate MIC value
1049 // Init MIC value calculation and reset the message
1050 pAdapter
->PrivateInfo
.Tx
.L
= RTMPTkipGetUInt32(pWpaKey
->TxMic
);
1051 pAdapter
->PrivateInfo
.Tx
.R
= RTMPTkipGetUInt32(pWpaKey
->TxMic
+ 4);
1052 pAdapter
->PrivateInfo
.Tx
.nBytesInM
= 0;
1053 pAdapter
->PrivateInfo
.Tx
.M
= 0;
1056 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
+ 4, 12);
1058 // Priority + 3 bytes of 0
1059 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, Priority
, 4);
1061 pSrc
+= LENGTH_802_11
;
1062 RTMPTkipAppend(&pAdapter
->PrivateInfo
.Tx
, pSrc
, Len
- LENGTH_802_11
);
1063 RTMPTkipGetMIC(&pAdapter
->PrivateInfo
.Tx
);
1065 NdisMoveMemory(pDest
, pAdapter
->PrivateInfo
.Tx
.MIC
, 8);
1067 // IV + EIV + ICV which ASIC added after encryption done
1070 else if (pAdapter
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1076 pTmp
= (PUCHAR
) &Iv16
;
1077 *pTmp
= pWpaKey
->TxTsc
[0];
1078 *(pTmp
+ 1) = pWpaKey
->TxTsc
[1];
1082 Iv32
= *(PULONG
)(&pWpaKey
->TxTsc
[2]);
1084 // Increase TxTsc value for next transmission
1085 while (++pWpaKey
->TxTsc
[i
] == 0x0)
1093 NdisMoveMemory(&pTxD
->Iv
, &Iv16
, 4);
1096 NdisMoveMemory(&pTxD
->Eiv
, &Iv32
, 4);
1099 pTxD
->IvOffset
= LENGTH_802_11
;
1102 NdisMoveMemory(pTxD
->Key
, pWpaKey
->Key
, 16);
1105 CipherAlg
= CIPHER_AES
;
1107 // IV + EIV + HW MIC
1112 RTMPFrameEndianChange(pAdapter
, pOriginDest
, DIR_WRITE
, FALSE
);
1113 RTMPDescriptorEndianChange((PUCHAR
)pTxD
, TYPE_TXD
);
1118 RTMPWriteTxDescriptor(pTxD
, TRUE
, CipherAlg
, TRUE
, FALSE
, FALSE
, RetryMode
, FrameGap
,
1119 pAdapter
->PortCfg
.TxRate
, 4, Len
, pAdapter
->PortCfg
.TxPreambleInUsed
, 0);
1121 // Increase & maintain Tx Ring Index
1122 pAdapter
->CurEncryptIndex
++;
1123 if (pAdapter
->CurEncryptIndex
>= TX_RING_SIZE
)
1125 pAdapter
->CurEncryptIndex
= 0;
1127 pAdapter
->RalinkCounters
.EncryptCount
++;
1129 // Kick Encrypt Control Register at the end of all ring buffer preparation
1130 RTMP_IO_WRITE32(pAdapter
, SECCSR1
, 0x1);
1132 // Make sure to release Tx ring resource
1133 NdisReleaseSpinLock(&pAdapter
->TxRingLock
);
1137 ========================================================================
1139 Routine Description:
1148 ========================================================================
1158 UCHAR k_ipad
[65]; /* inner padding - key XORd with ipad */
1159 UCHAR k_opad
[65]; /* outer padding - key XORd with opad */
1162 // if key is longer than 64 bytes reset it to key=SHA1(key)
1167 SHAUpdate(&tctx
, key
, key_len
);
1168 SHAFinal(&tctx
, key
);
1171 NdisZeroMemory(k_ipad
, sizeof(k_ipad
));
1172 NdisZeroMemory(k_opad
, sizeof(k_opad
));
1173 NdisMoveMemory(k_ipad
, key
, key_len
);
1174 NdisMoveMemory(k_opad
, key
, key_len
);
1176 // XOR key with ipad and opad values
1177 for (i
= 0; i
< 64; i
++)
1183 // perform inner SHA1
1184 SHAInit(&context
); /* init context for 1st pass */
1185 SHAUpdate(&context
, k_ipad
, 64); /* start with inner pad */
1186 SHAUpdate(&context
, text
, text_len
); /* then text of datagram */
1187 SHAFinal(&context
, digest
); /* finish up 1st pass */
1189 //perform outer SHA1
1190 SHAInit(&context
); /* init context for 2nd pass */
1191 SHAUpdate(&context
, k_opad
, 64); /* start with outer pad */
1192 SHAUpdate(&context
, digest
, 20); /* then results of 1st hash */
1193 SHAFinal(&context
, digest
); /* finish up 2nd pass */
1197 ========================================================================
1199 Routine Description:
1209 ========================================================================
1223 INT currentindex
= 0;
1226 NdisMoveMemory(input
, prefix
, prefix_len
);
1227 input
[prefix_len
] = 0;
1228 NdisMoveMemory(&input
[prefix_len
+ 1], data
, data_len
);
1229 total_len
= prefix_len
+ 1 + data_len
;
1230 input
[total_len
] = 0;
1232 for (i
= 0; i
< (len
+ 19) / 20; i
++)
1234 HMAC_SHA1(input
, total_len
, key
, key_len
, &output
[currentindex
]);
1236 input
[total_len
- 1]++;
1241 ========================================================================
1243 Routine Description:
1249 Output Store the TPTK
1253 ========================================================================
1264 UCHAR concatenation
[76];
1267 UCHAR Prefix
[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
1268 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
1270 NdisZeroMemory(temp
, sizeof(temp
));
1272 // Get smaller address
1273 if (RTMPCompareMemory(SA
, AA
, 6) == 1)
1274 NdisMoveMemory(concatenation
, AA
, 6);
1276 NdisMoveMemory(concatenation
, SA
, 6);
1279 // Get larger address
1280 if (RTMPCompareMemory(SA
, AA
, 6) == 1)
1281 NdisMoveMemory(&concatenation
[CurrPos
], SA
, 6);
1283 NdisMoveMemory(&concatenation
[CurrPos
], AA
, 6);
1286 // Get smaller address
1287 if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 1)
1288 NdisMoveMemory(&concatenation
[CurrPos
], SNonce
, 32);
1290 NdisMoveMemory(&concatenation
[CurrPos
], ANonce
, 32);
1293 // Get larger address
1294 if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 1)
1295 NdisMoveMemory(&concatenation
[CurrPos
], ANonce
, 32);
1297 NdisMoveMemory(&concatenation
[CurrPos
], SNonce
, 32);
1300 PRF(PMK
, LEN_MASTER_KEY
, Prefix
, 22, concatenation
, 76 , output
, len
);
1304 ========================================================================
1306 Routine Description:
1307 Misc function to Generate random number
1316 ========================================================================
1319 IN PRTMP_ADAPTER pAd
,
1323 UCHAR local
[80], KeyCounter
[32];
1326 UCHAR prefix
[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
1328 NdisZeroMemory(result
, 80);
1329 NdisZeroMemory(local
, 80);
1330 NdisZeroMemory(KeyCounter
, 32);
1331 NdisMoveMemory(local
, pAd
->CurrentAddress
, ETH_LENGTH_OF_ADDRESS
);
1333 for (i
= 0; i
< 32; i
++)
1335 curr
= ETH_LENGTH_OF_ADDRESS
;
1336 CurrentTime
= jiffies
;
1337 NdisMoveMemory(local
, pAd
->CurrentAddress
, ETH_LENGTH_OF_ADDRESS
);
1338 curr
+= ETH_LENGTH_OF_ADDRESS
;
1339 NdisMoveMemory(&local
[curr
], &CurrentTime
, sizeof(CurrentTime
));
1340 curr
+= sizeof(CurrentTime
);
1341 NdisMoveMemory(&local
[curr
], result
, 32);
1343 NdisMoveMemory(&local
[curr
], &i
, 2);
1345 PRF(KeyCounter
, 32, prefix
,12, local
, curr
, result
, 32);
1347 NdisMoveMemory(random
, result
, 32);
1351 ========================================================================
1353 Routine Description:
1354 Misc function to decrypt AES body
1361 This function references to RFC 3394 for aes key unwrap algorithm.
1363 ========================================================================
1365 VOID
AES_GTK_KEY_UNWRAP(
1367 OUT UCHAR
*plaintext
,
1368 IN UCHAR
*ciphertext
)
1370 UCHAR A
[8], BIN
[16], BOUT
[16];
1379 NdisMoveMemory(A
, ciphertext
, 8);
1381 NdisMoveMemory(R1
, &ciphertext
[8], 8);
1383 NdisMoveMemory(R2
, &ciphertext
[16], 8);
1385 aes_set_key(&aesctx
, key
, 128);
1387 for (j
= 5; j
>= 0; j
--)
1389 xor = num_blocks
* j
+ 2;
1390 NdisMoveMemory(BIN
, A
, 8);
1391 BIN
[7] = A
[7] ^ xor;
1392 NdisMoveMemory(&BIN
[8], R2
, 8);
1393 aes_decrypt(&aesctx
, BIN
, BOUT
);
1394 NdisMoveMemory(A
, &BOUT
[0], 8);
1395 NdisMoveMemory(R2
, &BOUT
[8], 8);
1397 xor = num_blocks
* j
+ 1;
1398 NdisMoveMemory(BIN
, A
, 8);
1399 BIN
[7] = A
[7] ^ xor;
1400 NdisMoveMemory(&BIN
[8], R1
, 8);
1401 aes_decrypt(&aesctx
, BIN
, BOUT
);
1402 NdisMoveMemory(A
, &BOUT
[0], 8);
1403 NdisMoveMemory(R1
, &BOUT
[8], 8);
1407 NdisMoveMemory(&plaintext
[0], R1
, 8);
1408 NdisMoveMemory(&plaintext
[8], R2
, 8);