diff options
author | Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> | 2014-05-16 11:46:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-16 17:23:42 -0400 |
commit | f0f77dc6be76ed1854b08688390e156e4b351ab5 (patch) | |
tree | 07e7cdba0bc3a096bf2933da0a1af984e6ae4dd2 /net/mac802154 | |
parent | 3e9c156e2c210ab67b12b1b692983a6b97c19d3f (diff) |
ieee802154, mac802154: implement devkey record option
The 802.15.4-2011 standard states that for each key, a list of devices
that use this key shall be kept. Previous patches have only considered
two options:
* a device "uses" (or may use) all keys, rendering the list useless
* a device is restricted to a certain set of keys
Another option would be that a device *may* use all keys, but need not
do so, and we are interested in the actual set of keys the device uses.
Recording keys used by any given device may have a noticable performance
impact and might not be needed as often. The common case, in which a
device will not switch keys too often, should still perform well.
Signed-off-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac802154')
-rw-r--r-- | net/mac802154/llsec.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index 392653b1b5a3..a83674edaafd 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c | |||
@@ -921,6 +921,37 @@ llsec_do_decrypt(struct sk_buff *skb, const struct mac802154_llsec *sec, | |||
921 | } | 921 | } |
922 | 922 | ||
923 | static int | 923 | static int |
924 | llsec_update_devkey_record(struct mac802154_llsec_device *dev, | ||
925 | const struct ieee802154_llsec_key_id *in_key) | ||
926 | { | ||
927 | struct mac802154_llsec_device_key *devkey; | ||
928 | |||
929 | devkey = llsec_devkey_find(dev, in_key); | ||
930 | |||
931 | if (!devkey) { | ||
932 | struct mac802154_llsec_device_key *next; | ||
933 | |||
934 | next = kzalloc(sizeof(*devkey), GFP_ATOMIC); | ||
935 | if (!next) | ||
936 | return -ENOMEM; | ||
937 | |||
938 | next->devkey.key_id = *in_key; | ||
939 | |||
940 | spin_lock_bh(&dev->lock); | ||
941 | |||
942 | devkey = llsec_devkey_find(dev, in_key); | ||
943 | if (!devkey) | ||
944 | list_add_rcu(&next->devkey.list, &dev->dev.keys); | ||
945 | else | ||
946 | kfree(next); | ||
947 | |||
948 | spin_unlock_bh(&dev->lock); | ||
949 | } | ||
950 | |||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | static int | ||
924 | llsec_update_devkey_info(struct mac802154_llsec_device *dev, | 955 | llsec_update_devkey_info(struct mac802154_llsec_device *dev, |
925 | const struct ieee802154_llsec_key_id *in_key, | 956 | const struct ieee802154_llsec_key_id *in_key, |
926 | u32 frame_counter) | 957 | u32 frame_counter) |
@@ -933,6 +964,13 @@ llsec_update_devkey_info(struct mac802154_llsec_device *dev, | |||
933 | return -ENOENT; | 964 | return -ENOENT; |
934 | } | 965 | } |
935 | 966 | ||
967 | if (dev->dev.key_mode == IEEE802154_LLSEC_DEVKEY_RECORD) { | ||
968 | int rc = llsec_update_devkey_record(dev, in_key); | ||
969 | |||
970 | if (rc < 0) | ||
971 | return rc; | ||
972 | } | ||
973 | |||
936 | spin_lock_bh(&dev->lock); | 974 | spin_lock_bh(&dev->lock); |
937 | 975 | ||
938 | if ((!devkey && frame_counter < dev->dev.frame_counter) || | 976 | if ((!devkey && frame_counter < dev->dev.frame_counter) || |