summaryrefslogtreecommitdiffstats
path: root/net/mac802154
diff options
context:
space:
mode:
authorDiogenes Pereira <dvnp@cesar.org.br>2017-09-05 09:18:04 -0300
committerStefan Schmidt <stefan@osg.samsung.com>2017-09-20 13:37:16 +0200
commit3e4962667efb0f6c09fa3111e6ee53838118b227 (patch)
treeedff991e3f4004d4965afed65bd6cc74fd195885 /net/mac802154
parent91f4aa977947f046dc144fa9e3b06f0ffb53be79 (diff)
downloadlinux-3e4962667efb0f6c09fa3111e6ee53838118b227.tar.bz2
mac802154: Fix MAC header and payload encrypted
According to 802.15.4-2003/2006/2015 specifications the MAC frame is composed of MHR, MAC payload and MFR and just the outgoing MAC payload must be encrypted. If communication is secure,sender build Auxiliary Security Header(ASH), insert it next to the standard MHR header with security enabled bit ON, and secure frames before transmitting them. According to the information carried within the ASH, recipient retrieves the right cryptographic key and correctly un-secure MAC frames. The error scenario occurs on Linux using IEEE802154_SCF_SECLEVEL_ENC(4) security level when llsec_do_encrypt_unauth() function builds theses MAC frames incorrectly. On recipients these MAC frames are discarded,logging "got invalid frame" messages. Signed-off-by: Diogenes Pereira <dvnp@cesar.org.br> Signed-off-by: Stefan Schmidt <stefan@osg.samsung.com>
Diffstat (limited to 'net/mac802154')
-rw-r--r--net/mac802154/llsec.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index edec2f9919d0..2fb703d70803 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -623,13 +623,18 @@ llsec_do_encrypt_unauth(struct sk_buff *skb, const struct mac802154_llsec *sec,
u8 iv[16];
struct scatterlist src;
SKCIPHER_REQUEST_ON_STACK(req, key->tfm0);
- int err;
+ int err, datalen;
+ unsigned char *data;
llsec_geniv(iv, sec->params.hwaddr, &hdr->sec);
- sg_init_one(&src, skb->data, skb->len);
+ /* Compute data payload offset and data length */
+ data = skb_mac_header(skb) + skb->mac_len;
+ datalen = skb_tail_pointer(skb) - data;
+ sg_init_one(&src, data, datalen);
+
skcipher_request_set_tfm(req, key->tfm0);
skcipher_request_set_callback(req, 0, NULL, NULL);
- skcipher_request_set_crypt(req, &src, &src, skb->len, iv);
+ skcipher_request_set_crypt(req, &src, &src, datalen, iv);
err = crypto_skcipher_encrypt(req);
skcipher_request_zero(req);
return err;