Lines Matching +full:tx +full:- +full:sec

1 // SPDX-License-Identifier: GPL-2.0-only
4 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
7 Host AP project hostap-drivers v0.1.3
8 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
10 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
15 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
36 return jiffies_to_msecs(end - start); in elapsed_jiffies_msecs()
38 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); in elapsed_jiffies_msecs()
57 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); in libipw_translate_scan()
65 iwe.u.data.length = min(network->ssid_len, (u8) 32); in libipw_translate_scan()
67 &iwe, network->ssid); in libipw_translate_scan()
72 libipw_modes[network->mode]); in libipw_translate_scan()
77 if (network->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { in libipw_translate_scan()
78 if (network->capability & WLAN_CAPABILITY_ESS) in libipw_translate_scan()
90 iwe.u.freq.m = libipw_channel_to_freq(ieee, network->channel); in libipw_translate_scan()
97 if (network->capability & WLAN_CAPABILITY_PRIVACY) in libipw_translate_scan()
103 &iwe, network->ssid); in libipw_translate_scan()
107 * more of magic - Jean II */ in libipw_translate_scan()
113 for (i = 0, j = 0; i < network->rates_len;) { in libipw_translate_scan()
114 if (j < network->rates_ex_len && in libipw_translate_scan()
115 ((network->rates_ex[j] & 0x7F) < in libipw_translate_scan()
116 (network->rates[i] & 0x7F))) in libipw_translate_scan()
117 rate = network->rates_ex[j++] & 0x7F; in libipw_translate_scan()
119 rate = network->rates[i++] & 0x7F; in libipw_translate_scan()
126 for (; j < network->rates_ex_len; j++) { in libipw_translate_scan()
127 rate = network->rates_ex[j] & 0x7F; in libipw_translate_scan()
135 if ((current_val - start) > iwe_stream_lcp_len(info)) in libipw_translate_scan()
143 if (!(network->stats.mask & LIBIPW_STATMASK_RSSI)) { in libipw_translate_scan()
148 if (ieee->perfect_rssi == ieee->worst_rssi) in libipw_translate_scan()
153 (ieee->perfect_rssi - ieee->worst_rssi) * in libipw_translate_scan()
154 (ieee->perfect_rssi - ieee->worst_rssi) - in libipw_translate_scan()
155 (ieee->perfect_rssi - network->stats.rssi) * in libipw_translate_scan()
156 (15 * (ieee->perfect_rssi - ieee->worst_rssi) + in libipw_translate_scan()
157 62 * (ieee->perfect_rssi - in libipw_translate_scan()
158 network->stats.rssi))) / in libipw_translate_scan()
159 ((ieee->perfect_rssi - in libipw_translate_scan()
160 ieee->worst_rssi) * (ieee->perfect_rssi - in libipw_translate_scan()
161 ieee->worst_rssi)); in libipw_translate_scan()
168 if (!(network->stats.mask & LIBIPW_STATMASK_NOISE)) { in libipw_translate_scan()
172 iwe.u.qual.noise = network->stats.noise; in libipw_translate_scan()
175 if (!(network->stats.mask & LIBIPW_STATMASK_SIGNAL)) { in libipw_translate_scan()
179 iwe.u.qual.level = network->stats.signal; in libipw_translate_scan()
187 iwe.u.data.length = p - custom; in libipw_translate_scan()
192 if (network->wpa_ie_len) { in libipw_translate_scan()
194 memcpy(buf, network->wpa_ie, network->wpa_ie_len); in libipw_translate_scan()
196 iwe.u.data.length = network->wpa_ie_len; in libipw_translate_scan()
201 if (network->rsn_ie_len) { in libipw_translate_scan()
203 memcpy(buf, network->rsn_ie, network->rsn_ie_len); in libipw_translate_scan()
205 iwe.u.data.length = network->rsn_ie_len; in libipw_translate_scan()
213 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), in libipw_translate_scan()
215 elapsed_jiffies_msecs(network->last_scanned)); in libipw_translate_scan()
216 iwe.u.data.length = p - custom; in libipw_translate_scan()
221 iwe.cmd = -1; in libipw_translate_scan()
223 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: "); in libipw_translate_scan()
225 if (libipw_get_channel_flags(ieee, network->channel) & in libipw_translate_scan()
228 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID "); in libipw_translate_scan()
231 if (libipw_get_channel_flags(ieee, network->channel) & in libipw_translate_scan()
234 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS "); in libipw_translate_scan()
238 iwe.u.data.length = p - custom; in libipw_translate_scan()
256 char *stop = ev + wrqu->data.length; in libipw_wx_get_scan()
261 spin_lock_irqsave(&ieee->lock, flags); in libipw_wx_get_scan()
263 list_for_each_entry(network, &ieee->network_list, list) { in libipw_wx_get_scan()
265 if (stop - ev < SCAN_ITEM_SIZE) { in libipw_wx_get_scan()
266 err = -E2BIG; in libipw_wx_get_scan()
270 if (ieee->scan_age == 0 || in libipw_wx_get_scan()
271 time_after(network->last_scanned + ieee->scan_age, jiffies)) in libipw_wx_get_scan()
276 network->ssid_len, network->ssid, in libipw_wx_get_scan()
277 network->bssid, in libipw_wx_get_scan()
279 network->last_scanned)); in libipw_wx_get_scan()
283 spin_unlock_irqrestore(&ieee->lock, flags); in libipw_wx_get_scan()
285 wrqu->data.length = ev - extra; in libipw_wx_get_scan()
286 wrqu->data.flags = 0; in libipw_wx_get_scan()
297 struct iw_point *erq = &(wrqu->encoding); in libipw_wx_set_encode()
298 struct net_device *dev = ieee->dev; in libipw_wx_set_encode()
299 struct libipw_security sec = { in libipw_wx_set_encode() local
304 int host_crypto = ieee->host_encrypt || ieee->host_decrypt; in libipw_wx_set_encode()
308 key = erq->flags & IW_ENCODE_INDEX; in libipw_wx_set_encode()
311 return -EINVAL; in libipw_wx_set_encode()
312 key--; in libipw_wx_set_encode()
316 key = ieee->crypt_info.tx_keyidx; in libipw_wx_set_encode()
322 crypt = &ieee->crypt_info.crypt[key]; in libipw_wx_set_encode()
324 if (erq->flags & IW_ENCODE_DISABLED) { in libipw_wx_set_encode()
328 libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt); in libipw_wx_set_encode()
333 * and if no key index was provided, de-init them all */ in libipw_wx_set_encode()
335 if (ieee->crypt_info.crypt[i] != NULL) { in libipw_wx_set_encode()
338 libipw_crypt_delayed_deinit(&ieee->crypt_info, in libipw_wx_set_encode()
339 &ieee->crypt_info.crypt[i]); in libipw_wx_set_encode()
344 sec.enabled = 0; in libipw_wx_set_encode()
345 sec.encrypt = 0; in libipw_wx_set_encode()
346 sec.level = SEC_LEVEL_0; in libipw_wx_set_encode()
347 sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT; in libipw_wx_set_encode()
353 sec.enabled = 1; in libipw_wx_set_encode()
354 sec.encrypt = 1; in libipw_wx_set_encode()
355 sec.flags |= SEC_ENABLED | SEC_ENCRYPT; in libipw_wx_set_encode()
357 if (*crypt != NULL && (*crypt)->ops != NULL && in libipw_wx_set_encode()
358 strcmp((*crypt)->ops->name, "WEP") != 0) { in libipw_wx_set_encode()
361 libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt); in libipw_wx_set_encode()
371 return -ENOMEM; in libipw_wx_set_encode()
372 new_crypt->ops = libipw_get_crypto_ops("WEP"); in libipw_wx_set_encode()
373 if (!new_crypt->ops) { in libipw_wx_set_encode()
375 new_crypt->ops = libipw_get_crypto_ops("WEP"); in libipw_wx_set_encode()
378 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) in libipw_wx_set_encode()
379 new_crypt->priv = new_crypt->ops->init(key); in libipw_wx_set_encode()
381 if (!new_crypt->ops || !new_crypt->priv) { in libipw_wx_set_encode()
386 "load module libipw_crypt_wep\n", dev->name); in libipw_wx_set_encode()
387 return -EOPNOTSUPP; in libipw_wx_set_encode()
393 if (erq->length > 0) { in libipw_wx_set_encode()
394 len = erq->length <= 5 ? 5 : 13; in libipw_wx_set_encode()
395 memcpy(sec.keys[key], keybuf, erq->length); in libipw_wx_set_encode()
396 if (len > erq->length) in libipw_wx_set_encode()
397 memset(sec.keys[key] + erq->length, 0, in libipw_wx_set_encode()
398 len - erq->length); in libipw_wx_set_encode()
400 key, len, sec.keys[key], in libipw_wx_set_encode()
401 erq->length, len); in libipw_wx_set_encode()
402 sec.key_sizes[key] = len; in libipw_wx_set_encode()
404 (*crypt)->ops->set_key(sec.keys[key], len, NULL, in libipw_wx_set_encode()
405 (*crypt)->priv); in libipw_wx_set_encode()
406 sec.flags |= (1 << key); in libipw_wx_set_encode()
409 if (key == sec.active_key) in libipw_wx_set_encode()
410 sec.flags |= SEC_ACTIVE_KEY; in libipw_wx_set_encode()
414 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, in libipw_wx_set_encode()
415 NULL, (*crypt)->priv); in libipw_wx_set_encode()
420 memset(sec.keys[key], 0, 13); in libipw_wx_set_encode()
421 (*crypt)->ops->set_key(sec.keys[key], 13, NULL, in libipw_wx_set_encode()
422 (*crypt)->priv); in libipw_wx_set_encode()
423 sec.key_sizes[key] = 13; in libipw_wx_set_encode()
424 sec.flags |= (1 << key); in libipw_wx_set_encode()
427 /* No key data - just set the default TX key index */ in libipw_wx_set_encode()
429 LIBIPW_DEBUG_WX("Setting key %d to default Tx " in libipw_wx_set_encode()
431 ieee->crypt_info.tx_keyidx = key; in libipw_wx_set_encode()
432 sec.active_key = key; in libipw_wx_set_encode()
433 sec.flags |= SEC_ACTIVE_KEY; in libipw_wx_set_encode()
436 if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) { in libipw_wx_set_encode()
437 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); in libipw_wx_set_encode()
438 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : in libipw_wx_set_encode()
440 sec.flags |= SEC_AUTH_MODE; in libipw_wx_set_encode()
442 sec.auth_mode == WLAN_AUTH_OPEN ? in libipw_wx_set_encode()
448 sec.flags |= SEC_LEVEL; in libipw_wx_set_encode()
449 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ in libipw_wx_set_encode()
450 sec.encode_alg[key] = SEC_ALG_WEP; in libipw_wx_set_encode()
453 if (ieee->set_security) in libipw_wx_set_encode()
454 ieee->set_security(dev, &sec); in libipw_wx_set_encode()
463 struct iw_point *erq = &(wrqu->encoding); in libipw_wx_get_encode()
465 struct libipw_security *sec = &ieee->sec; in libipw_wx_get_encode() local
469 key = erq->flags & IW_ENCODE_INDEX; in libipw_wx_get_encode()
472 return -EINVAL; in libipw_wx_get_encode()
473 key--; in libipw_wx_get_encode()
475 key = ieee->crypt_info.tx_keyidx; in libipw_wx_get_encode()
477 erq->flags = key + 1; in libipw_wx_get_encode()
479 if (!sec->enabled) { in libipw_wx_get_encode()
480 erq->length = 0; in libipw_wx_get_encode()
481 erq->flags |= IW_ENCODE_DISABLED; in libipw_wx_get_encode()
485 len = sec->key_sizes[key]; in libipw_wx_get_encode()
486 memcpy(keybuf, sec->keys[key], len); in libipw_wx_get_encode()
488 erq->length = len; in libipw_wx_get_encode()
489 erq->flags |= IW_ENCODE_ENABLED; in libipw_wx_get_encode()
491 if (ieee->open_wep) in libipw_wx_get_encode()
492 erq->flags |= IW_ENCODE_OPEN; in libipw_wx_get_encode()
494 erq->flags |= IW_ENCODE_RESTRICTED; in libipw_wx_get_encode()
503 struct net_device *dev = ieee->dev; in libipw_wx_set_encodeext()
504 struct iw_point *encoding = &wrqu->encoding; in libipw_wx_set_encodeext()
512 struct libipw_security sec = { in libipw_wx_set_encodeext() local
516 idx = encoding->flags & IW_ENCODE_INDEX; in libipw_wx_set_encodeext()
519 return -EINVAL; in libipw_wx_set_encodeext()
520 idx--; in libipw_wx_set_encodeext()
522 idx = ieee->crypt_info.tx_keyidx; in libipw_wx_set_encodeext()
524 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { in libipw_wx_set_encodeext()
525 crypt = &ieee->crypt_info.crypt[idx]; in libipw_wx_set_encodeext()
529 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) in libipw_wx_set_encodeext()
530 return -EINVAL; in libipw_wx_set_encodeext()
531 if (ieee->iw_mode == IW_MODE_INFRA) in libipw_wx_set_encodeext()
532 crypt = &ieee->crypt_info.crypt[idx]; in libipw_wx_set_encodeext()
534 return -EINVAL; in libipw_wx_set_encodeext()
537 sec.flags |= SEC_ENABLED | SEC_ENCRYPT; in libipw_wx_set_encodeext()
538 if ((encoding->flags & IW_ENCODE_DISABLED) || in libipw_wx_set_encodeext()
539 ext->alg == IW_ENCODE_ALG_NONE) { in libipw_wx_set_encodeext()
541 libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt); in libipw_wx_set_encodeext()
544 if (ieee->crypt_info.crypt[i] != NULL) in libipw_wx_set_encodeext()
548 sec.enabled = 0; in libipw_wx_set_encodeext()
549 sec.encrypt = 0; in libipw_wx_set_encodeext()
550 sec.level = SEC_LEVEL_0; in libipw_wx_set_encodeext()
551 sec.flags |= SEC_LEVEL; in libipw_wx_set_encodeext()
556 sec.enabled = 1; in libipw_wx_set_encodeext()
557 sec.encrypt = 1; in libipw_wx_set_encodeext()
559 if (group_key ? !ieee->host_mc_decrypt : in libipw_wx_set_encodeext()
560 !(ieee->host_encrypt || ieee->host_decrypt || in libipw_wx_set_encodeext()
561 ieee->host_encrypt_msdu)) in libipw_wx_set_encodeext()
564 switch (ext->alg) { in libipw_wx_set_encodeext()
579 dev->name, ext->alg); in libipw_wx_set_encodeext()
580 ret = -EINVAL; in libipw_wx_set_encodeext()
591 dev->name, ext->alg); in libipw_wx_set_encodeext()
592 ret = -EINVAL; in libipw_wx_set_encodeext()
596 if (*crypt == NULL || (*crypt)->ops != ops) { in libipw_wx_set_encodeext()
599 libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt); in libipw_wx_set_encodeext()
603 ret = -ENOMEM; in libipw_wx_set_encodeext()
606 new_crypt->ops = ops; in libipw_wx_set_encodeext()
607 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) in libipw_wx_set_encodeext()
608 new_crypt->priv = new_crypt->ops->init(idx); in libipw_wx_set_encodeext()
609 if (new_crypt->priv == NULL) { in libipw_wx_set_encodeext()
611 ret = -EINVAL; in libipw_wx_set_encodeext()
617 if (ext->key_len > 0 && (*crypt)->ops->set_key && in libipw_wx_set_encodeext()
618 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, in libipw_wx_set_encodeext()
619 (*crypt)->priv) < 0) { in libipw_wx_set_encodeext()
620 LIBIPW_DEBUG_WX("%s: key setting failed\n", dev->name); in libipw_wx_set_encodeext()
621 ret = -EINVAL; in libipw_wx_set_encodeext()
626 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { in libipw_wx_set_encodeext()
627 ieee->crypt_info.tx_keyidx = idx; in libipw_wx_set_encodeext()
628 sec.active_key = idx; in libipw_wx_set_encodeext()
629 sec.flags |= SEC_ACTIVE_KEY; in libipw_wx_set_encodeext()
632 if (ext->alg != IW_ENCODE_ALG_NONE) { in libipw_wx_set_encodeext()
633 int key_len = clamp_val(ext->key_len, 0, SCM_KEY_LEN); in libipw_wx_set_encodeext()
635 memcpy(sec.keys[idx], ext->key, key_len); in libipw_wx_set_encodeext()
636 sec.key_sizes[idx] = key_len; in libipw_wx_set_encodeext()
637 sec.flags |= (1 << idx); in libipw_wx_set_encodeext()
638 if (ext->alg == IW_ENCODE_ALG_WEP) { in libipw_wx_set_encodeext()
639 sec.encode_alg[idx] = SEC_ALG_WEP; in libipw_wx_set_encodeext()
640 sec.flags |= SEC_LEVEL; in libipw_wx_set_encodeext()
641 sec.level = SEC_LEVEL_1; in libipw_wx_set_encodeext()
642 } else if (ext->alg == IW_ENCODE_ALG_TKIP) { in libipw_wx_set_encodeext()
643 sec.encode_alg[idx] = SEC_ALG_TKIP; in libipw_wx_set_encodeext()
644 sec.flags |= SEC_LEVEL; in libipw_wx_set_encodeext()
645 sec.level = SEC_LEVEL_2; in libipw_wx_set_encodeext()
646 } else if (ext->alg == IW_ENCODE_ALG_CCMP) { in libipw_wx_set_encodeext()
647 sec.encode_alg[idx] = SEC_ALG_CCMP; in libipw_wx_set_encodeext()
648 sec.flags |= SEC_LEVEL; in libipw_wx_set_encodeext()
649 sec.level = SEC_LEVEL_3; in libipw_wx_set_encodeext()
651 /* Don't set sec level for group keys. */ in libipw_wx_set_encodeext()
653 sec.flags &= ~SEC_LEVEL; in libipw_wx_set_encodeext()
656 if (ieee->set_security) in libipw_wx_set_encodeext()
657 ieee->set_security(dev, &sec); in libipw_wx_set_encodeext()
666 struct iw_point *encoding = &wrqu->encoding; in libipw_wx_get_encodeext()
668 struct libipw_security *sec = &ieee->sec; in libipw_wx_get_encodeext() local
671 max_key_len = encoding->length - sizeof(*ext); in libipw_wx_get_encodeext()
673 return -EINVAL; in libipw_wx_get_encodeext()
675 idx = encoding->flags & IW_ENCODE_INDEX; in libipw_wx_get_encodeext()
678 return -EINVAL; in libipw_wx_get_encodeext()
679 idx--; in libipw_wx_get_encodeext()
681 idx = ieee->crypt_info.tx_keyidx; in libipw_wx_get_encodeext()
683 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && in libipw_wx_get_encodeext()
684 ext->alg != IW_ENCODE_ALG_WEP) in libipw_wx_get_encodeext()
685 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) in libipw_wx_get_encodeext()
686 return -EINVAL; in libipw_wx_get_encodeext()
688 encoding->flags = idx + 1; in libipw_wx_get_encodeext()
691 if (!sec->enabled) { in libipw_wx_get_encodeext()
692 ext->alg = IW_ENCODE_ALG_NONE; in libipw_wx_get_encodeext()
693 ext->key_len = 0; in libipw_wx_get_encodeext()
694 encoding->flags |= IW_ENCODE_DISABLED; in libipw_wx_get_encodeext()
696 if (sec->encode_alg[idx] == SEC_ALG_WEP) in libipw_wx_get_encodeext()
697 ext->alg = IW_ENCODE_ALG_WEP; in libipw_wx_get_encodeext()
698 else if (sec->encode_alg[idx] == SEC_ALG_TKIP) in libipw_wx_get_encodeext()
699 ext->alg = IW_ENCODE_ALG_TKIP; in libipw_wx_get_encodeext()
700 else if (sec->encode_alg[idx] == SEC_ALG_CCMP) in libipw_wx_get_encodeext()
701 ext->alg = IW_ENCODE_ALG_CCMP; in libipw_wx_get_encodeext()
703 return -EINVAL; in libipw_wx_get_encodeext()
705 ext->key_len = sec->key_sizes[idx]; in libipw_wx_get_encodeext()
706 memcpy(ext->key, sec->keys[idx], ext->key_len); in libipw_wx_get_encodeext()
707 encoding->flags |= IW_ENCODE_ENABLED; in libipw_wx_get_encodeext()
708 if (ext->key_len && in libipw_wx_get_encodeext()
709 (ext->alg == IW_ENCODE_ALG_TKIP || in libipw_wx_get_encodeext()
710 ext->alg == IW_ENCODE_ALG_CCMP)) in libipw_wx_get_encodeext()
711 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; in libipw_wx_get_encodeext()