// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2002-2004, Instant802 Networks, Inc.
 * Copyright 2005, Devicescape Software, Inc.
 * Copyright (C) 2016 Intel Deutschland GmbH
 */
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/export.h>
#include <linux/unaligned.h>

#include <net/mac80211.h>
#include "driver-ops.h"
#include "key.h"
#include "tkip.h"
#include "wep.h"

#define PHASE1_LOOP_COUNT 8

/*
 * 2-byte by 2-byte subset of the full AES S-box table; second part of this
 * table is identical to first part but byte-swapped
 */
static const u16 tkip_sbox[256] =
{
	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
};

static u16 tkipS(u16 val)
{
	return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]);
}

static u8 *write_tkip_iv(u8 *pos, u16 iv16)
{
	*pos++ = iv16 >> 8;
	*pos++ = ((iv16 >> 8) | 0x20) & 0x7f;
	*pos++ = iv16 & 0xFF;
	return pos;
}

/*
 * P1K := Phase1(TA, TK, TSC)
 * TA = transmitter address (48 bits)
 * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits)
 * TSC = TKIP sequence counter (48 bits, only 32 msb bits used)
 * P1K: 80 bits
 */
static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx,
			       const u8 *ta, u32 tsc_IV32)
{
	int i, j;
	u16 *p1k = ctx->p1k;

	p1k[0] = tsc_IV32 & 0xFFFF;
	p1k[1] = tsc_IV32 >> 16;
	p1k[2] = get_unaligned_le16(ta + 0);
	p1k[3] = get_unaligned_le16(ta + 2);
	p1k[4] = get_unaligned_le16(ta + 4);

	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
		j = 2 * (i & 1);
		p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j));
		p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j));
		p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j));
		p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j));
		p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
	}
	ctx->state = TKIP_STATE_PHASE1_DONE;
	ctx->p1k_iv32 = tsc_IV32;
}

static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
			       u16 tsc_IV16, u8 *rc4key)
{
	u16 ppk[6];
	const u16 *p1k = ctx->p1k;
	int i;

	ppk[0] = p1k[0];
	ppk[1] = p1k[1];
	ppk[2] = p1k[2];
	ppk[3] = p1k[3];
	ppk[4] = p1k[4];
	ppk[5] = p1k[4] + tsc_IV16;

	ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0));
	ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2));
	ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4));
	ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6));
	ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8));
	ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10));
	ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1);
	ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1);
	ppk[2] += ror16(ppk[1], 1);
	ppk[3] += ror16(ppk[2], 1);
	ppk[4] += ror16(ppk[3], 1);
	ppk[5] += ror16(ppk[4], 1);

	rc4key = write_tkip_iv(rc4key, tsc_IV16);
	*rc4key++ = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF;

	for (i = 0; i < 6; i++)
		put_unaligned_le16(ppk[i], rc4key + 2 * i);
}

/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets
 * of the IV. Returns pointer to the octet following IVs (i.e., beginning of
 * the packet payload). */
u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key_conf *keyconf, u64 pn)
{
	pos = write_tkip_iv(pos, TKIP_PN_TO_IV16(pn));
	*pos++ = (keyconf->keyidx << 6) | (1 << 5) /* Ext IV */;
	put_unaligned_le32(TKIP_PN_TO_IV32(pn), pos);
	return pos + 4;
}
EXPORT_SYMBOL_GPL(ieee80211_tkip_add_iv);

static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32)
{
	struct ieee80211_sub_if_data *sdata = key->sdata;
	struct tkip_ctx *ctx = &key->u.tkip.tx;
	const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];

	lockdep_assert_held(&key->u.tkip.txlock);

	/*
	 * Update the P1K when the IV32 is different from the value it
	 * had when we last computed it (or when not initialised yet).
	 * This might flip-flop back and forth if packets are processed
	 * out-of-order due to the different ACs, but then we have to
	 * just compute the P1K more often.
	 */
	if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT)
		tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32);
}

void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf,
			       u32 iv32, u16 *p1k)
{
	struct ieee80211_key *key = (struct ieee80211_key *)
			container_of(keyconf, struct ieee80211_key, conf);
	struct tkip_ctx *ctx = &key->u.tkip.tx;

	spin_lock_bh(&key->u.tkip.txlock);
	ieee80211_compute_tkip_p1k(key, iv32);
	memcpy(p1k, ctx->p1k, sizeof(ctx->p1k));
	spin_unlock_bh(&key->u.tkip.txlock);
}
EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv);

void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
			       const u8 *ta, u32 iv32, u16 *p1k)
{
	const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
	struct tkip_ctx ctx;

	tkip_mixing_phase1(tk, &ctx, ta, iv32);
	memcpy(p1k, ctx.p1k, sizeof(ctx.p1k));
}
EXPORT_SYMBOL(ieee80211_get_tkip_rx_p1k);

