mirror of
https://github.com/drasko/open-ameba.git
synced 2024-11-25 07:24:17 +00:00
eeb7f808ae
Signed-off-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com>
341 lines
11 KiB
C
341 lines
11 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
#ifndef _RTW_PSK_H_
|
|
#define _RTW_PSK_H_
|
|
|
|
#define GMK_LEN 32
|
|
#define GTK_LEN 32
|
|
#define PMK_LEN 32
|
|
#define KEY_NONCE_LEN 32
|
|
#define NumGroupKey 4
|
|
#define KEY_RC_LEN 8
|
|
#define KEY_IV_LEN 16
|
|
#define KEY_RSC_LEN 8
|
|
#define KEY_ID_LEN 8
|
|
#define KEY_MIC_LEN 16
|
|
#define KEY_MATERIAL_LEN 2
|
|
#define PTK_LEN_EAPOLMIC 16
|
|
#define PTK_LEN_EAPOLENC 16
|
|
#define PTK_LEN_TKIP 64
|
|
#define PTK_LEN_CCMP 48
|
|
#define LIB1X_ETHER_EAPOL_TYPE 0x888E
|
|
|
|
#define DescTypePos 0
|
|
#define KeyInfoPos 1
|
|
#define KeyLenPos 3
|
|
#define ReplayCounterPos 5
|
|
#define KeyNoncePos 13
|
|
#define KeyIVPos 45
|
|
#define KeyRSCPos 61
|
|
#define KeyIDPos 69
|
|
#define KeyMICPos 77
|
|
#define KeyDataLenPos 93
|
|
#define KeyDataPos 95
|
|
#define LIB1X_EAPOL_VER 1 //0000 0001B
|
|
#define LIB1X_EAPOL_EAPPKT 0 //0000 0000B
|
|
#define LIB1X_EAPOL_START 1 //0000 0001B
|
|
#define LIB1X_EAPOL_LOGOFF 2 //0000 0010B
|
|
#define LIB1X_EAPOL_KEY 3 //0000 0011B
|
|
#define LIB1X_EAPOL_ENCASFALERT 4 //0000 0100B
|
|
|
|
|
|
#define A_SHA_DIGEST_LEN 20
|
|
#define ETHER_HDRLEN 14
|
|
#define LIB1X_EAPOL_HDRLEN 4
|
|
#define INFO_ELEMENT_SIZE 128
|
|
#define MAX_EAPOLMSG_LEN 512
|
|
#define MAX_EAPOLKEYMSG_LEN (MAX_EAPOLMSG_LEN-(ETHER_HDRLEN+LIB1X_EAPOL_HDRLEN))
|
|
#define EAPOLMSG_HDRLEN 95 //EAPOL-key payload length without KeyData
|
|
#define WPA_ELEMENT_ID 0xDD
|
|
#define WPA2_ELEMENT_ID 0x30
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#endif
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
#define ETHER_ADDRLEN 6
|
|
#define PMK_EXPANSION_CONST "Pairwise key expansion"
|
|
#define PMK_EXPANSION_CONST_SIZE 22
|
|
#define GMK_EXPANSION_CONST "Group key expansion"
|
|
#define GMK_EXPANSION_CONST_SIZE 19
|
|
#define RANDOM_EXPANSION_CONST "Init Counter"
|
|
#define RANDOM_EXPANSION_CONST_SIZE 12
|
|
|
|
#define WLAN_REASON_MIC_FAILURE 14
|
|
#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15
|
|
|
|
/*
|
|
2008-12-16, For Corega CG-WLCB54GL 54Mbps NIC interoperability issue.
|
|
The behavior of this NIC when it connect to the other AP with WPA/TKIP is:
|
|
AP <----------------------> STA
|
|
....................
|
|
------------> Assoc Rsp (ok)
|
|
------------> EAPOL-key (4-way msg 1)
|
|
<------------ unknown TKIP encryption data
|
|
------------> EAPOL-key (4-way msg 1)
|
|
<------------ unknown TKIP encryption data
|
|
.....................
|
|
<------------ disassoc (code=8, STA is leaving) when the 5 seconds timer timeout counting from Assoc_Rsp is got.
|
|
....................
|
|
------------> Assoc Rsp (ok)
|
|
<-----------> EAPOL-key (4-way handshake success)
|
|
|
|
If MAX_RESEND_NUM=3, our AP will send disassoc (code=15, 4-way timeout) to STA before STA sending disassoc to AP.
|
|
And this NIC will always can not connect to our AP.
|
|
set MAX_RESEND_NUM=5 can fix this issue.
|
|
*/
|
|
//#define MAX_RESEND_NUM 3
|
|
#define MAX_RESEND_NUM 5
|
|
#define RESEND_TIME 1000
|
|
|
|
#define GK_REKEY_TIME 3600000 //Set rekey period to 1 hour
|
|
|
|
typedef enum {
|
|
desc_type_RSN = 2,
|
|
desc_type_WPA = 254
|
|
} DescTypeRSN;
|
|
|
|
typedef enum {
|
|
type_Group = 0,
|
|
type_Pairwise = 1
|
|
} KeyType;
|
|
|
|
typedef enum {
|
|
key_desc_ver1 = 1,
|
|
key_desc_ver2 = 2
|
|
} KeyDescVer;
|
|
|
|
enum {
|
|
PSK_WPA = 1,
|
|
PSK_WPA2 = 2
|
|
};
|
|
|
|
enum {
|
|
PSK_STATE_IDLE,
|
|
PSK_STATE_PTKSTART,
|
|
PSK_STATE_PTKINITNEGOTIATING,
|
|
PSK_STATE_PTKINITDONE,
|
|
};
|
|
|
|
enum {
|
|
PSK_GSTATE_REKEYNEGOTIATING,
|
|
PSK_GSTATE_REKEYESTABLISHED,
|
|
PSK_GSTATE_KEYERROR,
|
|
};
|
|
|
|
typedef struct _OCTET_STRING {
|
|
unsigned char *Octet;
|
|
int Length;
|
|
} OCTET_STRING;
|
|
|
|
typedef union _LARGE_INTEGER {
|
|
unsigned char charData[8];
|
|
struct {
|
|
unsigned long HighPart;
|
|
unsigned long LowPart;
|
|
} field;
|
|
} LARGE_INTEGER, *PLARGE_INTEGER;
|
|
|
|
typedef union _OCTET16_INTEGER {
|
|
unsigned char charData[16];
|
|
struct {
|
|
LARGE_INTEGER HighPart;
|
|
LARGE_INTEGER LowPart;
|
|
} field;
|
|
} OCTET16_INTEGER;
|
|
|
|
typedef union _OCTET32_INTEGER {
|
|
unsigned char charData[32];
|
|
struct {
|
|
OCTET16_INTEGER HighPart;
|
|
OCTET16_INTEGER LowPart;
|
|
} field;
|
|
} OCTET32_INTEGER;
|
|
|
|
// group key info
|
|
typedef struct _wpa_global_info {
|
|
OCTET32_INTEGER Counter;
|
|
//Save PSK to global array
|
|
// unsigned char PSK[A_SHA_DIGEST_LEN * 2];
|
|
int GTKAuthenticator;
|
|
int GKeyDoneStations;
|
|
int GInitAKeys;
|
|
int GUpdateStationKeys;
|
|
int GkeyReady;
|
|
OCTET_STRING AuthInfoElement;
|
|
unsigned char AuthInfoBuf[INFO_ELEMENT_SIZE];
|
|
unsigned char MulticastCipher;
|
|
OCTET_STRING GNonce;
|
|
unsigned char GNonceBuf[KEY_NONCE_LEN];
|
|
unsigned char GTK[NumGroupKey][GTK_LEN];
|
|
unsigned char GMK[GMK_LEN];
|
|
int GN;
|
|
int GM;
|
|
int GTKRekey;
|
|
#ifdef CONFIG_GK_REKEY
|
|
struct timer_list GKRekeyTimer;
|
|
#endif
|
|
} WPA_GLOBAL_INFO;
|
|
|
|
// wpa sta info
|
|
typedef struct _wpa_sta_info {
|
|
int state;
|
|
int gstate;
|
|
int RSNEnabled; // bit0-WPA, bit1-WPA2
|
|
int PInitAKeys;
|
|
unsigned char UnicastCipher;
|
|
LARGE_INTEGER CurrentReplayCounter;
|
|
LARGE_INTEGER ReplayCounterStarted; // david+1-12-2007
|
|
OCTET_STRING ANonce;
|
|
OCTET_STRING SNonce;
|
|
unsigned char AnonceBuf[KEY_NONCE_LEN];
|
|
unsigned char SnonceBuf[KEY_NONCE_LEN];
|
|
unsigned char PMK[PMK_LEN];
|
|
unsigned char PTK[PTK_LEN_TKIP];
|
|
OCTET_STRING EAPOLMsgRecvd;
|
|
OCTET_STRING EAPOLMsgSend;
|
|
OCTET_STRING EapolKeyMsgRecvd;
|
|
OCTET_STRING EapolKeyMsgSend;
|
|
|
|
unsigned char eapSendBuf[MAX_EAPOLMSG_LEN];
|
|
// unsigned char eapRecvdBuf[MAX_EAPOLMSG_LEN];
|
|
struct timer_list resendTimer;
|
|
int resendCnt;
|
|
int clientHndshkProcessing;
|
|
int clientHndshkDone;
|
|
int clientGkeyUpdate;
|
|
LARGE_INTEGER clientMICReportReplayCounter;
|
|
} WPA_STA_INFO;
|
|
|
|
typedef struct _LIB1X_EAPOL_KEY
|
|
{
|
|
unsigned char key_desc_ver;
|
|
unsigned char key_info[2];
|
|
unsigned char key_len[2];
|
|
unsigned char key_replay_counter[KEY_RC_LEN];
|
|
unsigned char key_nounce[KEY_NONCE_LEN];
|
|
unsigned char key_iv[KEY_IV_LEN];
|
|
unsigned char key_rsc[KEY_RSC_LEN];
|
|
unsigned char key_id[KEY_ID_LEN];
|
|
unsigned char key_mic[KEY_MIC_LEN];
|
|
unsigned char key_data_len[KEY_MATERIAL_LEN];
|
|
unsigned char *key_data;
|
|
} lib1x_eapol_key;
|
|
|
|
struct lib1x_eapol
|
|
{
|
|
unsigned char protocol_version;
|
|
unsigned char packet_type; // This makes it odd in number !
|
|
unsigned short packet_body_length;
|
|
};
|
|
|
|
struct wlan_ethhdr_t
|
|
{
|
|
unsigned char daddr[WLAN_ETHADDR_LEN];
|
|
unsigned char saddr[WLAN_ETHADDR_LEN];
|
|
unsigned short type;
|
|
};
|
|
|
|
typedef enum{
|
|
DOT11_PortStatus_Unauthorized,
|
|
DOT11_PortStatus_Authorized,
|
|
DOT11_PortStatus_Guest
|
|
}DOT11_PORT_STATUS;
|
|
|
|
#ifdef CONFIG_MOVE_PSK_TO_ROM
|
|
static __inline__ OCTET_STRING SubStr(OCTET_STRING f, unsigned short s, unsigned short l)
|
|
{
|
|
OCTET_STRING res;
|
|
|
|
res.Length = l;
|
|
res.Octet = f.Octet + s;
|
|
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
#define SetSubStr(f,a,l) memcpy(f.Octet+l,a.Octet,a.Length)
|
|
#define GetKeyInfo0(f, mask) ((f.Octet[KeyInfoPos + 1] & mask) ? 1 : 0)
|
|
#define SetKeyInfo0(f,mask,b) (f.Octet[KeyInfoPos + 1] = (f.Octet[KeyInfoPos + 1] & ~mask) | ( b?mask:0x0) )
|
|
#define GetKeyInfo1(f, mask) ((f.Octet[KeyInfoPos] & mask) ? 1 : 0)
|
|
#define SetKeyInfo1(f,mask,b) (f.Octet[KeyInfoPos] = (f.Octet[KeyInfoPos] & ~mask) | ( b?mask:0x0) )
|
|
|
|
// EAPOLKey
|
|
#define Message_DescType(f) (f.Octet[DescTypePos])
|
|
#define Message_setDescType(f, type) (f.Octet[DescTypePos] = type)
|
|
// Key Information Filed
|
|
#define Message_KeyDescVer(f) (f.Octet[KeyInfoPos+1] & 0x07)
|
|
#define Message_setKeyDescVer(f, v) (f.Octet[KeyInfoPos+1] &= 0xf8) , f.Octet[KeyInfoPos+1] |= (v & 0x07)
|
|
#define Message_KeyType(f) GetKeyInfo0(f, 0x08)
|
|
#define Message_setKeyType(f, b) SetKeyInfo0(f,0x08,b)
|
|
#define Message_KeyIndex(f) ((f.Octet[KeyInfoPos+1] & 0x30) >> 4) & 0x03
|
|
#define Message_setKeyIndex(f, v) (f.Octet[KeyInfoPos+1] &= 0xcf), f.Octet[KeyInfoPos+1] |= ((v<<4) & 0x30)
|
|
#define Message_setInstall(f, b) SetKeyInfo0(f,0x40,b)
|
|
#define Message_setKeyAck(f, b) SetKeyInfo0(f,0x80,b)
|
|
|
|
#define Message_KeyMIC(f) GetKeyInfo1(f, 0x01)
|
|
#define Message_setKeyMIC(f, b) SetKeyInfo1(f,0x01,b)
|
|
#define Message_Secure(f) GetKeyInfo1(f,0x02)
|
|
#define Message_setSecure(f, b) SetKeyInfo1(f,0x02,b)
|
|
#define Message_Error(f) GetKeyInfo1(f,0x04)
|
|
#define Message_setError(f, b) SetKeyInfo1(f,0x04,b)
|
|
#define Message_Request(f) GetKeyInfo1(f,0x08)
|
|
#define Message_setRequest(f, b) SetKeyInfo1(f,0x08,b)
|
|
#define Message_setReserved(f, v) (f.Octet[KeyInfoPos] |= (v<<4&0xff))
|
|
#define Message_KeyLength(f) ((unsigned short)(f.Octet[KeyLenPos] <<8) + (unsigned short)(f.Octet[KeyLenPos+1]))
|
|
#define Message_setKeyLength(f, v) (f.Octet[KeyLenPos] = (v&0xff00) >>8 , f.Octet[KeyLenPos+1] = (v&0x00ff))
|
|
|
|
#define Message_KeyNonce(f) SubStr(f, KeyNoncePos, KEY_NONCE_LEN)
|
|
#define Message_setKeyNonce(f, v) SetSubStr(f, v, KeyNoncePos)
|
|
#define Message_EqualKeyNonce(f1, f2) memcmp(f1.Octet + KeyNoncePos, f2.Octet, KEY_NONCE_LEN)? 0:1
|
|
#define Message_setKeyIV(f, v) SetSubStr(f, v, KeyIVPos)
|
|
#define Message_setKeyRSC(f, v) SetSubStr(f, v, KeyRSCPos)
|
|
#define Message_setKeyID(f, v) SetSubStr(f, v, KeyIDPos)
|
|
#define Message_setMIC(f, v) SetSubStr(f, v, KeyMICPos)
|
|
#define Message_KeyDataLength(f) ((unsigned short)(f.Octet[KeyDataLenPos] <<8) + (unsigned short)(f.Octet[KeyDataLenPos+1]))
|
|
#define Message_setKeyDataLength(f, v) (f.Octet[KeyDataLenPos] = (v&0xff00) >>8 , f.Octet[KeyDataLenPos+1] = (v&0x00ff))
|
|
#define Message_setKeyData(f, v) SetSubStr(f, v, KeyDataPos);
|
|
|
|
#define Message_CopyReplayCounter(f1, f2) memcpy(f1.Octet + ReplayCounterPos, f2.Octet + ReplayCounterPos, KEY_RC_LEN)
|
|
#define Message_DefaultReplayCounter(li) (((li.field.HighPart == 0xffffffff) && (li.field.LowPart == 0xffffffff) ) ?1:0)
|
|
|
|
#define GET_MY_HWADDR(padapter) ((padapter)->eeprompriv.mac_addr)
|
|
#define LargeIntegerOverflow(x) (x.field.HighPart == 0xffffffff) && (x.field.LowPart == 0xffffffff)
|
|
#define LargeIntegerZero(x) memset(&x.charData, 0, 8)
|
|
#define Octet16IntegerOverflow(x) LargeIntegerOverflow(x.field.HighPart) && LargeIntegerOverflow(x.field.LowPart)
|
|
#define Octet16IntegerZero(x) memset(&x.charData, 0, 16)
|
|
#define SetNonce(ocDst, oc32Counter) SetEAPOL_KEYIV(ocDst, oc32Counter)
|
|
|
|
void ClientSendEAPOL(_adapter *padapter, struct sta_info *psta, int resend);
|
|
void SendEAPOL(_adapter *padapter, struct sta_info *psta, int resend);
|
|
void EAPOLKeyRecvd(_adapter *padapter, struct sta_info *psta);
|
|
void ClientEAPOLKeyRecvd(_adapter *padapter, struct sta_info *psta);
|
|
void init_wpa_sta_info(_adapter *padapter, struct sta_info *psta);
|
|
void psk_init(_adapter *padapter, unsigned char *pie, unsigned short ielen);
|
|
void psk_derive(_adapter *padapter, unsigned char *passphrase, unsigned char *ssid);
|
|
u16 psk_strip_rsn_pairwise(u8 *ie, u16 ie_len);
|
|
u16 psk_strip_wpa_pairwise(u8 *ie, u16 ie_len);
|
|
|
|
#endif // _RTW_PSK_H_
|
|
|