Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014 Fraunhofer ITWM
0004  *
0005  * Written by:
0006  * Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
0007  */
0008 
0009 #include <linux/err.h>
0010 #include <linux/bug.h>
0011 #include <linux/completion.h>
0012 #include <linux/ieee802154.h>
0013 #include <linux/rculist.h>
0014 
0015 #include <crypto/aead.h>
0016 #include <crypto/skcipher.h>
0017 
0018 #include "ieee802154_i.h"
0019 #include "llsec.h"
0020 
0021 static void llsec_key_put(struct mac802154_llsec_key *key);
0022 static bool llsec_key_id_equal(const struct ieee802154_llsec_key_id *a,
0023                    const struct ieee802154_llsec_key_id *b);
0024 
0025 static void llsec_dev_free(struct mac802154_llsec_device *dev);
0026 
0027 void mac802154_llsec_init(struct mac802154_llsec *sec)
0028 {
0029     memset(sec, 0, sizeof(*sec));
0030 
0031     memset(&sec->params.default_key_source, 0xFF, IEEE802154_ADDR_LEN);
0032 
0033     INIT_LIST_HEAD(&sec->table.security_levels);
0034     INIT_LIST_HEAD(&sec->table.devices);
0035     INIT_LIST_HEAD(&sec->table.keys);
0036     hash_init(sec->devices_short);
0037     hash_init(sec->devices_hw);
0038     rwlock_init(&sec->lock);
0039 }
0040 
0041 void mac802154_llsec_destroy(struct mac802154_llsec *sec)
0042 {
0043     struct ieee802154_llsec_seclevel *sl, *sn;
0044     struct ieee802154_llsec_device *dev, *dn;
0045     struct ieee802154_llsec_key_entry *key, *kn;
0046 
0047     list_for_each_entry_safe(sl, sn, &sec->table.security_levels, list) {
0048         struct mac802154_llsec_seclevel *msl;
0049 
0050         msl = container_of(sl, struct mac802154_llsec_seclevel, level);
0051         list_del(&sl->list);
0052         kfree_sensitive(msl);
0053     }
0054 
0055     list_for_each_entry_safe(dev, dn, &sec->table.devices, list) {
0056         struct mac802154_llsec_device *mdev;
0057 
0058         mdev = container_of(dev, struct mac802154_llsec_device, dev);
0059         list_del(&dev->list);
0060         llsec_dev_free(mdev);
0061     }
0062 
0063     list_for_each_entry_safe(key, kn, &sec->table.keys, list) {
0064         struct mac802154_llsec_key *mkey;
0065 
0066         mkey = container_of(key->key, struct mac802154_llsec_key, key);
0067         list_del(&key->list);
0068         llsec_key_put(mkey);
0069         kfree_sensitive(key);
0070     }
0071 }
0072 
0073 int mac802154_llsec_get_params(struct mac802154_llsec *sec,
0074                    struct ieee802154_llsec_params *params)
0075 {
0076     read_lock_bh(&sec->lock);
0077     *params = sec->params;
0078     read_unlock_bh(&sec->lock);
0079 
0080     return 0;
0081 }
0082 
0083 int mac802154_llsec_set_params(struct mac802154_llsec *sec,
0084                    const struct ieee802154_llsec_params *params,
0085                    int changed)
0086 {
0087     write_lock_bh(&sec->lock);
0088 
0089     if (changed & IEEE802154_LLSEC_PARAM_ENABLED)
0090         sec->params.enabled = params->enabled;
0091     if (changed & IEEE802154_LLSEC_PARAM_FRAME_COUNTER)
0092         sec->params.frame_counter = params->frame_counter;
0093     if (changed & IEEE802154_LLSEC_PARAM_OUT_LEVEL)
0094         sec->params.out_level = params->out_level;
0095     if (changed & IEEE802154_LLSEC_PARAM_OUT_KEY)
0096         sec->params.out_key = params->out_key;
0097     if (changed & IEEE802154_LLSEC_PARAM_KEY_SOURCE)
0098         sec->params.default_key_source = params->default_key_source;
0099     if (changed & IEEE802154_LLSEC_PARAM_PAN_ID)
0100         sec->params.pan_id = params->pan_id;
0101     if (changed & IEEE802154_LLSEC_PARAM_HWADDR)
0102         sec->params.hwaddr = params->hwaddr;
0103     if (changed & IEEE802154_LLSEC_PARAM_COORD_HWADDR)
0104         sec->params.coord_hwaddr = params->coord_hwaddr;
0105     if (changed & IEEE802154_LLSEC_PARAM_COORD_SHORTADDR)
0106         sec->params.coord_shortaddr = params->coord_shortaddr;
0107 
0108     write_unlock_bh(&sec->lock);
0109 
0110     return 0;
0111 }
0112 
0113 static struct mac802154_llsec_key*
0114 llsec_key_alloc(const struct ieee802154_llsec_key *template)
0115 {
0116     const int authsizes[3] = { 4, 8, 16 };
0117     struct mac802154_llsec_key *key;
0118     int i;
0119 
0120     key = kzalloc(sizeof(*key), GFP_KERNEL);
0121     if (!key)
0122         return NULL;
0123 
0124     kref_init(&key->ref);
0125     key->key = *template;
0126 
0127     BUILD_BUG_ON(ARRAY_SIZE(authsizes) != ARRAY_SIZE(key->tfm));
0128 
0129     for (i = 0; i < ARRAY_SIZE(key->tfm); i++) {
0130         key->tfm[i] = crypto_alloc_aead("ccm(aes)", 0,
0131                         CRYPTO_ALG_ASYNC);
0132         if (IS_ERR(key->tfm[i]))
0133             goto err_tfm;
0134         if (crypto_aead_setkey(key->tfm[i], template->key,
0135                        IEEE802154_LLSEC_KEY_SIZE))
0136             goto err_tfm;
0137         if (crypto_aead_setauthsize(key->tfm[i], authsizes[i]))
0138             goto err_tfm;
0139     }
0140 
0141     key->tfm0 = crypto_alloc_sync_skcipher("ctr(aes)", 0, 0);
0142     if (IS_ERR(key->tfm0))
0143         goto err_tfm;
0144 
0145     if (crypto_sync_skcipher_setkey(key->tfm0, template->key,
0146                    IEEE802154_LLSEC_KEY_SIZE))
0147         goto err_tfm0;
0148 
0149     return key;
0150 
0151 err_tfm0:
0152     crypto_free_sync_skcipher(key->tfm0);
0153 err_tfm:
0154     for (i = 0; i < ARRAY_SIZE(key->tfm); i++)
0155         if (!IS_ERR_OR_NULL(key->tfm[i]))
0156             crypto_free_aead(key->tfm[i]);
0157 
0158     kfree_sensitive(key);
0159     return NULL;
0160 }
0161 
0162 static void llsec_key_release(struct kref *ref)
0163 {
0164     struct mac802154_llsec_key *key;
0165     int i;
0166 
0167     key = container_of(ref, struct mac802154_llsec_key, ref);
0168 
0169     for (i = 0; i < ARRAY_SIZE(key->tfm); i++)
0170         crypto_free_aead(key->tfm[i]);
0171 
0172     crypto_free_sync_skcipher(key->tfm0);
0173     kfree_sensitive(key);
0174 }
0175 
0176 static struct mac802154_llsec_key*
0177 llsec_key_get(struct mac802154_llsec_key *key)
0178 {
0179     kref_get(&key->ref);
0180     return key;
0181 }
0182 
0183 static void llsec_key_put(struct mac802154_llsec_key *key)
0184 {
0185     kref_put(&key->ref, llsec_key_release);
0186 }
0187 
0188 static bool llsec_key_id_equal(const struct ieee802154_llsec_key_id *a,
0189                    const struct ieee802154_llsec_key_id *b)
0190 {
0191     if (a->mode != b->mode)
0192         return false;
0193 
0194     if (a->mode == IEEE802154_SCF_KEY_IMPLICIT)
0195         return ieee802154_addr_equal(&a->device_addr, &b->device_addr);
0196 
0197     if (a->id != b->id)
0198         return false;
0199 
0200     switch (a->mode) {
0201     case IEEE802154_SCF_KEY_INDEX:
0202         return true;
0203     case IEEE802154_SCF_KEY_SHORT_INDEX:
0204         return a->short_source == b->short_source;
0205     case IEEE802154_SCF_KEY_HW_INDEX:
0206         return a->extended_source == b->extended_source;
0207     }
0208 
0209     return false;
0210 }
0211 
0212 int mac802154_llsec_key_add(struct mac802154_llsec *sec,
0213                 const struct ieee802154_llsec_key_id *id,
0214                 const struct ieee802154_llsec_key *key)
0215 {
0216     struct mac802154_llsec_key *mkey = NULL;
0217     struct ieee802154_llsec_key_entry *pos, *new;
0218 
0219     if (!(key->frame_types & (1 << IEEE802154_FC_TYPE_MAC_CMD)) &&
0220         key->cmd_frame_ids)
0221         return -EINVAL;
0222 
0223     list_for_each_entry(pos, &sec->table.keys, list) {
0224         if (llsec_key_id_equal(&pos->id, id))
0225             return -EEXIST;
0226 
0227         if (memcmp(pos->key->key, key->key,
0228                IEEE802154_LLSEC_KEY_SIZE))
0229             continue;
0230 
0231         mkey = container_of(pos->key, struct mac802154_llsec_key, key);
0232 
0233         /* Don't allow multiple instances of the same AES key to have
0234          * different allowed frame types/command frame ids, as this is
0235          * not possible in the 802.15.4 PIB.
0236          */
0237         if (pos->key->frame_types != key->frame_types ||
0238             pos->key->cmd_frame_ids != key->cmd_frame_ids)
0239             return -EEXIST;
0240 
0241         break;
0242     }
0243 
0244     new = kzalloc(sizeof(*new), GFP_KERNEL);
0245     if (!new)
0246         return -ENOMEM;
0247 
0248     if (!mkey)
0249         mkey = llsec_key_alloc(key);
0250     else
0251         mkey = llsec_key_get(mkey);
0252 
0253     if (!mkey)
0254         goto fail;
0255 
0256     new->id = *id;
0257     new->key = &mkey->key;
0258 
0259     list_add_rcu(&new->list, &sec->table.keys);
0260 
0261     return 0;
0262 
0263 fail:
0264     kfree_sensitive(new);
0265     return -ENOMEM;
0266 }
0267 
0268 int mac802154_llsec_key_del(struct mac802154_llsec *sec,
0269                 const struct ieee802154_llsec_key_id *key)
0270 {
0271     struct ieee802154_llsec_key_entry *pos;
0272 
0273     list_for_each_entry(pos, &sec->table.keys, list) {
0274         struct mac802154_llsec_key *mkey;
0275 
0276         mkey = container_of(pos->key, struct mac802154_llsec_key, key);
0277 
0278         if (llsec_key_id_equal(&pos->id, key)) {
0279             list_del_rcu(&pos->list);
0280             llsec_key_put(mkey);
0281             return 0;
0282         }
0283     }
0284 
0285     return -ENOENT;
0286 }
0287 
0288 static bool llsec_dev_use_shortaddr(__le16 short_addr)
0289 {
0290     return short_addr != cpu_to_le16(IEEE802154_ADDR_UNDEF) &&
0291         short_addr != cpu_to_le16(0xffff);
0292 }
0293 
0294 static u32 llsec_dev_hash_short(__le16 short_addr, __le16 pan_id)
0295 {
0296     return ((__force u16)short_addr) << 16 | (__force u16)pan_id;
0297 }
0298 
0299 static u64 llsec_dev_hash_long(__le64 hwaddr)
0300 {
0301     return (__force u64)hwaddr;
0302 }
0303 
0304 static struct mac802154_llsec_device*
0305 llsec_dev_find_short(struct mac802154_llsec *sec, __le16 short_addr,
0306              __le16 pan_id)
0307 {
0308     struct mac802154_llsec_device *dev;
0309     u32 key = llsec_dev_hash_short(short_addr, pan_id);
0310 
0311     hash_for_each_possible_rcu(sec->devices_short, dev, bucket_s, key) {
0312         if (dev->dev.short_addr == short_addr &&
0313             dev->dev.pan_id == pan_id)
0314             return dev;
0315     }
0316 
0317     return NULL;
0318 }
0319 
0320 static struct mac802154_llsec_device*
0321 llsec_dev_find_long(struct mac802154_llsec *sec, __le64 hwaddr)
0322 {
0323     struct mac802154_llsec_device *dev;
0324     u64 key = llsec_dev_hash_long(hwaddr);
0325 
0326     hash_for_each_possible_rcu(sec->devices_hw, dev, bucket_hw, key) {
0327         if (dev->dev.hwaddr == hwaddr)
0328             return dev;
0329     }
0330 
0331     return NULL;
0332 }
0333 
0334 static void llsec_dev_free(struct mac802154_llsec_device *dev)
0335 {
0336     struct ieee802154_llsec_device_key *pos, *pn;
0337     struct mac802154_llsec_device_key *devkey;
0338 
0339     list_for_each_entry_safe(pos, pn, &dev->dev.keys, list) {
0340         devkey = container_of(pos, struct mac802154_llsec_device_key,
0341                       devkey);
0342 
0343         list_del(&pos->list);
0344         kfree_sensitive(devkey);
0345     }
0346 
0347     kfree_sensitive(dev);
0348 }
0349 
0350 int mac802154_llsec_dev_add(struct mac802154_llsec *sec,
0351                 const struct ieee802154_llsec_device *dev)
0352 {
0353     struct mac802154_llsec_device *entry;
0354     u32 skey = llsec_dev_hash_short(dev->short_addr, dev->pan_id);
0355     u64 hwkey = llsec_dev_hash_long(dev->hwaddr);
0356 
0357     BUILD_BUG_ON(sizeof(hwkey) != IEEE802154_ADDR_LEN);
0358 
0359     if ((llsec_dev_use_shortaddr(dev->short_addr) &&
0360          llsec_dev_find_short(sec, dev->short_addr, dev->pan_id)) ||
0361          llsec_dev_find_long(sec, dev->hwaddr))
0362         return -EEXIST;
0363 
0364     entry = kmalloc(sizeof(*entry), GFP_KERNEL);
0365     if (!entry)
0366         return -ENOMEM;
0367 
0368     entry->dev = *dev;
0369     spin_lock_init(&entry->lock);
0370     INIT_LIST_HEAD(&entry->dev.keys);
0371 
0372     if (llsec_dev_use_shortaddr(dev->short_addr))
0373         hash_add_rcu(sec->devices_short, &entry->bucket_s, skey);
0374     else
0375         INIT_HLIST_NODE(&entry->bucket_s);
0376 
0377     hash_add_rcu(sec->devices_hw, &entry->bucket_hw, hwkey);
0378     list_add_tail_rcu(&entry->dev.list, &sec->table.devices);
0379 
0380     return 0;
0381 }
0382 
0383 static void llsec_dev_free_rcu(struct rcu_head *rcu)
0384 {
0385     llsec_dev_free(container_of(rcu, struct mac802154_llsec_device, rcu));
0386 }
0387 
0388 int mac802154_llsec_dev_del(struct mac802154_llsec *sec, __le64 device_addr)
0389 {
0390     struct mac802154_llsec_device *pos;
0391 
0392     pos = llsec_dev_find_long(sec, device_addr);
0393     if (!pos)
0394         return -ENOENT;
0395 
0396     hash_del_rcu(&pos->bucket_s);
0397     hash_del_rcu(&pos->bucket_hw);
0398     list_del_rcu(&pos->dev.list);
0399     call_rcu(&pos->rcu, llsec_dev_free_rcu);
0400 
0401     return 0;
0402 }
0403 
0404 static struct mac802154_llsec_device_key*
0405 llsec_devkey_find(struct mac802154_llsec_device *dev,
0406           const struct ieee802154_llsec_key_id *key)
0407 {
0408     struct ieee802154_llsec_device_key *devkey;
0409 
0410     list_for_each_entry_rcu(devkey, &dev->dev.keys, list) {
0411         if (!llsec_key_id_equal(key, &devkey->key_id))
0412             continue;
0413 
0414         return container_of(devkey, struct mac802154_llsec_device_key,
0415                     devkey);
0416     }
0417 
0418     return NULL;
0419 }
0420 
0421 int mac802154_llsec_devkey_add(struct mac802154_llsec *sec,
0422                    __le64 dev_addr,
0423                    const struct ieee802154_llsec_device_key *key)
0424 {
0425     struct mac802154_llsec_device *dev;
0426     struct mac802154_llsec_device_key *devkey;
0427 
0428     dev = llsec_dev_find_long(sec, dev_addr);
0429 
0430     if (!dev)
0431         return -ENOENT;
0432 
0433     if (llsec_devkey_find(dev, &key->key_id))
0434         return -EEXIST;
0435 
0436     devkey = kmalloc(sizeof(*devkey), GFP_KERNEL);
0437     if (!devkey)
0438         return -ENOMEM;
0439 
0440     devkey->devkey = *key;
0441     list_add_tail_rcu(&devkey->devkey.list, &dev->dev.keys);
0442     return 0;
0443 }
0444 
0445 int mac802154_llsec_devkey_del(struct mac802154_llsec *sec,
0446                    __le64 dev_addr,
0447                    const struct ieee802154_llsec_device_key *key)
0448 {
0449     struct mac802154_llsec_device *dev;
0450     struct mac802154_llsec_device_key *devkey;
0451 
0452     dev = llsec_dev_find_long(sec, dev_addr);
0453 
0454     if (!dev)
0455         return -ENOENT;
0456 
0457     devkey = llsec_devkey_find(dev, &key->key_id);
0458     if (!devkey)
0459         return -ENOENT;
0460 
0461     list_del_rcu(&devkey->devkey.list);
0462     kfree_rcu(devkey, rcu);
0463     return 0;
0464 }
0465 
0466 static struct mac802154_llsec_seclevel*
0467 llsec_find_seclevel(const struct mac802154_llsec *sec,
0468             const struct ieee802154_llsec_seclevel *sl)
0469 {
0470     struct ieee802154_llsec_seclevel *pos;
0471 
0472     list_for_each_entry(pos, &sec->table.security_levels, list) {
0473         if (pos->frame_type != sl->frame_type ||
0474             (pos->frame_type == IEEE802154_FC_TYPE_MAC_CMD &&
0475              pos->cmd_frame_id != sl->cmd_frame_id) ||
0476             pos->device_override != sl->device_override ||
0477             pos->sec_levels != sl->sec_levels)
0478             continue;
0479 
0480         return container_of(pos, struct mac802154_llsec_seclevel,
0481                     level);
0482     }
0483 
0484     return NULL;
0485 }
0486 
0487 int mac802154_llsec_seclevel_add(struct mac802154_llsec *sec,
0488                  const struct ieee802154_llsec_seclevel *sl)
0489 {
0490     struct mac802154_llsec_seclevel *entry;
0491 
0492     if (llsec_find_seclevel(sec, sl))
0493         return -EEXIST;
0494 
0495     entry = kmalloc(sizeof(*entry), GFP_KERNEL);
0496     if (!entry)
0497         return -ENOMEM;
0498 
0499     entry->level = *sl;
0500 
0501     list_add_tail_rcu(&entry->level.list, &sec->table.security_levels);
0502 
0503     return 0;
0504 }
0505 
0506 int mac802154_llsec_seclevel_del(struct mac802154_llsec *sec,
0507                  const struct ieee802154_llsec_seclevel *sl)
0508 {
0509     struct mac802154_llsec_seclevel *pos;
0510 
0511     pos = llsec_find_seclevel(sec, sl);
0512     if (!pos)
0513         return -ENOENT;
0514 
0515     list_del_rcu(&pos->level.list);
0516     kfree_rcu(pos, rcu);
0517 
0518     return 0;
0519 }
0520 
0521 static int llsec_recover_addr(struct mac802154_llsec *sec,
0522                   struct ieee802154_addr *addr)
0523 {
0524     __le16 caddr = sec->params.coord_shortaddr;
0525 
0526     addr->pan_id = sec->params.pan_id;
0527 
0528     if (caddr == cpu_to_le16(IEEE802154_ADDR_BROADCAST)) {
0529         return -EINVAL;
0530     } else if (caddr == cpu_to_le16(IEEE802154_ADDR_UNDEF)) {
0531         addr->extended_addr = sec->params.coord_hwaddr;
0532         addr->mode = IEEE802154_ADDR_LONG;
0533     } else {
0534         addr->short_addr = sec->params.coord_shortaddr;
0535         addr->mode = IEEE802154_ADDR_SHORT;
0536     }
0537 
0538     return 0;
0539 }
0540 
0541 static struct mac802154_llsec_key*
0542 llsec_lookup_key(struct mac802154_llsec *sec,
0543          const struct ieee802154_hdr *hdr,
0544          const struct ieee802154_addr *addr,
0545          struct ieee802154_llsec_key_id *key_id)
0546 {
0547     struct ieee802154_addr devaddr = *addr;
0548     u8 key_id_mode = hdr->sec.key_id_mode;
0549     struct ieee802154_llsec_key_entry *key_entry;
0550     struct mac802154_llsec_key *key;
0551 
0552     if (key_id_mode == IEEE802154_SCF_KEY_IMPLICIT &&
0553         devaddr.mode == IEEE802154_ADDR_NONE) {
0554         if (hdr->fc.type == IEEE802154_FC_TYPE_BEACON) {
0555             devaddr.extended_addr = sec->params.coord_hwaddr;
0556             devaddr.mode = IEEE802154_ADDR_LONG;
0557         } else if (llsec_recover_addr(sec, &devaddr) < 0) {
0558             return NULL;
0559         }
0560     }
0561 
0562     list_for_each_entry_rcu(key_entry, &sec->table.keys, list) {
0563         const struct ieee802154_llsec_key_id *id = &key_entry->id;
0564 
0565         if (!(key_entry->key->frame_types & BIT(hdr->fc.type)))
0566             continue;
0567 
0568         if (id->mode != key_id_mode)
0569             continue;
0570 
0571         if (key_id_mode == IEEE802154_SCF_KEY_IMPLICIT) {
0572             if (ieee802154_addr_equal(&devaddr, &id->device_addr))
0573                 goto found;
0574         } else {
0575             if (id->id != hdr->sec.key_id)
0576                 continue;
0577 
0578             if ((key_id_mode == IEEE802154_SCF_KEY_INDEX) ||
0579                 (key_id_mode == IEEE802154_SCF_KEY_SHORT_INDEX &&
0580                  id->short_source == hdr->sec.short_src) ||
0581                 (key_id_mode == IEEE802154_SCF_KEY_HW_INDEX &&
0582                  id->extended_source == hdr->sec.extended_src))
0583                 goto found;
0584         }
0585     }
0586 
0587     return NULL;
0588 
0589 found:
0590     key = container_of(key_entry->key, struct mac802154_llsec_key, key);
0591     if (key_id)
0592         *key_id = key_entry->id;
0593     return llsec_key_get(key);
0594 }
0595 
0596 static void llsec_geniv(u8 iv[16], __le64 addr,
0597             const struct ieee802154_sechdr *sec)
0598 {
0599     __be64 addr_bytes = (__force __be64) swab64((__force u64) addr);
0600     __be32 frame_counter = (__force __be32) swab32((__force u32) sec->frame_counter);
0601 
0602     iv[0] = 1; /* L' = L - 1 = 1 */
0603     memcpy(iv + 1, &addr_bytes, sizeof(addr_bytes));
0604     memcpy(iv + 9, &frame_counter, sizeof(frame_counter));
0605     iv[13] = sec->level;
0606     iv[14] = 0;
0607     iv[15] = 1;
0608 }
0609 
0610 static int
0611 llsec_do_encrypt_unauth(struct sk_buff *skb, const struct mac802154_llsec *sec,
0612             const struct ieee802154_hdr *hdr,
0613             struct mac802154_llsec_key *key)
0614 {
0615     u8 iv[16];
0616     struct scatterlist src;
0617     SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->tfm0);
0618     int err, datalen;
0619     unsigned char *data;
0620 
0621     llsec_geniv(iv, sec->params.hwaddr, &hdr->sec);
0622     /* Compute data payload offset and data length */
0623     data = skb_mac_header(skb) + skb->mac_len;
0624     datalen = skb_tail_pointer(skb) - data;
0625     sg_init_one(&src, data, datalen);
0626 
0627     skcipher_request_set_sync_tfm(req, key->tfm0);
0628     skcipher_request_set_callback(req, 0, NULL, NULL);
0629     skcipher_request_set_crypt(req, &src, &src, datalen, iv);
0630     err = crypto_skcipher_encrypt(req);
0631     skcipher_request_zero(req);
0632     return err;
0633 }
0634 
0635 static struct crypto_aead*
0636 llsec_tfm_by_len(struct mac802154_llsec_key *key, int authlen)
0637 {
0638     int i;
0639 
0640     for (i = 0; i < ARRAY_SIZE(key->tfm); i++)
0641         if (crypto_aead_authsize(key->tfm[i]) == authlen)
0642             return key->tfm[i];
0643 
0644     BUG();
0645 }
0646 
0647 static int
0648 llsec_do_encrypt_auth(struct sk_buff *skb, const struct mac802154_llsec *sec,
0649               const struct ieee802154_hdr *hdr,
0650               struct mac802154_llsec_key *key)
0651 {
0652     u8 iv[16];
0653     unsigned char *data;
0654     int authlen, assoclen, datalen, rc;
0655     struct scatterlist sg;
0656     struct aead_request *req;
0657 
0658     authlen = ieee802154_sechdr_authtag_len(&hdr->sec);
0659     llsec_geniv(iv, sec->params.hwaddr, &hdr->sec);
0660 
0661     req = aead_request_alloc(llsec_tfm_by_len(key, authlen), GFP_ATOMIC);
0662     if (!req)
0663         return -ENOMEM;
0664 
0665     assoclen = skb->mac_len;
0666 
0667     data = skb_mac_header(skb) + skb->mac_len;
0668     datalen = skb_tail_pointer(skb) - data;
0669 
0670     skb_put(skb, authlen);
0671 
0672     sg_init_one(&sg, skb_mac_header(skb), assoclen + datalen + authlen);
0673 
0674     if (!(hdr->sec.level & IEEE802154_SCF_SECLEVEL_ENC)) {
0675         assoclen += datalen;
0676         datalen = 0;
0677     }
0678 
0679     aead_request_set_callback(req, 0, NULL, NULL);
0680     aead_request_set_crypt(req, &sg, &sg, datalen, iv);
0681     aead_request_set_ad(req, assoclen);
0682 
0683     rc = crypto_aead_encrypt(req);
0684 
0685     kfree_sensitive(req);
0686 
0687     return rc;
0688 }
0689 
0690 static int llsec_do_encrypt(struct sk_buff *skb,
0691                 const struct mac802154_llsec *sec,
0692                 const struct ieee802154_hdr *hdr,
0693                 struct mac802154_llsec_key *key)
0694 {
0695     if (hdr->sec.level == IEEE802154_SCF_SECLEVEL_ENC)
0696         return llsec_do_encrypt_unauth(skb, sec, hdr, key);
0697     else
0698         return llsec_do_encrypt_auth(skb, sec, hdr, key);
0699 }
0700 
0701 int mac802154_llsec_encrypt(struct mac802154_llsec *sec, struct sk_buff *skb)
0702 {
0703     struct ieee802154_hdr hdr;
0704     int rc, authlen, hlen;
0705     struct mac802154_llsec_key *key;
0706     u32 frame_ctr;
0707 
0708     hlen = ieee802154_hdr_pull(skb, &hdr);
0709 
0710     if (hlen < 0 || hdr.fc.type != IEEE802154_FC_TYPE_DATA)
0711         return -EINVAL;
0712 
0713     if (!hdr.fc.security_enabled ||
0714         (hdr.sec.level == IEEE802154_SCF_SECLEVEL_NONE)) {
0715         skb_push(skb, hlen);
0716         return 0;
0717     }
0718 
0719     authlen = ieee802154_sechdr_authtag_len(&hdr.sec);
0720 
0721     if (skb->len + hlen + authlen + IEEE802154_MFR_SIZE > IEEE802154_MTU)
0722         return -EMSGSIZE;
0723 
0724     rcu_read_lock();
0725 
0726     read_lock_bh(&sec->lock);
0727 
0728     if (!sec->params.enabled) {
0729         rc = -EINVAL;
0730         goto fail_read;
0731     }
0732 
0733     key = llsec_lookup_key(sec, &hdr, &hdr.dest, NULL);
0734     if (!key) {
0735         rc = -ENOKEY;
0736         goto fail_read;
0737     }
0738 
0739     read_unlock_bh(&sec->lock);
0740 
0741     write_lock_bh(&sec->lock);
0742 
0743     frame_ctr = be32_to_cpu(sec->params.frame_counter);
0744     hdr.sec.frame_counter = cpu_to_le32(frame_ctr);
0745     if (frame_ctr == 0xFFFFFFFF) {
0746         write_unlock_bh(&sec->lock);
0747         llsec_key_put(key);
0748         rc = -EOVERFLOW;
0749         goto fail;
0750     }
0751 
0752     sec->params.frame_counter = cpu_to_be32(frame_ctr + 1);
0753 
0754     write_unlock_bh(&sec->lock);
0755 
0756     rcu_read_unlock();
0757 
0758     skb->mac_len = ieee802154_hdr_push(skb, &hdr);
0759     skb_reset_mac_header(skb);
0760 
0761     rc = llsec_do_encrypt(skb, sec, &hdr, key);
0762     llsec_key_put(key);
0763 
0764     return rc;
0765 
0766 fail_read:
0767     read_unlock_bh(&sec->lock);
0768 fail:
0769     rcu_read_unlock();
0770     return rc;
0771 }
0772 
0773 static struct mac802154_llsec_device*
0774 llsec_lookup_dev(struct mac802154_llsec *sec,
0775          const struct ieee802154_addr *addr)
0776 {
0777     struct ieee802154_addr devaddr = *addr;
0778     struct mac802154_llsec_device *dev = NULL;
0779 
0780     if (devaddr.mode == IEEE802154_ADDR_NONE &&
0781         llsec_recover_addr(sec, &devaddr) < 0)
0782         return NULL;
0783 
0784     if (devaddr.mode == IEEE802154_ADDR_SHORT) {
0785         u32 key = llsec_dev_hash_short(devaddr.short_addr,
0786                            devaddr.pan_id);
0787 
0788         hash_for_each_possible_rcu(sec->devices_short, dev,
0789                        bucket_s, key) {
0790             if (dev->dev.pan_id == devaddr.pan_id &&
0791                 dev->dev.short_addr == devaddr.short_addr)
0792                 return dev;
0793         }
0794     } else {
0795         u64 key = llsec_dev_hash_long(devaddr.extended_addr);
0796 
0797         hash_for_each_possible_rcu(sec->devices_hw, dev,
0798                        bucket_hw, key) {
0799             if (dev->dev.hwaddr == devaddr.extended_addr)
0800                 return dev;
0801         }
0802     }
0803 
0804     return NULL;
0805 }
0806 
0807 static int
0808 llsec_lookup_seclevel(const struct mac802154_llsec *sec,
0809               u8 frame_type, u8 cmd_frame_id,
0810               struct ieee802154_llsec_seclevel *rlevel)
0811 {
0812     struct ieee802154_llsec_seclevel *level;
0813 
0814     list_for_each_entry_rcu(level, &sec->table.security_levels, list) {
0815         if (level->frame_type == frame_type &&
0816             (frame_type != IEEE802154_FC_TYPE_MAC_CMD ||
0817              level->cmd_frame_id == cmd_frame_id)) {
0818             *rlevel = *level;
0819             return 0;
0820         }
0821     }
0822 
0823     return -EINVAL;
0824 }
0825 
0826 static int
0827 llsec_do_decrypt_unauth(struct sk_buff *skb, const struct mac802154_llsec *sec,
0828             const struct ieee802154_hdr *hdr,
0829             struct mac802154_llsec_key *key, __le64 dev_addr)
0830 {
0831     u8 iv[16];
0832     unsigned char *data;
0833     int datalen;
0834     struct scatterlist src;
0835     SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->tfm0);
0836     int err;
0837 
0838     llsec_geniv(iv, dev_addr, &hdr->sec);
0839     data = skb_mac_header(skb) + skb->mac_len;
0840     datalen = skb_tail_pointer(skb) - data;
0841 
0842     sg_init_one(&src, data, datalen);
0843 
0844     skcipher_request_set_sync_tfm(req, key->tfm0);
0845     skcipher_request_set_callback(req, 0, NULL, NULL);
0846     skcipher_request_set_crypt(req, &src, &src, datalen, iv);
0847 
0848     err = crypto_skcipher_decrypt(req);
0849     skcipher_request_zero(req);
0850     return err;
0851 }
0852 
0853 static int
0854 llsec_do_decrypt_auth(struct sk_buff *skb, const struct mac802154_llsec *sec,
0855               const struct ieee802154_hdr *hdr,
0856               struct mac802154_llsec_key *key, __le64 dev_addr)
0857 {
0858     u8 iv[16];
0859     unsigned char *data;
0860     int authlen, datalen, assoclen, rc;
0861     struct scatterlist sg;
0862     struct aead_request *req;
0863 
0864     authlen = ieee802154_sechdr_authtag_len(&hdr->sec);
0865     llsec_geniv(iv, dev_addr, &hdr->sec);
0866 
0867     req = aead_request_alloc(llsec_tfm_by_len(key, authlen), GFP_ATOMIC);
0868     if (!req)
0869         return -ENOMEM;
0870 
0871     assoclen = skb->mac_len;
0872 
0873     data = skb_mac_header(skb) + skb->mac_len;
0874     datalen = skb_tail_pointer(skb) - data;
0875 
0876     sg_init_one(&sg, skb_mac_header(skb), assoclen + datalen);
0877 
0878     if (!(hdr->sec.level & IEEE802154_SCF_SECLEVEL_ENC)) {
0879         assoclen += datalen - authlen;
0880         datalen = authlen;
0881     }
0882 
0883     aead_request_set_callback(req, 0, NULL, NULL);
0884     aead_request_set_crypt(req, &sg, &sg, datalen, iv);
0885     aead_request_set_ad(req, assoclen);
0886 
0887     rc = crypto_aead_decrypt(req);
0888 
0889     kfree_sensitive(req);
0890     skb_trim(skb, skb->len - authlen);
0891 
0892     return rc;
0893 }
0894 
0895 static int
0896 llsec_do_decrypt(struct sk_buff *skb, const struct mac802154_llsec *sec,
0897          const struct ieee802154_hdr *hdr,
0898          struct mac802154_llsec_key *key, __le64 dev_addr)
0899 {
0900     if (hdr->sec.level == IEEE802154_SCF_SECLEVEL_ENC)
0901         return llsec_do_decrypt_unauth(skb, sec, hdr, key, dev_addr);
0902     else
0903         return llsec_do_decrypt_auth(skb, sec, hdr, key, dev_addr);
0904 }
0905 
0906 static int
0907 llsec_update_devkey_record(struct mac802154_llsec_device *dev,
0908                const struct ieee802154_llsec_key_id *in_key)
0909 {
0910     struct mac802154_llsec_device_key *devkey;
0911 
0912     devkey = llsec_devkey_find(dev, in_key);
0913 
0914     if (!devkey) {
0915         struct mac802154_llsec_device_key *next;
0916 
0917         next = kzalloc(sizeof(*devkey), GFP_ATOMIC);
0918         if (!next)
0919             return -ENOMEM;
0920 
0921         next->devkey.key_id = *in_key;
0922 
0923         spin_lock_bh(&dev->lock);
0924 
0925         devkey = llsec_devkey_find(dev, in_key);
0926         if (!devkey)
0927             list_add_rcu(&next->devkey.list, &dev->dev.keys);
0928         else
0929             kfree_sensitive(next);
0930 
0931         spin_unlock_bh(&dev->lock);
0932     }
0933 
0934     return 0;
0935 }
0936 
0937 static int
0938 llsec_update_devkey_info(struct mac802154_llsec_device *dev,
0939              const struct ieee802154_llsec_key_id *in_key,
0940              u32 frame_counter)
0941 {
0942     struct mac802154_llsec_device_key *devkey = NULL;
0943 
0944     if (dev->dev.key_mode == IEEE802154_LLSEC_DEVKEY_RESTRICT) {
0945         devkey = llsec_devkey_find(dev, in_key);
0946         if (!devkey)
0947             return -ENOENT;
0948     }
0949 
0950     if (dev->dev.key_mode == IEEE802154_LLSEC_DEVKEY_RECORD) {
0951         int rc = llsec_update_devkey_record(dev, in_key);
0952 
0953         if (rc < 0)
0954             return rc;
0955     }
0956 
0957     spin_lock_bh(&dev->lock);
0958 
0959     if ((!devkey && frame_counter < dev->dev.frame_counter) ||
0960         (devkey && frame_counter < devkey->devkey.frame_counter)) {
0961         spin_unlock_bh(&dev->lock);
0962         return -EINVAL;
0963     }
0964 
0965     if (devkey)
0966         devkey->devkey.frame_counter = frame_counter + 1;
0967     else
0968         dev->dev.frame_counter = frame_counter + 1;
0969 
0970     spin_unlock_bh(&dev->lock);
0971 
0972     return 0;
0973 }
0974 
0975 int mac802154_llsec_decrypt(struct mac802154_llsec *sec, struct sk_buff *skb)
0976 {
0977     struct ieee802154_hdr hdr;
0978     struct mac802154_llsec_key *key;
0979     struct ieee802154_llsec_key_id key_id;
0980     struct mac802154_llsec_device *dev;
0981     struct ieee802154_llsec_seclevel seclevel;
0982     int err;
0983     __le64 dev_addr;
0984     u32 frame_ctr;
0985 
0986     if (ieee802154_hdr_peek(skb, &hdr) < 0)
0987         return -EINVAL;
0988     if (!hdr.fc.security_enabled)
0989         return 0;
0990     if (hdr.fc.version == 0)
0991         return -EINVAL;
0992 
0993     read_lock_bh(&sec->lock);
0994     if (!sec->params.enabled) {
0995         read_unlock_bh(&sec->lock);
0996         return -EINVAL;
0997     }
0998     read_unlock_bh(&sec->lock);
0999 
1000     rcu_read_lock();
1001 
1002     key = llsec_lookup_key(sec, &hdr, &hdr.source, &key_id);
1003     if (!key) {
1004         err = -ENOKEY;
1005         goto fail;
1006     }
1007 
1008     dev = llsec_lookup_dev(sec, &hdr.source);
1009     if (!dev) {
1010         err = -EINVAL;
1011         goto fail_dev;
1012     }
1013 
1014     if (llsec_lookup_seclevel(sec, hdr.fc.type, 0, &seclevel) < 0) {
1015         err = -EINVAL;
1016         goto fail_dev;
1017     }
1018 
1019     if (!(seclevel.sec_levels & BIT(hdr.sec.level)) &&
1020         (hdr.sec.level == 0 && seclevel.device_override &&
1021          !dev->dev.seclevel_exempt)) {
1022         err = -EINVAL;
1023         goto fail_dev;
1024     }
1025 
1026     frame_ctr = le32_to_cpu(hdr.sec.frame_counter);
1027 
1028     if (frame_ctr == 0xffffffff) {
1029         err = -EOVERFLOW;
1030         goto fail_dev;
1031     }
1032 
1033     err = llsec_update_devkey_info(dev, &key_id, frame_ctr);
1034     if (err)
1035         goto fail_dev;
1036 
1037     dev_addr = dev->dev.hwaddr;
1038 
1039     rcu_read_unlock();
1040 
1041     err = llsec_do_decrypt(skb, sec, &hdr, key, dev_addr);
1042     llsec_key_put(key);
1043     return err;
1044 
1045 fail_dev:
1046     llsec_key_put(key);
1047 fail:
1048     rcu_read_unlock();
1049     return err;
1050 }