// SPDX-License-Identifier: GPL-2.0 /****************************************************************************** * rtl871x_security.c * * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. * Linux device driver for RTL8192SU * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * * Contact information: * WLAN FAE <[email protected]> * Larry Finger <[email protected]> * ******************************************************************************/ #define _RTL871X_SECURITY_C_ #include <linux/compiler.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/kref.h> #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/circ_buf.h> #include <linux/uaccess.h> #include <asm/byteorder.h> #include <linux/atomic.h> #include <linux/crc32poly.h> #include <linux/semaphore.h> #include <linux/ieee80211.h> #include "osdep_service.h" #include "drv_types.h" #include "osdep_intf.h" /* =====WEP related===== */ struct arc4context { … }; static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) { … } static u32 arcfour_byte(struct arc4context *parc4ctx) { … } static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len) { … } static sint bcrc32initialized; static u32 crc32_table[256]; static u8 crc32_reverseBit(u8 data) { … } static void crc32_init(void) { … } static u32 getcrc32(u8 *buf, u32 len) { … } /* * Need to consider the fragment situation */ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) { … } void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe) { … } /* 3 =====TKIP related===== */ static u32 secmicgetuint32(u8 *p) /* Convert from Byte[] to Us4Byte32 in a portable way */ { … } static void secmicputuint32(u8 *p, u32 val) /* Convert from Us4Byte32 to Byte[] in a portable way */ { … } static void secmicclear(struct mic_data *pmicdata) { … } void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key) { … } static void secmicappendbyte(struct mic_data *pmicdata, u8 b) { … } void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes) { … } void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst) { … } void seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri) { … } /* macros for extraction/creation of unsigned char/unsigned short values */ #define RotR1(v16) … #define Lo8(v16) … #define Hi8(v16) … #define Lo16(v32) … #define Hi16(v32) … #define Mk16(hi, lo) … /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ #define TK16(N) … /* S-box lookup: 16 bits --> 16 bits */ #define _S_(v16) … /* fixed algorithm "parameters" */ #define PHASE1_LOOP_CNT … #define TA_SIZE … #define TK_SIZE … #define P1K_SIZE … #define RC4_KEY_SIZE … /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ static const unsigned short Sbox1[2][256] = …; /* ********************************************************************** * Routine: Phase 1 -- generate P1K, given TA, TK, IV32 * * Inputs: * tk[] = temporal key [128 bits] * ta[] = transmitter's MAC address [ 48 bits] * iv32 = upper 32 bits of IV [ 32 bits] * Output: * p1k[] = Phase 1 key [ 80 bits] * * Note: * This function only needs to be called every 2**16 packets, * although in theory it could be called every packet. * ********************************************************************** */ static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) { … } /* ********************************************************************** * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 * * Inputs: * tk[] = Temporal key [128 bits] * p1k[] = Phase 1 output key [ 80 bits] * iv16 = low 16 bits of IV counter [ 16 bits] * Output: * rc4key[] = the key used to encrypt the packet [128 bits] * * Note: * The value {TA,IV32,IV16} for Phase1/Phase2 must be unique * across all packets using the same key TK value. Then, for a * given value of TK[], this TKIP48 construction guarantees that * the final RC4KEY value is unique across all packets. * * Suggested implementation optimization: if PPK[] is "overlaid" * appropriately on RC4KEY[], there is no need for the final * for loop below that copies the PPK[] result into RC4KEY[]. * ********************************************************************** */ static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) { … } /*The hlen isn't include the IV*/ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) { … } /* The hlen doesn't include the IV */ void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) { … } /* 3 =====AES related===== */ #define MAX_MSG_SIZE … /*****************************/ /******** SBOX Table *********/ /*****************************/ static const u8 sbox_table[256] = …; /****************************************/ /* aes128k128d() */ /* Performs a 128 bit AES encrypt with */ /* 128 bit data. */ /****************************************/ static void xor_128(u8 *a, u8 *b, u8 *out) { … } static void xor_32(u8 *a, u8 *b, u8 *out) { … } static u8 sbox(u8 a) { … } static void next_key(u8 *key, sint round) { … } static void byte_sub(u8 *in, u8 *out) { … } static void shift_row(u8 *in, u8 *out) { … } static void mix_column(u8 *in, u8 *out) { … } static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) { … } /************************************************/ /* construct_mic_iv() */ /* Builds the MIC IV from header fields and PN */ /************************************************/ static void construct_mic_iv(u8 *mic_iv, sint qc_exists, sint a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector) { … } /************************************************/ /* construct_mic_header1() */ /* Builds the first MIC header block from */ /* header fields. */ /************************************************/ static void construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu) { … } /************************************************/ /* construct_mic_header2() */ /* Builds the last MIC header block from */ /* header fields. */ /************************************************/ static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists, sint qc_exists) { … } /************************************************/ /* construct_mic_header2() */ /* Builds the last MIC header block from */ /* header fields. */ /************************************************/ static void construct_ctr_preload(u8 *ctr_preload, sint a4_exists, sint qc_exists, u8 *mpdu, u8 *pn_vector, sint c) { … } /************************************/ /* bitwise_xor() */ /* A 128 bit, bitwise exclusive or */ /************************************/ static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) { … } static void aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) { … } u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) { … } static void aes_decipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) { … } void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) { … } void r8712_use_tkipkey_handler(struct timer_list *t) { … }