|
@@ -920,6 +920,37 @@ llsec_do_decrypt(struct sk_buff *skb, const struct mac802154_llsec *sec,
|
|
|
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,
|
|
@@ -933,6 +964,13 @@ llsec_update_devkey_info(struct mac802154_llsec_device *dev,
|
|
|
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) ||
|