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; }
u8 rtw_set_802_11_add_key(struct rtw_adapter *padapter, struct 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_)) { u32 keyindex; u32 len = FIELD_OFFSET(struct ndis_802_11_key, KeyMaterial) + key->KeyLength; struct 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")); memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); 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; }
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; }