Commit e8d607ce authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman
Browse files

staging: wfx: drop 'secure link' feature



The Secure Link (slk) feature allows to encrypt (and authenticate) the
traffic between the host and the device. The official implementation of
this feature relies on mbedTLS. For that reason, this implementation is
not included in the current driver. To be included, the implementation
has to rely on kernel crypto API instead of mbedTLS.

So, for now, the driver contained stub functions waiting for the new
implementation based on kernel crypto API.

This new implementation represent a bunch of work and it is unlikely to
be done in near future.  Moreover, we strongly dislike to maintain
useless code. So, drop all the code related to secure link.

Whoever wants to implement secure link should revert this patch before
starting to work on it.

Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200907101521.66082-6-Jerome.Pouiller@silabs.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3e2311fa
Loading
Loading
Loading
Loading
+6 −42
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@
#include "wfx.h"
#include "hwio.h"
#include "traces.h"
#include "secure_link.h"
#include "hif_rx.h"
#include "hif_api_cmd.h"

@@ -88,20 +87,11 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf)
	_trace_piggyback(piggyback, false);

	hif = (struct hif_msg *)skb->data;
	WARN(hif->encrypted & 0x1, "unsupported encryption type");
	if (hif->encrypted == 0x2) {
		if (WARN(read_len < sizeof(struct hif_sl_msg), "corrupted read"))
			goto err;
		computed_len = le16_to_cpu(((struct hif_sl_msg *)hif)->len);
		computed_len = round_up(computed_len - sizeof(u16), 16);
		computed_len += sizeof(struct hif_sl_msg);
		computed_len += sizeof(struct hif_sl_tag);
	} else {
	WARN(hif->encrypted & 0x3, "encryption is unsupported");
	if (WARN(read_len < sizeof(struct hif_msg), "corrupted read"))
		goto err;
	computed_len = le16_to_cpu(hif->len);
	computed_len = round_up(computed_len, 2);
	}
	if (computed_len != read_len) {
		dev_err(wdev->dev, "inconsistent message length: %zu != %zu\n",
			computed_len, read_len);
@@ -109,16 +99,6 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf)
			       hif, read_len, true);
		goto err;
	}
	if (hif->encrypted == 0x2) {
		if (wfx_sl_decode(wdev, (struct hif_sl_msg *)hif)) {
			dev_kfree_skb(skb);
			// If frame was a confirmation, expect trouble in next
			// exchange. However, it is harmless to fail to decode
			// an indication frame, so try to continue. Anyway,
			// piggyback is probably correct.
			return piggyback;
		}
	}

	if (!(hif->id & HIF_ID_IS_INDICATION)) {
		(*is_cnf)++;
@@ -199,23 +179,7 @@ static void tx_helper(struct wfx_dev *wdev, struct hif_msg *hif)
	hif->seqnum = wdev->hif.tx_seqnum;
	wdev->hif.tx_seqnum = (wdev->hif.tx_seqnum + 1) % (HIF_COUNTER_MAX + 1);

	if (wfx_is_secure_command(wdev, hif->id)) {
		len = round_up(len - sizeof(hif->len), 16) + sizeof(hif->len) +
			sizeof(struct hif_sl_msg_hdr) +
			sizeof(struct hif_sl_tag);
		// AES support encryption in-place. However, mac80211 access to
		// 802.11 header after frame was sent (to get MAC addresses).
		// So, keep origin buffer clear.
		data = kmalloc(len, GFP_KERNEL);
		if (!data)
			goto end;
		is_encrypted = true;
		ret = wfx_sl_encode(wdev, hif, data);
		if (ret)
			goto end;
	} else {
	data = hif;
	}
	WARN(len > wdev->hw_caps.size_inp_ch_buf,
	     "%s: request exceed WFx capability: %zu > %d\n", __func__,
	     len, wdev->hw_caps.size_inp_ch_buf);
+0 −80
Original line number Diff line number Diff line
@@ -282,84 +282,4 @@ enum hif_secure_link_state {
	SEC_LINK_ENFORCED    = 0x3
};

enum hif_sl_encryption_type {
	NO_ENCRYPTION = 0,
	TX_ENCRYPTION = 1,
	RX_ENCRYPTION = 2,
	HP_ENCRYPTION = 3
};

struct hif_sl_msg_hdr {
	u32    seqnum:30;
	u32    encrypted:2;
} __packed;

struct hif_sl_msg {
	struct hif_sl_msg_hdr hdr;
	__le16 len;
	u8     payload[];
} __packed;

#define AES_CCM_TAG_SIZE          16

struct hif_sl_tag {
	u8     tag[16];
} __packed;

enum hif_sl_mac_key_dest {
	SL_MAC_KEY_DEST_OTP = 0x78,
	SL_MAC_KEY_DEST_RAM = 0x87
};

#define API_KEY_VALUE_SIZE        32

struct hif_req_set_sl_mac_key {
	u8     otp_or_ram;
	u8     key_value[API_KEY_VALUE_SIZE];
} __packed;

struct hif_cnf_set_sl_mac_key {
	__le32 status;
} __packed;

enum hif_sl_session_key_alg {
	HIF_SL_CURVE25519 = 0x01,
	HIF_SL_KDF        = 0x02
};

#define API_HOST_PUB_KEY_SIZE     32
#define API_HOST_PUB_KEY_MAC_SIZE 64

struct hif_req_sl_exchange_pub_keys {
	u8     algorithm:2;
	u8     reserved1:6;
	u8     reserved2[3];
	u8     host_pub_key[API_HOST_PUB_KEY_SIZE];
	u8     host_pub_key_mac[API_HOST_PUB_KEY_MAC_SIZE];
} __packed;

struct hif_cnf_sl_exchange_pub_keys {
	__le32 status;
} __packed;

#define API_NCP_PUB_KEY_SIZE      32
#define API_NCP_PUB_KEY_MAC_SIZE  64

struct hif_ind_sl_exchange_pub_keys {
	__le32 status;
	u8     ncp_pub_key[API_NCP_PUB_KEY_SIZE];
	u8     ncp_pub_key_mac[API_NCP_PUB_KEY_MAC_SIZE];
} __packed;

struct hif_req_sl_configure {
	u8     encr_bmp[32];
	u8     disable_session_key_protection:1;
	u8     reserved1:7;
	u8     reserved2[3];
} __packed;

struct hif_cnf_sl_configure {
	__le32 status;
} __packed;

#endif
+0 −19
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#include "bh.h"
#include "sta.h"
#include "data_rx.h"
#include "secure_link.h"
#include "hif_api_cmd.h"

static int hif_generic_confirm(struct wfx_dev *wdev,
@@ -53,8 +52,6 @@ static int hif_generic_confirm(struct wfx_dev *wdev,
	} else {
		wdev->hif_cmd.buf_send = NULL;
		mutex_unlock(&wdev->hif_cmd.lock);
		if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS)
			mutex_unlock(&wdev->hif_cmd.key_renew_lock);
	}
	return status;
}
@@ -110,21 +107,6 @@ static int hif_wakeup_indication(struct wfx_dev *wdev,
	return 0;
}

static int hif_keys_indication(struct wfx_dev *wdev,
			       const struct hif_msg *hif, const void *buf)
{
	const struct hif_ind_sl_exchange_pub_keys *body = buf;
	u8 pubkey[API_NCP_PUB_KEY_SIZE];

	// SL_PUB_KEY_EXCHANGE_STATUS_SUCCESS is used by legacy secure link
	if (body->status && body->status != HIF_STATUS_SLK_NEGO_SUCCESS)
		dev_warn(wdev->dev, "secure link negotiation error\n");
	memcpy(pubkey, body->ncp_pub_key, sizeof(pubkey));
	memreverse(pubkey, sizeof(pubkey));
	wfx_sl_check_pubkey(wdev, pubkey, body->ncp_pub_key_mac);
	return 0;
}

static int hif_receive_indication(struct wfx_dev *wdev,
				  const struct hif_msg *hif,
				  const void *buf, struct sk_buff *skb)
@@ -380,7 +362,6 @@ static const struct {
	{ HIF_IND_ID_SET_PM_MODE_CMPL,     hif_pm_mode_complete_indication },
	{ HIF_IND_ID_SCAN_CMPL,            hif_scan_complete_indication },
	{ HIF_IND_ID_SUSPEND_RESUME_TX,    hif_suspend_resume_indication },
	{ HIF_IND_ID_SL_EXCHANGE_PUB_KEYS, hif_keys_indication },
	{ HIF_IND_ID_EVENT,                hif_event_indication },
	{ HIF_IND_ID_GENERIC,              hif_generic_indication },
	{ HIF_IND_ID_ERROR,                hif_error_indication },
+0 −66
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ void wfx_init_hif_cmd(struct wfx_hif_cmd *hif_cmd)
	init_completion(&hif_cmd->ready);
	init_completion(&hif_cmd->done);
	mutex_init(&hif_cmd->lock);
	mutex_init(&hif_cmd->key_renew_lock);
}

