From e90626b5c3d2dec78f3177de8bf8e4e31d69c4ab Mon Sep 17 00:00:00 2001 From: kimocoder Date: Sun, 16 Aug 2020 18:45:23 +0200 Subject: [PATCH] Fixed kernel v5.8 support --- core/rtw_security.c | 284 ---------------------------------- include/rtw_security.h | 6 - os_dep/linux/ioctl_cfg80211.c | 49 ++---- 3 files changed, 10 insertions(+), 329 deletions(-) diff --git a/core/rtw_security.c b/core/rtw_security.c index 9c1eb59..eb08ef5 100644 --- a/core/rtw_security.c +++ b/core/rtw_security.c @@ -2130,178 +2130,6 @@ BIP_exit: #ifndef PLATFORM_FREEBSD #if defined(CONFIG_TDLS) -/* compress 512-bits */ -static int sha256_compress(struct rtw_sha256_state *md, unsigned char *buf) -{ - u32 S[8], W[64], t0, t1; - u32 t; - int i; - - /* copy state into S */ - for (i = 0; i < 8; i++) - S[i] = md->state[i]; - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) - W[i] = WPA_GET_BE32(buf + (4 * i)); - - /* fill W[16..63] */ - for (i = 16; i < 64; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + - W[i - 16]; - } - - /* Compress */ -#define RND(a, b, c, d, e, f, g, h, i) do {\ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; \ - } while (0) - - for (i = 0; i < 64; ++i) { - RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); - t = S[7]; - S[7] = S[6]; - S[6] = S[5]; - S[5] = S[4]; - S[4] = S[3]; - S[3] = S[2]; - S[2] = S[1]; - S[1] = S[0]; - S[0] = t; - } - - /* feedback */ - for (i = 0; i < 8; i++) - md->state[i] = md->state[i] + S[i]; - return 0; -} - -/* Initialize the hash state */ -static void sha256_init(struct rtw_sha256_state *md) -{ - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return CRYPT_OK if successful -*/ -static int sha256_process(struct rtw_sha256_state *md, unsigned char *in, - unsigned long inlen) -{ - unsigned long n; -#define block_size 64 - - if (md->curlen >= sizeof(md->buf)) - return -1; - - while (inlen > 0) { - if (md->curlen == 0 && inlen >= block_size) { - if (sha256_compress(md, (unsigned char *) in) < 0) - return -1; - md->length += block_size * 8; - in += block_size; - inlen -= block_size; - } else { - n = MIN(inlen, (block_size - md->curlen)); - _rtw_memcpy(md->buf + md->curlen, in, n); - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == block_size) { - if (sha256_compress(md, md->buf) < 0) - return -1; - md->length += 8 * block_size; - md->curlen = 0; - } - } - } - - return 0; -} - - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (32 bytes) - @return CRYPT_OK if successful -*/ -static int sha256_done(struct rtw_sha256_state *md, unsigned char *out) -{ - int i; - - if (md->curlen >= sizeof(md->buf)) - return -1; - - /* increase the length of the message */ - md->length += md->curlen * 8; - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char) 0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 56) { - while (md->curlen < 64) - md->buf[md->curlen++] = (unsigned char) 0; - sha256_compress(md, md->buf); - md->curlen = 0; - } - - /* pad upto 56 bytes of zeroes */ - while (md->curlen < 56) - md->buf[md->curlen++] = (unsigned char) 0; - - /* store length */ - WPA_PUT_BE64(md->buf + 56, md->length); - sha256_compress(md, md->buf); - - /* copy output */ - for (i = 0; i < 8; i++) - WPA_PUT_BE32(out + (4 * i), md->state[i]); - - return 0; -} - -/** - * sha256_vector - SHA256 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 of failure - */ -static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, - u8 *mac) -{ - struct rtw_sha256_state ctx; - size_t i; - - sha256_init(&ctx); - for (i = 0; i < num_elem; i++) - if (sha256_process(&ctx, addr[i], len[i])) - return -1; - if (sha256_done(&ctx, mac)) - return -1; - return 0; -} static u8 os_strlen(const char *s) { @@ -2332,78 +2160,6 @@ static int os_memcmp(const void *s1, const void *s2, u8 n) } #endif -/** - * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash (32 bytes) - */ -#if defined(CONFIG_TDLS) -static void hmac_sha256_vector(u8 *key, size_t key_len, size_t num_elem, - u8 *addr[], size_t *len, u8 *mac) -{ - unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ - unsigned char tk[32]; - u8 *_addr[6]; - size_t _len[6], i; - - if (num_elem > 5) { - /* - * Fixed limit on the number of fragments to avoid having to - * allocate memory (which could fail). - */ - return; - } - - /* if key is longer than 64 bytes reset it to key = SHA256(key) */ - if (key_len > 64) { - sha256_vector(1, &key, &key_len, tk); - key = tk; - key_len = 32; - } - - /* the HMAC_SHA256 transform looks like: - * - * SHA256(K XOR opad, SHA256(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected */ - - /* start out by storing key in ipad */ - _rtw_memset(k_pad, 0, sizeof(k_pad)); - _rtw_memcpy(k_pad, key, key_len); - /* XOR key with ipad values */ - for (i = 0; i < 64; i++) - k_pad[i] ^= 0x36; - - /* perform inner SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - for (i = 0; i < num_elem; i++) { - _addr[i + 1] = addr[i]; - _len[i + 1] = len[i]; - } - sha256_vector(1 + num_elem, _addr, _len, mac); - - _rtw_memset(k_pad, 0, sizeof(k_pad)); - _rtw_memcpy(k_pad, key, key_len); - /* XOR key with opad values */ - for (i = 0; i < 64; i++) - k_pad[i] ^= 0x5c; - - /* perform outer SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - _addr[1] = mac; - _len[1] = 32; - sha256_vector(2, _addr, _len, mac); -} -#endif /* CONFIG_TDLS */ #endif /* PLATFORM_FREEBSD */ /** * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) @@ -2418,46 +2174,6 @@ static void hmac_sha256_vector(u8 *key, size_t key_len, size_t num_elem, * This function is used to derive new, cryptographically separate keys from a * given key. */ -#ifndef PLATFORM_FREEBSD /* Baron */ -#if defined(CONFIG_TDLS) -static void sha256_prf(u8 *key, size_t key_len, char *label, - u8 *data, size_t data_len, u8 *buf, size_t buf_len) -{ - u16 counter = 1; - size_t pos, plen; - u8 hash[SHA256_MAC_LEN]; - u8 *addr[4]; - size_t len[4]; - u8 counter_le[2], length_le[2]; - - addr[0] = counter_le; - len[0] = 2; - addr[1] = (u8 *) label; - len[1] = os_strlen(label); - addr[2] = data; - len[2] = data_len; - addr[3] = length_le; - len[3] = sizeof(length_le); - - WPA_PUT_LE16(length_le, buf_len * 8); - pos = 0; - while (pos < buf_len) { - plen = buf_len - pos; - WPA_PUT_LE16(counter_le, counter); - if (plen >= SHA256_MAC_LEN) { - hmac_sha256_vector(key, key_len, 4, addr, len, - &buf[pos]); - pos += SHA256_MAC_LEN; - } else { - hmac_sha256_vector(key, key_len, 4, addr, len, hash); - _rtw_memcpy(&buf[pos], hash, plen); - break; - } - counter++; - } -} -#endif -#endif /* PLATFORM_FREEBSD Baron */ /* AES tables*/ const u32 Te0[256] = { diff --git a/include/rtw_security.h b/include/rtw_security.h index f4fc8fb..f09f8a3 100644 --- a/include/rtw_security.h +++ b/include/rtw_security.h @@ -254,12 +254,6 @@ struct security_priv { #define SEC_IS_BIP_KEY_INSTALLED(sec) _FALSE #endif -struct rtw_sha256_state { - u64 length; - u32 state[8], curlen; - u8 buf[64]; -}; - #define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)\ do {\ switch (psecuritypriv->dot11AuthAlgrthm) {\ diff --git a/os_dep/linux/ioctl_cfg80211.c b/os_dep/linux/ioctl_cfg80211.c index feb651e..f5c6db5 100644 --- a/os_dep/linux/ioctl_cfg80211.c +++ b/os_dep/linux/ioctl_cfg80211.c @@ -7598,15 +7598,17 @@ exit: return ret; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) +static void cfg80211_rtw_update_mgmt_frame_register(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct mgmt_frame_regs *upd) +#else static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) struct wireless_dev *wdev, #else struct net_device *ndev, #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) - struct mgmt_frame_regs *upd) -#else u16 frame_type, bool reg) #endif { @@ -7614,11 +7616,6 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, struct net_device *ndev = wdev_to_ndev(wdev); #endif _adapter *adapter; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) - u16 frame_type = BIT(upd->global_stypes << 4); - bool reg = false; -#endif - struct rtw_wdev_priv *pwdev_priv; if (ndev == NULL) @@ -7632,31 +7629,6 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, frame_type, reg); #endif - switch (frame_type) { - case IEEE80211_STYPE_AUTH: /* 0x00B0 */ - if (reg > 0) - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH, reg); - else - CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH, reg); - break; -#ifdef not_yet - case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */ - if (reg > 0) - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); - else - CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); - break; - case IEEE80211_STYPE_ACTION: /* 0x00D0 */ - if (reg > 0) - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); - else - CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); - break; -#endif - default: - break; - } - exit: return; } @@ -10078,16 +10050,15 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) .mgmt_tx = cfg80211_rtw_mgmt_tx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) + .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_register, +#else + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, +#endif #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) .action = cfg80211_rtw_mgmt_tx, #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) - .update_mgmt_frame_registrations = cfg80211_rtw_mgmt_frame_register, -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) - .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, -#endif - #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) .tdls_mgmt = cfg80211_rtw_tdls_mgmt, .tdls_oper = cfg80211_rtw_tdls_oper,