void sreset_restore_security_station(_adapter *padapter) { u8 EntryId = 0; struct mlme_priv *mlmepriv = &padapter->mlmepriv; struct sta_priv * pstapriv = &padapter->stapriv; struct sta_info *psta; struct security_priv* psecuritypriv=&(padapter->securitypriv); struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; { u8 val8; if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) { val8 = 0xcc; #ifdef CONFIG_WAPI_SUPPORT } else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) { //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. val8 = 0x4c; #endif } else { val8 = 0xcf; } rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); } #if 0 if ( ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP40_ ) || ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP104_ )) { for(EntryId=0; EntryId<4; EntryId++) { if(EntryId == psecuritypriv->dot11PrivacyKeyIndex) rtw_set_key(padapter,&padapter->securitypriv, EntryId, 1); else rtw_set_key(padapter,&padapter->securitypriv, EntryId, 0); } } else #endif if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) { psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv)); if (psta == NULL) { //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); } else { //pairwise key rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); //group key rtw_set_key(padapter,&padapter->securitypriv,padapter->securitypriv.dot118021XGrpKeyid, 0); } } }
static void _restore_security_setting(_adapter *padapter) { u8 EntryId = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv * pstapriv = &padapter->stapriv; struct sta_info *psta; struct security_priv* psecuritypriv=&(padapter->securitypriv); struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? rtw_write8(padapter, REG_SECCFG, 0xcc) : rtw_write8(padapter, REG_SECCFG, 0xcf); if ( ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP40_ ) || ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP104_ )) { for(EntryId=0; EntryId<4; EntryId++) { if(EntryId == psecuritypriv->dot11PrivacyKeyIndex) rtw_set_key(padapter,&padapter->securitypriv, EntryId, 1); else rtw_set_key(padapter,&padapter->securitypriv, EntryId, 0); } } else if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) { psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); if (psta == NULL) { //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); } else { //pairwise key rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); //group key rtw_set_key(padapter,&padapter->securitypriv,padapter->securitypriv.dot118021XGrpKeyid, 0); } } }
u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){ uint encryptionalgo; u8 * pbssid; struct sta_info *stainfo; u8 bgroup = _FALSE; u8 bgrouptkey = _FALSE;//can be remove later u8 ret=_SUCCESS; _func_enter_; if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, // it must fail the request and return NDIS_STATUS_INVALID_DATA. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex)); ret= _FAIL; goto exit; } if(key->KeyIndex & 0x40000000) { // Pairwise key RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n")); pbssid=get_bssid(&padapter->mlmepriv); stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid); if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n")); encryptionalgo=stainfo->dot118021XPrivacy; } else{ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n")); encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; } RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo )); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm)); if((stainfo!=NULL)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy)); } if(key->KeyIndex & 0x000000FF){ // The key index is specified in the lower 8 bits by values of zero to 255. // The key index should be set to zero for a Pairwise key, and the driver should fail with // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n")); ret= _FAIL; goto exit; } // check BSSID if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n")); ret= _FALSE; goto exit; } // Check key length for TKIP. //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength)); ret=_FAIL; goto exit; } // Check key length for AES. if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. if(key->KeyLength == 32) { key->KeyLength = 16; } else { ret= _FAIL; goto exit; } } // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength)); ret=_FAIL; goto exit; } bgroup = _FALSE; // Check the pairwise key. Added by Annie, 2005-07-06. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); } else { // Group key - KeyIndex(BIT30==0) RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n")); // when add wep key through add key and didn't assigned encryption type before if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy)); switch(key->KeyLength) { case 5: padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; case 13: padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; default: padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; } encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm)); } else { encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength)); } if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n")); ret= _FAIL; goto exit; } // Check key length for TKIP if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength)); ret= _FAIL; goto exit; } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { // Check key length for AES // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength)); ret= _FAIL; goto exit; } // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { key->KeyLength = 16; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) ); } if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 bgrouptkey = _TRUE; } if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE)) { bgrouptkey = _TRUE; } bgroup = _TRUE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") ); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") ); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); } // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) { u8 ret; u32 keyindex; u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n")); wep->Length = len; keyindex = key->KeyIndex&0x7fffffff; wep->KeyIndex = keyindex ; wep->KeyLength = key->KeyLength; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n")); _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; padapter->securitypriv.dot11PrivacyKeyIndex=keyindex; ret = rtw_set_802_11_add_wep(padapter, wep); goto exit; } if(key->KeyIndex & 0x20000000){ // SetRSC RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n")); if(bgroup == _TRUE) { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); } else { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); } } // Indicate this key idx is used for TX // Save the key in KeyMaterial if(bgroup == _TRUE) // Group transmit key { int res; if(bgrouptkey == _TRUE) { padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex; } if((key->KeyIndex&0x3) == 0){ ret = _FAIL; goto exit; } _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16); _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); if((key->KeyIndex & 0x10000000)) { _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); } else { _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); } //set group key by index _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); key->KeyIndex=key->KeyIndex & 0x03; padapter->securitypriv.binstallGrpkey=_TRUE; padapter->securitypriv.bcheck_grpkey=_FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key")); res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1); if(res==_FAIL) ret= _FAIL; goto exit; } else // Pairwise Key { u8 res; pbssid=get_bssid(&padapter->mlmepriv); stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); if(stainfo!=NULL) { _rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); if(encryptionalgo== _TKIP_) { padapter->securitypriv.busetkipkey=_FALSE; //_set_timer(&padapter->securitypriv.tkip_timer, 50); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n")); // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] if((key->KeyIndex & 0x10000000)){ _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); } else { _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); } } else if(encryptionalgo == _AES_) { } //Set key to CAM through H2C command if(bgrouptkey)//never go to here { res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n")); } else{ res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n")); } if(res ==_FALSE) ret= _FAIL; } } exit: _func_exit_; return ret; }
uint8_t rtw_set_802_11_add_key(struct rtl_priv* rtlpriv, NDIS_802_11_KEY *key){ uint encryptionalgo; uint8_t * pbssid; struct sta_info *stainfo; uint8_t bgroup = _FALSE; uint8_t bgrouptkey = _FALSE;//can be remove later uint8_t ret=_SUCCESS; if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, // it must fail the request and return NDIS_STATUS_INVALID_DATA. ret= _FAIL; goto exit; } if(key->KeyIndex & 0x40000000) { // Pairwise key pbssid=get_bssid(&rtlpriv->mlmepriv); stainfo=rtw_get_stainfo(&rtlpriv->stapriv, pbssid); if((stainfo!=NULL)&&(rtlpriv->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ encryptionalgo=stainfo->dot118021XPrivacy; } else{ encryptionalgo=rtlpriv->securitypriv.dot11PrivacyAlgrthm; } if((stainfo!=NULL)){ ; } if(key->KeyIndex & 0x000000FF){ // The key index is specified in the lower 8 bits by values of zero to 255. // The key index should be set to zero for a Pairwise key, and the driver should fail with // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero ret= _FAIL; goto exit; } // check BSSID if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ ret= _FALSE; goto exit; } // Check key length for TKIP. //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ ret=_FAIL; goto exit; } // Check key length for AES. if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. if(key->KeyLength == 32) { key->KeyLength = 16; } else { ret= _FAIL; goto exit; } } // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { ret=_FAIL; goto exit; } bgroup = _FALSE; } else { // when add wep key through add key and didn't assigned encryption type before if((rtlpriv->securitypriv.ndisauthtype<=3)&&(rtlpriv->securitypriv.dot118021XGrpPrivacy==0)) { switch(key->KeyLength) { case 5: rtlpriv->securitypriv.dot11PrivacyAlgrthm=_WEP40_; break; case 13: rtlpriv->securitypriv.dot11PrivacyAlgrthm=_WEP104_; break; default: rtlpriv->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; break; } encryptionalgo=rtlpriv->securitypriv.dot11PrivacyAlgrthm; } else { encryptionalgo=rtlpriv->securitypriv.dot118021XGrpPrivacy; } if((check_fwstate(&rtlpriv->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { ret= _FAIL; goto exit; } // Check key length for TKIP if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { ret= _FAIL; goto exit; } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { // Check key length for AES // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. ret= _FAIL; goto exit; } // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { key->KeyLength = 16; } if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 bgrouptkey = _TRUE; } if((check_fwstate(&rtlpriv->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&rtlpriv->mlmepriv, _FW_LINKED)==_TRUE)) { bgrouptkey = _TRUE; } bgroup = _TRUE; } // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). if((rtlpriv->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) { uint8_t ret; uint32_t keyindex; uint32_t len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; NDIS_802_11_WEP *wep = &rtlpriv->securitypriv.ndiswep; wep->Length = len; keyindex = key->KeyIndex&0x7fffffff; wep->KeyIndex = keyindex ; wep->KeyLength = key->KeyLength; memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); memcpy(&(rtlpriv->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); rtlpriv->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; rtlpriv->securitypriv.dot11PrivacyKeyIndex=keyindex; ret = rtw_set_802_11_add_wep(rtlpriv, wep); goto exit; } if(key->KeyIndex & 0x20000000){ // SetRSC if(bgroup == _TRUE) { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; memcpy(&rtlpriv->securitypriv.dot11Grprxpn, &keysrc, 8); } else { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; memcpy(&rtlpriv->securitypriv.dot11Grptxpn, &keysrc, 8); } } // Indicate this key idx is used for TX // Save the key in KeyMaterial if(bgroup == _TRUE) // Group transmit key { int res; if(bgrouptkey == _TRUE) { rtlpriv->securitypriv.dot118021XGrpKeyid=(uint8_t)key->KeyIndex; } if((key->KeyIndex&0x3) == 0){ ret = _FAIL; goto exit; } memset(&rtlpriv->securitypriv.dot118021XGrpKey[(uint8_t)((key->KeyIndex) & 0x03)], 0, 16); memset(&rtlpriv->securitypriv.dot118021XGrptxmickey[(uint8_t)((key->KeyIndex) & 0x03)], 0, 16); memset(&rtlpriv->securitypriv.dot118021XGrprxmickey[(uint8_t)((key->KeyIndex) & 0x03)], 0, 16); if((key->KeyIndex & 0x10000000)) { memcpy(&rtlpriv->securitypriv.dot118021XGrptxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); memcpy(&rtlpriv->securitypriv.dot118021XGrprxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); } else { memcpy(&rtlpriv->securitypriv.dot118021XGrptxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); memcpy(&rtlpriv->securitypriv.dot118021XGrprxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); } //set group key by index memcpy(&rtlpriv->securitypriv.dot118021XGrpKey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); key->KeyIndex=key->KeyIndex & 0x03; rtlpriv->securitypriv.binstallGrpkey=_TRUE; rtlpriv->securitypriv.bcheck_grpkey=_FALSE; res=rtw_set_key(rtlpriv,&rtlpriv->securitypriv, key->KeyIndex, 1); if(res==_FAIL) ret= _FAIL; goto exit; } else // Pairwise Key { uint8_t res; pbssid=get_bssid(&rtlpriv->mlmepriv); stainfo=rtw_get_stainfo(&rtlpriv->stapriv , pbssid ); if(stainfo!=NULL) { memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); if(encryptionalgo== _TKIP_) { rtlpriv->securitypriv.busetkipkey=_FALSE; //_set_timer(&rtlpriv->securitypriv.tkip_timer, 50); // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] if((key->KeyIndex & 0x10000000)){ memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); } else { memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); } } else if(encryptionalgo == _AES_) { } //Set key to CAM through H2C command if(bgrouptkey)//never go to here { res=rtw_setstakey_cmd(rtlpriv, (unsigned char *)stainfo, _FALSE); } else{ res=rtw_setstakey_cmd(rtlpriv, (unsigned char *)stainfo, _TRUE); } if(res ==_FALSE) ret= _FAIL; } } exit: return ret; }