⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlc_key.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		break;	default:		WL_ERROR(("wl%d: wlc_key_iv_update: unsupported algorithm %d\n", wlc->pub.unit,			key->algo));		ASSERT(1 == 0);		break;	}	WL_WSEC(("wl%d: wlc_key_iv_update end: iv32 0x%08x iv16 0x%04x\n", wlc->pub.unit, txiv->hi,		txiv->lo));}wsec_key_t*wlc_key_lookup(wlc_info_t *wlc, struct scb *scb, wlc_bsscfg_t *bsscfg, uint index, bool ismulti){	wsec_key_t *key = NULL;	WL_WSEC(("\nwl%d: wlc_key_lookup: index %d\n", wlc->pub.unit, index));	if (scb->key && !ismulti) {		key = scb->key;		ASSERT(WSEC_KEY_INDEX(wlc, key) < WLC_MAX_WSEC_KEYS(wlc));		/* ASSERT(key->index == index); */		/* indexes should both be zero for per-path key */		WL_WSEC(("wl%d: wlc_key_lookup: per-path key-ID %d index %d, algo %d\n",			wlc->pub.unit,			key->id, key->idx, key->algo));	} else {		ASSERT(index < WSEC_MAX_DEFAULT_KEYS);		key = WLC_BSSCFG_WEPKEY(bsscfg, index);		if (key) {			WL_WSEC(("wl%d: wlc_key_lookup: valid group key at key-ID %d, algo %d\n",				wlc->pub.unit, index, key->algo));		} else {			WL_WSEC(("wl%d: wlc_key_lookup: no valid group key at key-ID %d\n",				wlc->pub.unit, index));		}	}	return key;}/* initialize all hardware keys for the current core */voidwlc_key_hw_init_all(wlc_info_t *wlc){	uint i;	uint hw_keys;	WL_TRACE(("wl%d: wlc_key_hw_init_all\n", wlc->pub.unit));	wlc_key_hw_clear_all(wlc);	if (WLC_SW_KEYS(wlc))		return;	hw_keys = WLC_MAX_WSEC_HW_KEYS(wlc);	for (i = 0; i < hw_keys; i++) {		if (WSEC_KEY(wlc, i))			wlc_key_hw_init(wlc, i);	}}/* Clear all hardware key state in the current core. * This assumes that the core has been reset so all registers * have their reset value. */static voidwlc_key_hw_clear_all(wlc_info_t *wlc){	struct ether_addr addr;	int i, hw_keys, num_addrs;	uint16 v;	WL_TRACE(("wl%d: wlc_key_hw_clear_all\n", wlc->pub.unit));	hw_keys = WLC_MAX_WSEC_HW_KEYS(wlc);	/* zero out the entire key table */	wlc_set_shm(wlc, wlc->seckeys, 0, hw_keys * D11_MAX_KEY_SIZE);	for (i = 0; i < hw_keys; i++) {		/* Set the matching SECALGO table entry */		v = WSEC_ALGO_OFF | (i << SKL_INDEX_SHIFT);		wlc_write_shm(wlc, M_SECKINDXALGO_BLK + i*2, v);	}	/* clear the Rx-TA MAC addresses */	bzero(addr.octet, ETHER_ADDR_LEN);	WL_NONE(("**** KEY SETTING\n"));	if (D11REV_LT(wlc->pub.corerev, 5)) {		WL_NONE(("**** KEY SETTING SET ADDR corerev %d \n", wlc->pub.corerev));		/* clear the 4 Rx-TA addrs in the RXE COND registers */		wlc_set_addrmatch(wlc, RCM_WEP_TA0_OFFSET, &addr);		wlc_set_addrmatch(wlc, RCM_WEP_TA1_OFFSET, &addr);		wlc_set_addrmatch(wlc, RCM_WEP_TA2_OFFSET, &addr);		wlc_set_addrmatch(wlc, RCM_WEP_TA3_OFFSET, &addr);		/* clear the soft Rx-TA addrs in shm */		num_addrs = WSEC_MAX_SEC_KEYS - (WSEC_MAX_DEFAULT_KEYS + WSEC_MAX_RXE_KEYS);		wlc_set_shm(wlc, M_SECPSMRXTAMCH_BLK, 0, num_addrs * ETHER_ADDR_LEN);		/* set the soft Rx-TA addr count */		wlc_write_shm(wlc, M_SEC_VALNUMSOFTMCHTA, WSEC_MAX_SEC_KEYS -			(WSEC_MAX_DEFAULT_KEYS + WSEC_MAX_RXE_KEYS));	} else {		WL_NONE(("**** KEY SETTING RCMTA corerev %d \n", wlc->pub.corerev));		/* clear the address table */		for (i = 0; i < (WSEC_MAX_RCMTA_KEYS - WSEC_MAX_DEFAULT_KEYS); i++)			wlc_set_rcmta(wlc, i, &addr);		/* update the rcmta_size reg in case we are running with a		 * WSEC_MAX_RCMTA_KEYS value different than the reset value		 */		W_REG(&wlc->regs->rcmta_size, (WSEC_MAX_RCMTA_KEYS - WSEC_MAX_DEFAULT_KEYS));	}	/* clear the ucode default key flag MHF_DEFKEYVALID */	wlc_mhf(wlc, MHF_DEFKEYVALID, 0, TRUE);	WL_WSEC(("wl%d: wlc_key_hw_clear_all: clear MHF_DEFKEYVALID\n", wlc->pub.unit));}/* Updates all hw keys marked for band switch update in wlc->wsec_bsupdate */voidwlc_key_bsupdate(wlc_info_t *wlc){	int i;	/* update and clear the update flag if set */	for (i = 0; i < WLC_MAX_WSEC_HW_KEYS(wlc); i++) {		if (isset(wlc->wsec_bsupdate.vec, i)) {			clrbit(wlc->wsec_bsupdate.vec, i);			wlc_key_hw_init(wlc, i);		}	}}/* * Return MHF_DEFKEYVALID flag based on soft keys and/or default WEP keys * existances and other factors. *//* * ucode flag MHF_DEFKEYVALID should be SET only when WEP encryption is * enabled, only one SSID is in use, there are valid default WEP keys and * there are no soft keys. It is cleared in all other cases. * The following explains why. * * This flag is meaningful only to encrypted unicast frames received. When * processing a rx'd unicast frame the ucode tries a pairwise key match first * based on the frame's TA and then falls back to a default key indicated by * the key index field in IV field of the frame if no pairwise key match is * found. For multicast/broadcast frames the ucode uses the key index field * in the frames' IV anyway to find the key entry. * * In case of Multi-SSID, the default keys are only valid for one SSID, and * the ucode does not distinguish between the SSIDs when checking the flag. * * In case of software encryption/decryption when soft keys are installed * this flag must be cleared so that encrypted unicast frames can be sent up * to the driver without any decryption attempt when there is no key installed * in the hardware for the TA. It is true for both STA and AP. * * In case of WPA/TKIP|AES we don't support group-key-only configuration and * there must be a pairwise key there on STA and one pairwise key per * associated STA on AP therefore this flag should always be cleared on both * STA and AP. * * In case of mixed WPA/TKIP|AES and 802.1x/WEP this flag should be always * cleared on AP since there must be a pairwise key for each STA. * * In case of 802.1x/WEP it should be always cleared on AP. However it must * be set on STA since there is no pairwise key on STA. * * In case of mixed WPA/TKIP|AES and 802.11/WEP this flag should be always * cleared on AP since the current transition mode support on AP plumbs * pairwise key for WEP STAs too. * * In case of multiple SSID configuration (AP-STA and/or AP-MSSID), default * keys are invalid. * In any other case of 802.11/WEP this flag should always be set. It is true * for both STA and AP. */uint32wlc_key_defkeyflag(wlc_info_t *wlc){	bool defkeys = FALSE, swkeys = FALSE;	wsec_key_t *key;	int j;	/* no default key attempt for WPA */	/* assuming AES or TKIP is enabled */	if (wlc->cfg.WPA_auth != WPA_AUTH_DISABLED)		return 0;	/* set defkeys to TRUE if there are any default WEP keys */	/* assuming WEP is enabled */	for (j = 0; j < WSEC_MAX_DEFAULT_KEYS; j ++) {		if ((key = WSEC_KEY(wlc, j)) &&		    (key->algo == CRYPTO_ALGO_WEP1 || key->algo == CRYPTO_ALGO_WEP128)) {			defkeys = TRUE;			break;		}	}	/* set swkeys to TRUE if there are any soft keys */	for (j = WLC_MAX_WSEC_HW_KEYS(wlc); j < WLC_MAX_WSEC_KEYS(wlc); j++) {		if (WSEC_KEY(wlc, j)) {			swkeys = TRUE;			break;		}	}	/* set the flag only when there are default WEP keys and there are no soft keys */	WL_WSEC(("wl%d: wlc_key_defkeyflag: default WEP keys %s, soft keys %s\n",		wlc->pub.unit, defkeys ? "Yes" : "No", swkeys ? "Yes" : "No"));	return (defkeys && !swkeys) ? MHF_DEFKEYVALID : 0;}/* Carry out any hardware actions needed after a wlc->wsec_key has been modified */voidwlc_key_update(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, int index){	wsec_key_t *key;	WL_TRACE(("wl%d: wlc_key_update key %d\n", wlc->pub.unit, index));		key = WSEC_KEY(wlc, index);	if ((key) && (key->algo == CRYPTO_ALGO_TKIP))		return;	/*	 * Clear the ucode default key valid flag MHF_DEFKEYVALID if inserting	 * a per-STA soft key	 */	if (index >= WLC_MAX_WSEC_HW_KEYS(wlc) && WSEC_KEY(wlc, index)) {		wlc_mhf(wlc, MHF_DEFKEYVALID, 0, TRUE);		WL_WSEC(("wl%d: wlc_key_update: insert soft key %d, clear MHF_DEFKEYVALID\n",		         wlc->pub.unit, index));	}	/*	 * Need to check both soft keys and default WEP keys before	 * making decision to clear or set this flag when deleting a soft key	 */	else if ((index >= WLC_MAX_WSEC_HW_KEYS(wlc) && !WSEC_KEY(wlc, index))) {		uint32 flag = wlc_key_defkeyflag(wlc);		wlc_mhf(wlc, MHF_DEFKEYVALID, flag, TRUE);		WL_WSEC(("wl%d: wlc_key_update: delete soft key %d, %s MHF_DEFKEYVALID\n",		         wlc->pub.unit, index, flag ? "set" : "clear"));	}	/* if this is a soft key, then the hardware needs no update */	if (index >= WLC_MAX_WSEC_HW_KEYS(wlc))		return;	/* since we only update the hardware for the current core,	 * mark the key for update on band switch if we are running on	 * multiple cores	 */	if (wlc->ncores > 1)		setbit(wlc->wsec_bsupdate.vec, index);	/* update the hardware */	if (wlc->pub.up)		wlc_key_hw_init(wlc, index);}/* update the hardware with values to match the corresponding wlc->wsec_key */voidwlc_key_hw_init(wlc_info_t *wlc, int index){	wsec_key_t *key;	struct ether_addr ea;	uint offset;	uint16 v;	WL_TRACE(("wl%d: wlc_key_hw_init key %d\n", wlc->pub.unit, index));	ASSERT(index < WLC_MAX_WSEC_HW_KEYS(wlc));	ASSERT(wlc->sbclk);	if (!WLC_SW_KEYS(wlc))		key = WSEC_KEY(wlc, index);	else		key = NULL;	/* Clear the MAC address match if this is a paired key.	 * This protects the ucode or hardware from getting an	 * address match while we update this key.	 */	if (index >= WSEC_MAX_DEFAULT_KEYS) {		bzero(ea.octet, ETHER_ADDR_LEN);		wlc_key_write_addr(wlc, index, &ea);	}	/* Set the matching SECALGO table entry (algorithm and table index) */	if (!key)		v = WSEC_ALGO_OFF | (index << SKL_INDEX_SHIFT);	else		v = key->algo_hw | (index << SKL_INDEX_SHIFT);	wlc_write_shm(wlc, M_SECKINDXALGO_BLK + index * 2, v);	/*	 * Set the rx and tx default key (i < WSEC_MAX_DEFAULT_KEYS)	 *	or set the per sta key (i >= WSEC_MAX_DEFAULT_KEYS).	 */	offset = index * D11_MAX_KEY_SIZE;	if (key) {		/* Tx default key */		if (index < WSEC_MAX_DEFAULT_KEYS)			wlc_copyto_shm(wlc, wlc->seckeys + offset, key->data, D11_MAX_KEY_SIZE);		/* otherwise, write the key */		wlc_copyto_shm(wlc, wlc->seckeys + WSEC_RXKEYOFF + offset, key->data,				D11_MAX_KEY_SIZE);	} else {		/* zero out key data if no key */		/* Tx default key */		if (index < WSEC_MAX_DEFAULT_KEYS)			wlc_set_shm(wlc, wlc->seckeys + offset, 0, D11_MAX_KEY_SIZE);		/* Rx key */		wlc_set_shm(wlc, wlc->seckeys + WSEC_RXKEYOFF + offset, 0, D11_MAX_KEY_SIZE);	}	/* handle per station keys */	if (key && index >= WSEC_MAX_DEFAULT_KEYS) {		/* update the MAC address match */		wlc_key_write_addr(wlc, index, &key->ea);	}	/* update ucode flag MHF_DEFKEYVALID */	/*	 * Need to check both soft keys and default WEP keys before	 * making decision to either set or clear it when updating a default key	 */	if (index < WSEC_MAX_DEFAULT_KEYS) {		uint32 flag = wlc_key_defkeyflag(wlc);		wlc_mhf(wlc, MHF_DEFKEYVALID, flag, TRUE);		WL_WSEC(("wl%d: wlc_key_hw_init: %s default key %d, %s MHF_DEFKEYVALID\n",		         wlc->pub.unit, key ? "insert" : "delete", index, flag ? "set" : "clear"));	}}/* update the pairwise key address for a hardware key */static voidwlc_key_write_addr(wlc_info_t *wlc, int i, const struct ether_addr *ea){	uint offset;	WL_TRACE(("wl%d: wlc_key_write_addr key %d\n", wlc->pub.unit, i));	ASSERT(i < WLC_MAX_WSEC_HW_KEYS(wlc));	ASSERT(i >= WSEC_MAX_DEFAULT_KEYS);	if (D11REV_LT(wlc->pub.corerev, 5)) {		/* set 4 RXE match registers */		if (i < (WSEC_MAX_DEFAULT_KEYS + WSEC_MAX_RXE_KEYS)) {			/* calculate register offset */			offset = (i - WSEC_MAX_DEFAULT_KEYS) * ETHER_ADDR_LEN / 2;			/* write to RXE match register */			wlc_set_addrmatch(wlc, RCM_WEP_TA0_OFFSET + offset, ea);		} else {			/* set 8 PSM match registers */			/* calculate shared memory offset */			offset = (i - (WSEC_MAX_DEFAULT_KEYS + WSEC_MAX_RXE_KEYS)) * ETHER_ADDR_LEN;			/* write to shared memory */			wlc_copyto_shm(wlc, M_SECPSMRXTAMCH_BLK + offset, ea->octet,				ETHER_ADDR_LEN);		}	} else {		wlc_set_rcmta(wlc, (i - WSEC_MAX_DEFAULT_KEYS), ea);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -