summaryrefslogtreecommitdiffstats
path: root/drivers/staging/wfx/bh.c
diff options
context:
space:
mode:
authorJérôme Pouiller <jerome.pouiller@silabs.com>2019-09-19 14:25:43 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-10-04 10:47:35 +0200
commit846239f641db5af8dd952575a65808281f2d849e (patch)
tree2a26524b1b29e85026ffe5f20b742c91848fdf89 /drivers/staging/wfx/bh.c
parentf95a29d40782f4f0052a692a822de3ba044b19ff (diff)
staging: wfx: introduce "secure link"
Chip support encryption of the link between host and chip. This feature is called "secure link". Driver code on github[1] support it. However, it relies on mbedtls for cryptographic functions. So, I decided to not import this feature in current patch. However, in order to keep code synchronized between github and kernel, I imported all code related to this feature, even if most of it is just no-op. [1]: https://github.com/SiliconLabs/wfx-linux-driver/ Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com> Link: https://lore.kernel.org/r/20190919142527.31797-14-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/wfx/bh.c')
-rw-r--r--drivers/staging/wfx/bh.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c
index c94c9c401a69..d321fd312d55 100644
--- a/drivers/staging/wfx/bh.c
+++ b/drivers/staging/wfx/bh.c
@@ -12,6 +12,7 @@
#include "wfx.h"
#include "hwio.h"
#include "traces.h"
+#include "secure_link.h"
#include "hif_rx.h"
#include "hif_api_cmd.h"
@@ -74,7 +75,18 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf)
hif = (struct hif_msg *) skb->data;
WARN(hif->encrypted & 0x1, "unsupported encryption type");
if (hif->encrypted == 0x2) {
- BUG(); // Not yet implemented
+ if (wfx_sl_decode(wdev, (void *) 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;
+ }
+ le16_to_cpus(hif->len);
+ computed_len = round_up(hif->len - sizeof(hif->len), 16)
+ + sizeof(struct hif_sl_msg)
+ + sizeof(struct hif_sl_tag);
} else {
le16_to_cpus(hif->len);
computed_len = round_up(hif->len, 2);
@@ -166,7 +178,22 @@ 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);
- data = hif;
+ 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);