Changeset View
Changeset View
Standalone View
Standalone View
sys/net80211/ieee80211_crypto.c
| Show All 35 Lines | |||||
| #include <sys/kernel.h> | #include <sys/kernel.h> | ||||
| #include <sys/malloc.h> | #include <sys/malloc.h> | ||||
| #include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||
| #include <net/if.h> | #include <net/if.h> | ||||
| #include <net/if_media.h> | #include <net/if_media.h> | ||||
| #include <net/if_var.h> /* ic_printf */ | |||||
| #include <net/ethernet.h> /* XXX ETHER_HDR_LEN */ | #include <net/ethernet.h> /* XXX ETHER_HDR_LEN */ | ||||
| #include <net80211/ieee80211_var.h> | #include <net80211/ieee80211_var.h> | ||||
| MALLOC_DEFINE(M_80211_CRYPTO, "80211crypto", "802.11 crypto state"); | MALLOC_DEFINE(M_80211_CRYPTO, "80211crypto", "802.11 crypto state"); | ||||
| static int _ieee80211_crypto_delkey(struct ieee80211vap *, | static int _ieee80211_crypto_delkey(struct ieee80211vap *, | ||||
| struct ieee80211_key *); | struct ieee80211_key *); | ||||
| ▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | |||||
| void | void | ||||
| ieee80211_crypto_vattach(struct ieee80211vap *vap) | ieee80211_crypto_vattach(struct ieee80211vap *vap) | ||||
| { | { | ||||
| int i; | int i; | ||||
| /* NB: we assume everything is pre-zero'd */ | /* NB: we assume everything is pre-zero'd */ | ||||
| vap->iv_max_keyix = IEEE80211_WEP_NKID; | vap->iv_max_keyix = IEEE80211_WEP_NKID; | ||||
| vap->iv_def_txkey = IEEE80211_KEYIX_NONE; | vap->iv_def_txkey = IEEE80211_KEYIX_NONE; | ||||
| for (i = 0; i < IEEE80211_WEP_NKID; i++) | |||||
| for (i = 0; i < IEEE80211_MAX_NKID; i++) | |||||
| ieee80211_crypto_resetkey(vap, &vap->iv_nw_keys[i], | ieee80211_crypto_resetkey(vap, &vap->iv_nw_keys[i], | ||||
| IEEE80211_KEYIX_NONE); | IEEE80211_KEYIX_NONE); | ||||
| /* | /* | ||||
| * Initialize the driver key support routines to noop entries. | * Initialize the driver key support routines to noop entries. | ||||
| * This is useful especially for the cipher test modules. | * This is useful especially for the cipher test modules. | ||||
| */ | */ | ||||
| vap->iv_key_alloc = null_key_alloc; | vap->iv_key_alloc = null_key_alloc; | ||||
| vap->iv_key_set = null_key_set; | vap->iv_key_set = null_key_set; | ||||
| vap->iv_key_delete = null_key_delete; | vap->iv_key_delete = null_key_delete; | ||||
| vap->iv_key_update_begin = null_key_update; | vap->iv_key_update_begin = null_key_update; | ||||
| ▲ Show 20 Lines • Show All 296 Lines • ▼ Show 20 Lines | |||||
| * Clear the global key table. | * Clear the global key table. | ||||
| */ | */ | ||||
| void | void | ||||
| ieee80211_crypto_delglobalkeys(struct ieee80211vap *vap) | ieee80211_crypto_delglobalkeys(struct ieee80211vap *vap) | ||||
| { | { | ||||
| int i; | int i; | ||||
| ieee80211_key_update_begin(vap); | ieee80211_key_update_begin(vap); | ||||
| for (i = 0; i < IEEE80211_WEP_NKID; i++) | for (i = 0; i < IEEE80211_MAX_NKID; i++) | ||||
| (void) _ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[i]); | (void) _ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[i]); | ||||
| ieee80211_key_update_end(vap); | ieee80211_key_update_end(vap); | ||||
| } | } | ||||
| /* | /* | ||||
| * Set the contents of the specified key. | * Set the contents of the specified key. | ||||
| * | * | ||||
| * Locking must be handled by the caller using: | * Locking must be handled by the caller using: | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | ieee80211_crypto_get_key_wepidx(const struct ieee80211vap *vap, | ||||
| if (ieee80211_is_key_global(vap, k)) { | if (ieee80211_is_key_global(vap, k)) { | ||||
| return (k - vap->iv_nw_keys); | return (k - vap->iv_nw_keys); | ||||
| } | } | ||||
| return (-1); | return (-1); | ||||
| } | } | ||||
| /* | /* | ||||
| * Return index if the key is an IGTK key (4..5); -1 otherwise. | |||||
| * | |||||
| * This is different to "get_keyid" which defaults to returning | |||||
| * 0 for unicast keys; it assumes that it won't be used for WEP. | |||||
| */ | |||||
| int | |||||
| ieee80211_crypto_get_key_igtk_idx(const struct ieee80211vap *vap, | |||||
| const struct ieee80211_key *k) | |||||
| { | |||||
| if (ieee80211_is_key_igtk(vap, k)) { | |||||
| /* XXX TODO: i hate this */ | |||||
| return (k - vap->iv_nw_keys); | |||||
| } | |||||
| return (-1); | |||||
| } | |||||
| /* | |||||
| * Return the group or unicast key. | |||||
| * | |||||
| * Don't call this for IGTK keyx! | |||||
| * | |||||
| * Note: only supports a single unicast key (0). | * Note: only supports a single unicast key (0). | ||||
| */ | */ | ||||
| uint8_t | uint8_t | ||||
| ieee80211_crypto_get_keyid(struct ieee80211vap *vap, struct ieee80211_key *k) | ieee80211_crypto_get_keyid(struct ieee80211vap *vap, struct ieee80211_key *k) | ||||
| { | { | ||||
| if (ieee80211_is_key_global(vap, k)) { | if (ieee80211_is_key_global(vap, k)) { | ||||
| return (k - vap->iv_nw_keys); | return (k - vap->iv_nw_keys); | ||||
| } | } | ||||
| /* | |||||
| * TODO: I wish this function could return an error, | |||||
| * but then I'd have to audit all the places that called it | |||||
| * and make sure THEY can handle the error! | |||||
| */ | |||||
| if (ieee80211_is_key_igtk(vap, k)) { | |||||
| if_printf(vap->iv_ifp, "%s: IGTK key passed in! Invalid!\n", | |||||
| __func__); | |||||
| } | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| struct ieee80211_key * | struct ieee80211_key * | ||||
| ieee80211_crypto_get_txkey(struct ieee80211_node *ni, struct mbuf *m) | ieee80211_crypto_get_txkey(struct ieee80211_node *ni, struct mbuf *m) | ||||
| { | { | ||||
| struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
| struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
| ▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | ieee80211_crypto_reload_keys(struct ieee80211com *ic) | ||||
| /* | /* | ||||
| * Keys in the global key table of each vap. | * Keys in the global key table of each vap. | ||||
| */ | */ | ||||
| /* NB: used only during resume so don't lock for now */ | /* NB: used only during resume so don't lock for now */ | ||||
| TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { | TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { | ||||
| if (vap->iv_state != IEEE80211_S_RUN) | if (vap->iv_state != IEEE80211_S_RUN) | ||||
| continue; | continue; | ||||
| /* Global/WEP keys */ | |||||
| for (i = 0; i < IEEE80211_WEP_NKID; i++) { | for (i = 0; i < IEEE80211_WEP_NKID; i++) { | ||||
| const struct ieee80211_key *k = &vap->iv_nw_keys[i]; | const struct ieee80211_key *k = &vap->iv_nw_keys[i]; | ||||
| if (k->wk_flags & IEEE80211_KEY_DEVKEY) | if (k->wk_flags & IEEE80211_KEY_DEVKEY) | ||||
| dev_key_set(vap, k); | dev_key_set(vap, k); | ||||
| } | } | ||||
| /* TODO: do the two iGTK keys too if the driver supports it? */ | |||||
| /* (The drivers will need to be made aware of the other two KIDs and ignore them if needed..) */ | |||||
| } | } | ||||
| /* | /* | ||||
| * Unicast keys. | * Unicast keys. | ||||
| */ | */ | ||||
| ieee80211_iterate_nodes(&ic->ic_sta, load_ucastkey, NULL); | ieee80211_iterate_nodes(&ic->ic_sta, load_ucastkey, NULL); | ||||
| } | } | ||||
| /* | /* | ||||
| Show All 30 Lines | |||||