| 1 | --- a/src/drivers/driver_madwifi.c |
| 2 | +++ b/src/drivers/driver_madwifi.c |
| 3 | @@ -439,7 +439,11 @@ madwifi_set_key(const char *ifname, void |
| 4 | __func__, alg, ether_sprintf(addr), key_idx); |
| 5 | |
| 6 | if (alg == WPA_ALG_WEP) |
| 7 | + { |
| 8 | cipher = IEEE80211_CIPHER_WEP; |
| 9 | + if ((!addr || !memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN)) && drv->wext) |
| 10 | + return wpa_driver_wext_set_key(ifname, drv->wext, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); |
| 11 | + } |
| 12 | else if (alg == WPA_ALG_TKIP) |
| 13 | cipher = IEEE80211_CIPHER_TKIP; |
| 14 | else if (alg == WPA_ALG_CCMP) |
| 15 | @@ -458,20 +462,45 @@ madwifi_set_key(const char *ifname, void |
| 16 | |
| 17 | memset(&wk, 0, sizeof(wk)); |
| 18 | wk.ik_type = cipher; |
| 19 | - wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; |
| 20 | - if (addr == NULL || is_broadcast_ether_addr(addr)) { |
| 21 | - memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); |
| 22 | + wk.ik_flags = IEEE80211_KEY_RECV; |
| 23 | + if (set_tx) |
| 24 | + wk.ik_flags |= IEEE80211_KEY_XMIT; |
| 25 | + if (addr == NULL) { |
| 26 | + os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); |
| 27 | wk.ik_keyix = key_idx; |
| 28 | - wk.ik_flags |= IEEE80211_KEY_DEFAULT; |
| 29 | - } else if (!memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN)) { |
| 30 | - wk.ik_flags |= IEEE80211_KEY_GROUP; |
| 31 | - memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); |
| 32 | } else { |
| 33 | - memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); |
| 34 | - wk.ik_keyix = IEEE80211_KEYIX_NONE; |
| 35 | + os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); |
| 36 | + /* |
| 37 | + * Deduce whether group/global or unicast key by checking |
| 38 | + * the address (yech). Note also that we can only mark global |
| 39 | + * keys default; doing this for a unicast key is an error. |
| 40 | + */ |
| 41 | + if (os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", |
| 42 | + IEEE80211_ADDR_LEN) == 0) { |
| 43 | + wk.ik_flags |= IEEE80211_KEY_GROUP; |
| 44 | + wk.ik_keyix = key_idx; |
| 45 | + } else { |
| 46 | + wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE : |
| 47 | + key_idx; |
| 48 | + } |
| 49 | } |
| 50 | + if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) |
| 51 | + wk.ik_flags |= IEEE80211_KEY_DEFAULT; |
| 52 | wk.ik_keylen = key_len; |
| 53 | memcpy(wk.ik_keydata, key, key_len); |
| 54 | +#ifdef WORDS_BIGENDIAN |
| 55 | +#define WPA_KEY_RSC_LEN 8 |
| 56 | + { |
| 57 | + size_t i; |
| 58 | + u8 tmp[WPA_KEY_RSC_LEN]; |
| 59 | + os_memset(tmp, 0, sizeof(tmp)); |
| 60 | + for (i = 0; i < seq_len; i++) |
| 61 | + tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i]; |
| 62 | + os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN); |
| 63 | + } |
| 64 | +#else /* WORDS_BIGENDIAN */ |
| 65 | + os_memcpy(&wk.ik_keyrsc, seq, seq_len); |
| 66 | +#endif /* WORDS_BIGENDIAN */ |
| 67 | |
| 68 | ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); |
| 69 | if (ret < 0) { |
| 70 | |