void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
			    struct sk_buff *skb, u8 *p2k)
{
	struct ieee80211_key *key = (struct ieee80211_key *)
			container_of(keyconf, struct ieee80211_key, conf);
	const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
	struct tkip_ctx *ctx = &key->u.tkip.tx;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
	u32 iv32 = get_unaligned_le32(&data[4]);
	u16 iv16 = data[2] | (data[0] << 8);

	spin_lock(&key->u.tkip.txlock);
	ieee80211_compute_tkip_p1k(key, iv32);
	tkip_mixing_phase2(tk, ctx, iv16, p2k);
	spin_unlock(&key->u.tkip.txlock);
}
EXPORT_SYMBOL(ieee80211_get_tkip_p2k);

/*
 * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
 * beginning of the buffer containing payload. This payload must include
 * the IV/Ext.IV and space for (taildroom) four octets for ICV.
 * @payload_len is the length of payload (_not_ including IV/ICV length).
 * @ta is the transmitter addresses.
 */
int ieee80211_tkip_encrypt_data(struct arc4_ctx *ctx,
				struct ieee80211_key *key,
				struct sk_buff *skb,
				u8 *payload, size_t payload_len)
{
	u8 rc4key[16];

	ieee80211_get_tkip_p2k(&key->conf, skb, rc4key);

	return ieee80211_wep_encrypt_data(ctx, rc4key, 16,
					  payload, payload_len);
}

/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
 * beginning of the buffer containing IEEE 802.11 header payload, i.e.,
 * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the
 * length of payload, including IV, Ext. IV, MIC, ICV.  */
int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx,
				struct ieee80211_key *key,
				u8 *payload, size_t payload_len, u8 *ta,
				u8 *ra, int only_iv, int queue,
				u32 *out_iv32, u16 *out_iv16)
{
	u32 iv32;
	u32 iv16;
	u8 rc4key[16], keyid, *pos = payload;
	int res;
	const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
	struct tkip_ctx_rx *rx_ctx = &key->u.tkip.rx[queue];

	if (payload_len < 12)
		return -1;

	iv16 = (pos[0] << 8) | pos[2];
	keyid = pos[3];
	iv32 = get_unaligned_le32(pos + 4);
	pos += 8;

	if (!(keyid & (1 << 5)))
		return TKIP_DECRYPT_NO_EXT_IV;

	if ((keyid >> 6) != key->conf.keyidx)
		return TKIP_DECRYPT_INVALID_KEYIDX;

	/* Reject replays if the received TSC is smaller than or equal to the
	 * last received value in a valid message, but with an exception for
	 * the case where a new key has been set and no valid frame using that
	 * key has yet received and the local RSC was initialized to 0. This
	 * exception allows the very first frame sent by the transmitter to be
	 * accepted even if that transmitter were to use TSC 0 (IEEE 802.11
	 * described TSC to be initialized to 1 whenever a new key is taken into
	 * use).
	 */
	if (iv32 < rx_ctx->iv32 ||
	    (iv32 == rx_ctx->iv32 &&
	     (iv16 < rx_ctx->iv16 ||
	      (iv16 == rx_ctx->iv16 &&
	       (rx_ctx->iv32 || rx_ctx->iv16 ||
		rx_ctx->ctx.state != TKIP_STATE_NOT_INIT)))))
		return TKIP_DECRYPT_REPLAY;

	if (only_iv) {
		res = TKIP_DECRYPT_OK;
		rx_ctx->ctx.state = TKIP_STATE_PHASE1_HW_UPLOADED;
		goto done;
	}

	if (rx_ctx->ctx.state == TKIP_STATE_NOT_INIT ||
	    rx_ctx->iv32 != iv32) {
		/* IV16 wrapped around - perform TKIP phase 1 */
		tkip_mixing_phase1(tk, &rx_ctx->ctx, ta, iv32);
	}
	if (key->local->ops->update_tkip_key &&
	    key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
	    rx_ctx->ctx.state != TKIP_STATE_PHASE1_HW_UPLOADED) {
		struct ieee80211_sub_if_data *sdata = key->sdata;

		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
			sdata = container_of(key->sdata->bss,
					struct ieee80211_sub_if_data, u.ap);
		drv_update_tkip_key(key->local, sdata, &key->conf, key->sta,
				iv32, rx_ctx->ctx.p1k);
		rx_ctx->ctx.state = TKIP_STATE_PHASE1_HW_UPLOADED;
	}

	tkip_mixing_phase2(tk, &rx_ctx->ctx, iv16, rc4key);

	res = ieee80211_wep_decrypt_data(ctx, rc4key, 16, pos, payload_len - 12);
 done:
	if (res == TKIP_DECRYPT_OK) {
		/*
		 * Record previously received IV, will be copied into the
		 * key information after MIC verification. It is possible
		 * that we don't catch replays of fragments but that's ok
		 * because the Michael MIC verication will then fail.
		 */
		*out_iv32 = iv32;
		*out_iv16 = iv16;
	}

	return res;
}
