enum {
IEEE802154_LLSEC_DEVKEY_IGNORE,
IEEE802154_LLSEC_DEVKEY_RESTRICT,
+ IEEE802154_LLSEC_DEVKEY_RECORD,
__IEEE802154_LLSEC_DEVKEY_MAX,
};
return llsec_do_decrypt_auth(skb, sec, hdr, key, dev_addr);
}
+static int
+llsec_update_devkey_record(struct mac802154_llsec_device *dev,
+ const struct ieee802154_llsec_key_id *in_key)
+{
+ struct mac802154_llsec_device_key *devkey;
+
+ devkey = llsec_devkey_find(dev, in_key);
+
+ if (!devkey) {
+ struct mac802154_llsec_device_key *next;
+
+ next = kzalloc(sizeof(*devkey), GFP_ATOMIC);
+ if (!next)
+ return -ENOMEM;
+
+ next->devkey.key_id = *in_key;
+
+ spin_lock_bh(&dev->lock);
+
+ devkey = llsec_devkey_find(dev, in_key);
+ if (!devkey)
+ list_add_rcu(&next->devkey.list, &dev->dev.keys);
+ else
+ kfree(next);
+
+ spin_unlock_bh(&dev->lock);
+ }
+
+ return 0;
+}
+
static int
llsec_update_devkey_info(struct mac802154_llsec_device *dev,
const struct ieee802154_llsec_key_id *in_key,
return -ENOENT;
}
+ if (dev->dev.key_mode == IEEE802154_LLSEC_DEVKEY_RECORD) {
+ int rc = llsec_update_devkey_record(dev, in_key);
+
+ if (rc < 0)
+ return rc;
+ }
+
spin_lock_bh(&dev->lock);
if ((!devkey && frame_counter < dev->dev.frame_counter) ||