drivers/staging/rtl8723bs/core/rtw_security.c

Source file repositories/reference/linux-study-clean/drivers/staging/rtl8723bs/core/rtw_security.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/rtl8723bs/core/rtw_security.c
Extension
.c
Size
47349 bytes
Lines
1500
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if ((curfragnum + 1) == pattrib->nr_frags) {	/* the last fragment */

				length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;

				crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));

				arc4_setkey(ctx, wepkey, 3 + keylength);
				arc4_crypt(ctx, payload, payload, length);
				arc4_crypt(ctx, payload + length, crc.f1, 4);

			} else {
				length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
				crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
				arc4_setkey(ctx, wepkey, 3 + keylength);
				arc4_crypt(ctx, payload, payload, length);
				arc4_crypt(ctx, payload + length, crc.f1, 4);

				pframe += pxmitpriv->frag_len;
				pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
			}
		}
	}
}

void rtw_wep_decrypt(struct adapter  *padapter, u8 *precvframe)
{
	/*  exclude ICV */
	u8 crc[4];
	signed int	length;
	u32 keylength;
	u8 *pframe, *payload, *iv, wepkey[16];
	u8  keyindex;
	struct	rx_pkt_attrib	 *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);
	struct	security_priv *psecuritypriv = &padapter->securitypriv;
	struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx;

	pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;

	/* start to decrypt recvframe */
	if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
		iv = pframe + prxattrib->hdrlen;
		/* keyindex =(iv[3]&0x3); */
		keyindex = prxattrib->key_index;
		keylength = psecuritypriv->dot11DefKeylen[keyindex];
		memcpy(&wepkey[0], iv, 3);
		/* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
		memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
		length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;

		payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;

		/* decrypt payload include icv */
		arc4_setkey(ctx, wepkey, 3 + keylength);
		arc4_crypt(ctx, payload, payload,  length);

		/* calculate icv and compare the icv */
		*((u32 *)crc) = ~crc32_le(~0, payload, length - 4);

	}
}

/* 3		=====TKIP related ===== */

static void secmicclear(struct mic_data *pmicdata)
{
/*  Reset the state to the empty message. */
	pmicdata->L = pmicdata->K0;
	pmicdata->R = pmicdata->K1;
	pmicdata->nBytesInM = 0;
	pmicdata->M = 0;
}

void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
{
	/*  Set the key */
	pmicdata->K0 = get_unaligned_le32(key);
	pmicdata->K1 = get_unaligned_le32(key + 4);
	/*  and reset the message */
	secmicclear(pmicdata);
}

void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
{
	/*  Append the byte to our word-sized buffer */
	pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);
	pmicdata->nBytesInM++;
	/*  Process the word if it is full. */
	if (pmicdata->nBytesInM >= 4) {
		pmicdata->L ^= pmicdata->M;
		pmicdata->R ^= ROL32(pmicdata->L, 17);

Annotation

Implementation Notes