static void wfx_fill_header(struct hif_msg *hif, int if_id,
@@ -62,9 +61,6 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
	if (wdev->chip_frozen)
		return -ETIMEDOUT;

	if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS)
		mutex_lock(&wdev->hif_cmd.key_renew_lock);

	mutex_lock(&wdev->hif_cmd.lock);
	WARN(wdev->hif_cmd.buf_send, "data locking error");

@@ -118,8 +114,6 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
			 "WSM request %s%s%s (%#.2x) on vif %d returned status %d\n",
			 get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret);

	if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS)
		mutex_unlock(&wdev->hif_cmd.key_renew_lock);
	return ret;
}

@@ -147,7 +141,6 @@ int hif_shutdown(struct wfx_dev *wdev)
	else
		control_reg_write(wdev, 0);
	mutex_unlock(&wdev->hif_cmd.lock);
	mutex_unlock(&wdev->hif_cmd.key_renew_lock);
	kfree(hif);
	return ret;
}
@@ -535,62 +528,3 @@ int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len)
	kfree(hif);
	return ret;
}

int hif_sl_send_pub_keys(struct wfx_dev *wdev,
			 const u8 *pubkey, const u8 *pubkey_hmac)
{
	int ret;
	struct hif_msg *hif;
	struct hif_req_sl_exchange_pub_keys *body = wfx_alloc_hif(sizeof(*body),
								  &hif);

	if (!hif)
		return -ENOMEM;
	body->algorithm = HIF_SL_CURVE25519;
	memcpy(body->host_pub_key, pubkey, sizeof(body->host_pub_key));
	memcpy(body->host_pub_key_mac, pubkey_hmac,
	       sizeof(body->host_pub_key_mac));
	wfx_fill_header(hif, -1, HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS,
			sizeof(*body));
	ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
	kfree(hif);
	// Compatibility with legacy secure link
	if (ret == le32_to_cpu(HIF_STATUS_SLK_NEGO_SUCCESS))
		ret = 0;
	return ret;
}

int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap)
{
	int ret;
	struct hif_msg *hif;
	struct hif_req_sl_configure *body = wfx_alloc_hif(sizeof(*body), &hif);

	if (!hif)
		return -ENOMEM;
	memcpy(body->encr_bmp, bitmap, sizeof(body->encr_bmp));
	wfx_fill_header(hif, -1, HIF_REQ_ID_SL_CONFIGURE, sizeof(*body));
	ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
	kfree(hif);
	return ret;
}

int hif_sl_set_mac_key(struct wfx_dev *wdev, const u8 *slk_key, int destination)
{
	int ret;
	struct hif_msg *hif;
	struct hif_req_set_sl_mac_key *body = wfx_alloc_hif(sizeof(*body),
							    &hif);

	if (!hif)
		return -ENOMEM;
	memcpy(body->key_value, slk_key, sizeof(body->key_value));
	body->otp_or_ram = destination;
	wfx_fill_header(hif, -1, HIF_REQ_ID_SET_SL_MAC_KEY, sizeof(*body));
	ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
	kfree(hif);
	// Compatibility with legacy secure link
	if (ret == le32_to_cpu(HIF_STATUS_SLK_SET_KEY_SUCCESS))
		ret = 0;
	return ret;
}
+0 −6
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ struct wfx_vif;

struct wfx_hif_cmd {
	struct mutex      lock;
	struct mutex      key_renew_lock;
	struct completion ready;
	struct completion done;
	bool              async;
@@ -58,10 +57,5 @@ int hif_beacon_transmit(struct wfx_vif *wvif, bool enable);
int hif_map_link(struct wfx_vif *wvif,
		 bool unmap, u8 *mac_addr, int sta_id, bool mfp);
int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len);
int hif_sl_set_mac_key(struct wfx_dev *wdev,
		       const u8 *slk_key, int destination);
int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap);
int hif_sl_send_pub_keys(struct wfx_dev *wdev,
			 const u8 *pubkey, const u8 *pubkey_hmac);

#endif
Loading