diff options
author | Jérôme Pouiller <jerome.pouiller@silabs.com> | 2019-09-19 14:25:43 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-04 10:47:35 +0200 |
commit | 846239f641db5af8dd952575a65808281f2d849e (patch) | |
tree | 2a26524b1b29e85026ffe5f20b742c91848fdf89 /drivers/staging/wfx/bh.c | |
parent | f95a29d40782f4f0052a692a822de3ba044b19ff (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.c | 31 |
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); |