aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154/wpan.c
diff options
context:
space:
mode:
authorPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>2014-05-16 11:46:40 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-16 17:23:41 -0400
commitf30be4d53cada48598dab0983866ae4b16af46dc (patch)
tree032e1761fd2a0f7ea4bb09f828d3938c99085725 /net/mac802154/wpan.c
parent4c14a2fb5d143e4ed94143be2b8c1961b47df9af (diff)
mac802154: integrate llsec with wpan devices
Signed-off-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac802154/wpan.c')
-rw-r--r--net/mac802154/wpan.c118
1 files changed, 90 insertions, 28 deletions
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
index ed105774c15d..00729ca1e30a 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
@@ -183,6 +183,38 @@ out:
183 return rc; 183 return rc;
184} 184}
185 185
186static int mac802154_set_header_security(struct mac802154_sub_if_data *priv,
187 struct ieee802154_hdr *hdr,
188 const struct ieee802154_mac_cb *cb)
189{
190 struct ieee802154_llsec_params params;
191 u8 level;
192
193 mac802154_llsec_get_params(&priv->sec, &params);
194
195 if (!params.enabled && cb->secen_override && cb->secen)
196 return -EINVAL;
197 if (!params.enabled ||
198 (cb->secen_override && !cb->secen) ||
199 !params.out_level)
200 return 0;
201 if (cb->seclevel_override && !cb->seclevel)
202 return -EINVAL;
203
204 level = cb->seclevel_override ? cb->seclevel : params.out_level;
205
206 hdr->fc.security_enabled = 1;
207 hdr->sec.level = level;
208 hdr->sec.key_id_mode = params.out_key.mode;
209 if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX)
210 hdr->sec.short_src = params.out_key.short_source;
211 else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX)
212 hdr->sec.extended_src = params.out_key.extended_source;
213 hdr->sec.key_id = params.out_key.id;
214
215 return 0;
216}
217
186static int mac802154_header_create(struct sk_buff *skb, 218static int mac802154_header_create(struct sk_buff *skb,
187 struct net_device *dev, 219 struct net_device *dev,
188 unsigned short type, 220 unsigned short type,
@@ -204,6 +236,9 @@ static int mac802154_header_create(struct sk_buff *skb,
204 hdr.fc.ack_request = cb->ackreq; 236 hdr.fc.ack_request = cb->ackreq;
205 hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev); 237 hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
206 238
239 if (mac802154_set_header_security(priv, &hdr, cb) < 0)
240 return -EINVAL;
241
207 if (!saddr) { 242 if (!saddr) {
208 spin_lock_bh(&priv->mib_lock); 243 spin_lock_bh(&priv->mib_lock);
209 244
@@ -259,6 +294,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev)
259{ 294{
260 struct mac802154_sub_if_data *priv; 295 struct mac802154_sub_if_data *priv;
261 u8 chan, page; 296 u8 chan, page;
297 int rc;
262 298
263 priv = netdev_priv(dev); 299 priv = netdev_priv(dev);
264 300
@@ -274,6 +310,13 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev)
274 return NETDEV_TX_OK; 310 return NETDEV_TX_OK;
275 } 311 }
276 312
313 rc = mac802154_llsec_encrypt(&priv->sec, skb);
314 if (rc) {
315 pr_warn("encryption failed: %i\n", rc);
316 kfree_skb(skb);
317 return NETDEV_TX_OK;
318 }
319
277 skb->skb_iif = dev->ifindex; 320 skb->skb_iif = dev->ifindex;
278 dev->stats.tx_packets++; 321 dev->stats.tx_packets++;
279 dev->stats.tx_bytes += skb->len; 322 dev->stats.tx_bytes += skb->len;
@@ -294,6 +337,15 @@ static const struct net_device_ops mac802154_wpan_ops = {
294 .ndo_set_mac_address = mac802154_wpan_mac_addr, 337 .ndo_set_mac_address = mac802154_wpan_mac_addr,
295}; 338};
296 339
340static void mac802154_wpan_free(struct net_device *dev)
341{
342 struct mac802154_sub_if_data *priv = netdev_priv(dev);
343
344 mac802154_llsec_destroy(&priv->sec);
345
346 free_netdev(dev);
347}
348
297void mac802154_wpan_setup(struct net_device *dev) 349void mac802154_wpan_setup(struct net_device *dev)
298{ 350{
299 struct mac802154_sub_if_data *priv; 351 struct mac802154_sub_if_data *priv;
@@ -303,14 +355,14 @@ void mac802154_wpan_setup(struct net_device *dev)
303 355
304 dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; 356 dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
305 dev->header_ops = &mac802154_header_ops; 357 dev->header_ops = &mac802154_header_ops;
306 dev->needed_tailroom = 2; /* FCS */ 358 dev->needed_tailroom = 2 + 16; /* FCS + MIC */
307 dev->mtu = IEEE802154_MTU; 359 dev->mtu = IEEE802154_MTU;
308 dev->tx_queue_len = 300; 360 dev->tx_queue_len = 300;
309 dev->type = ARPHRD_IEEE802154; 361 dev->type = ARPHRD_IEEE802154;
310 dev->flags = IFF_NOARP | IFF_BROADCAST; 362 dev->flags = IFF_NOARP | IFF_BROADCAST;
311 dev->watchdog_timeo = 0; 363 dev->watchdog_timeo = 0;
312 364
313 dev->destructor = free_netdev; 365 dev->destructor = mac802154_wpan_free;
314 dev->netdev_ops = &mac802154_wpan_ops; 366 dev->netdev_ops = &mac802154_wpan_ops;
315 dev->ml_priv = &mac802154_mlme_wpan; 367 dev->ml_priv = &mac802154_mlme_wpan;
316 368
@@ -321,6 +373,7 @@ void mac802154_wpan_setup(struct net_device *dev)
321 priv->page = 0; 373 priv->page = 0;
322 374
323 spin_lock_init(&priv->mib_lock); 375 spin_lock_init(&priv->mib_lock);
376 mutex_init(&priv->sec_mtx);
324 377
325 get_random_bytes(&priv->bsn, 1); 378 get_random_bytes(&priv->bsn, 1);
326 get_random_bytes(&priv->dsn, 1); 379 get_random_bytes(&priv->dsn, 1);
@@ -333,6 +386,8 @@ void mac802154_wpan_setup(struct net_device *dev)
333 386
334 priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); 387 priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
335 priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); 388 priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
389
390 mac802154_llsec_init(&priv->sec);
336} 391}
337 392
338static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) 393static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
@@ -341,9 +396,11 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
341} 396}
342 397
343static int 398static int
344mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb) 399mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
400 const struct ieee802154_hdr *hdr)
345{ 401{
346 __le16 span, sshort; 402 __le16 span, sshort;
403 int rc;
347 404
348 pr_debug("getting packet via slave interface %s\n", sdata->dev->name); 405 pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
349 406
@@ -390,6 +447,12 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb)
390 447
391 skb->dev = sdata->dev; 448 skb->dev = sdata->dev;
392 449
450 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
451 if (rc) {
452 pr_debug("decryption failed: %i\n", rc);
453 return NET_RX_DROP;
454 }
455
393 sdata->dev->stats.rx_packets++; 456 sdata->dev->stats.rx_packets++;
394 sdata->dev->stats.rx_bytes += skb->len; 457 sdata->dev->stats.rx_bytes += skb->len;
395 458
@@ -421,60 +484,58 @@ static void mac802154_print_addr(const char *name,
421 } 484 }
422} 485}
423 486
424static int mac802154_parse_frame_start(struct sk_buff *skb) 487static int mac802154_parse_frame_start(struct sk_buff *skb,
488 struct ieee802154_hdr *hdr)
425{ 489{
426 int hlen; 490 int hlen;
427 struct ieee802154_hdr hdr;
428 struct ieee802154_mac_cb *cb = mac_cb_init(skb); 491 struct ieee802154_mac_cb *cb = mac_cb_init(skb);
429 492
430 hlen = ieee802154_hdr_pull(skb, &hdr); 493 hlen = ieee802154_hdr_pull(skb, hdr);
431 if (hlen < 0) 494 if (hlen < 0)
432 return -EINVAL; 495 return -EINVAL;
433 496
434 skb->mac_len = hlen; 497 skb->mac_len = hlen;
435 498
436 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr.fc), 499 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
437 hdr.seq); 500 hdr->seq);
438 501
439 cb->type = hdr.fc.type; 502 cb->type = hdr->fc.type;
440 cb->ackreq = hdr.fc.ack_request; 503 cb->ackreq = hdr->fc.ack_request;
441 cb->secen = hdr.fc.security_enabled; 504 cb->secen = hdr->fc.security_enabled;
442 505
443 mac802154_print_addr("destination", &hdr.dest); 506 mac802154_print_addr("destination", &hdr->dest);
444 mac802154_print_addr("source", &hdr.source); 507 mac802154_print_addr("source", &hdr->source);
445 508
446 cb->source = hdr.source; 509 cb->source = hdr->source;
447 cb->dest = hdr.dest; 510 cb->dest = hdr->dest;
448 511
449 if (hdr.fc.security_enabled) { 512 if (hdr->fc.security_enabled) {
450 u64 key; 513 u64 key;
451 514
452 pr_debug("seclevel %i\n", hdr.sec.level); 515 pr_debug("seclevel %i\n", hdr->sec.level);
453 516
454 switch (hdr.sec.key_id_mode) { 517 switch (hdr->sec.key_id_mode) {
455 case IEEE802154_SCF_KEY_IMPLICIT: 518 case IEEE802154_SCF_KEY_IMPLICIT:
456 pr_debug("implicit key\n"); 519 pr_debug("implicit key\n");
457 break; 520 break;
458 521
459 case IEEE802154_SCF_KEY_INDEX: 522 case IEEE802154_SCF_KEY_INDEX:
460 pr_debug("key %02x\n", hdr.sec.key_id); 523 pr_debug("key %02x\n", hdr->sec.key_id);
461 break; 524 break;
462 525
463 case IEEE802154_SCF_KEY_SHORT_INDEX: 526 case IEEE802154_SCF_KEY_SHORT_INDEX:
464 pr_debug("key %04x:%04x %02x\n", 527 pr_debug("key %04x:%04x %02x\n",
465 le32_to_cpu(hdr.sec.short_src) >> 16, 528 le32_to_cpu(hdr->sec.short_src) >> 16,
466 le32_to_cpu(hdr.sec.short_src) & 0xffff, 529 le32_to_cpu(hdr->sec.short_src) & 0xffff,
467 hdr.sec.key_id); 530 hdr->sec.key_id);
468 break; 531 break;
469 532
470 case IEEE802154_SCF_KEY_HW_INDEX: 533 case IEEE802154_SCF_KEY_HW_INDEX:
471 key = swab64((__force u64) hdr.sec.extended_src); 534 key = swab64((__force u64) hdr->sec.extended_src);
472 pr_debug("key source %8phC %02x\n", &key, 535 pr_debug("key source %8phC %02x\n", &key,
473 hdr.sec.key_id); 536 hdr->sec.key_id);
474 break; 537 break;
475 } 538 }
476
477 return -EINVAL;
478 } 539 }
479 540
480 return 0; 541 return 0;
@@ -485,8 +546,9 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
485 int ret; 546 int ret;
486 struct sk_buff *sskb; 547 struct sk_buff *sskb;
487 struct mac802154_sub_if_data *sdata; 548 struct mac802154_sub_if_data *sdata;
549 struct ieee802154_hdr hdr;
488 550
489 ret = mac802154_parse_frame_start(skb); 551 ret = mac802154_parse_frame_start(skb, &hdr);
490 if (ret) { 552 if (ret) {
491 pr_debug("got invalid frame\n"); 553 pr_debug("got invalid frame\n");
492 return; 554 return;
@@ -499,7 +561,7 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
499 561
500 sskb = skb_clone(skb, GFP_ATOMIC); 562 sskb = skb_clone(skb, GFP_ATOMIC);
501 if (sskb) 563 if (sskb)
502 mac802154_subif_frame(sdata, sskb); 564 mac802154_subif_frame(sdata, sskb, &hdr);
503 } 565 }
504 rcu_read_unlock(); 566 rcu_read_unlock();
505} 567}