?? ieee80211_crypto.c
字號:
/*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: ieee80211_crypto.c 1426 2006-02-01 20:07:11Z mrenzmann $ */#ifndef EXPORT_SYMTAB#define EXPORT_SYMTAB#endif/* * IEEE 802.11 generic crypto support. */#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/kmod.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/random.h>#include "if_ethersubr.h" /* XXX ETHER_HDR_LEN */#include "if_media.h"#include <net80211/ieee80211_var.h>/* * Table of registered cipher modules. */static const struct ieee80211_cipher *ciphers[IEEE80211_CIPHER_MAX];static int _ieee80211_crypto_delkey(struct ieee80211vap *, struct ieee80211_key *, struct ieee80211_node *);/* * Default "null" key management routines. */static intnull_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k){ return IEEE80211_KEYIX_NONE;}static intnull_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k, struct ieee80211_node *ni){ return 1;}static intnull_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, const u_int8_t mac[IEEE80211_ADDR_LEN]){ return 1;}static void null_key_update(struct ieee80211vap *vap){}#ifdef ATH_SUPERG_COMPstatic voidnull_comp_set(struct ieee80211vap *vap, struct ieee80211_node *ni, int en){}#endif/* * Write-arounds for common operations. */static __inline voidcipher_detach(struct ieee80211_key *key){ key->wk_cipher->ic_detach(key);}static __inline void *cipher_attach(struct ieee80211vap *vap, struct ieee80211_key *key){ return key->wk_cipher->ic_attach(vap, key);}/* * Wrappers for driver key management methods. */static __inline intdev_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *key){ return vap->iv_key_alloc(vap, key);}static __inline intdev_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *key, struct ieee80211_node *ni){ return vap->iv_key_delete(vap, key, ni);}static __inline intdev_key_set(struct ieee80211vap *vap, const struct ieee80211_key *key, const u_int8_t mac[IEEE80211_ADDR_LEN]){ return vap->iv_key_set(vap, key, mac);}#ifdef ATH_SUPERG_COMPstatic __inline voiddev_comp_set(struct ieee80211vap *vap, struct ieee80211_node *ni, int en){ return vap->iv_comp_set(vap, ni, en);}#endif/* * Setup crypto support for a device/shared instance. */voidieee80211_crypto_attach(struct ieee80211com *ic){ /* NB: we assume everything is pre-zero'd */ ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none;}EXPORT_SYMBOL(ieee80211_crypto_attach);/* * Teardown crypto support. */voidieee80211_crypto_detach(struct ieee80211com *ic){}EXPORT_SYMBOL(ieee80211_crypto_detach);/* * Setup crypto support for a vap. */voidieee80211_crypto_vattach(struct ieee80211vap *vap){ int i; /* NB: we assume everything is pre-zero'd */ vap->iv_def_txkey = IEEE80211_KEYIX_NONE; for (i = 0; i < IEEE80211_WEP_NKID; i++) ieee80211_crypto_resetkey(vap, &vap->iv_nw_keys[i], IEEE80211_KEYIX_NONE); /* * Initialize the driver key support routines to noop entries. * This is useful especially for the cipher test modules. */ vap->iv_key_alloc = null_key_alloc; vap->iv_key_set = null_key_set; vap->iv_key_delete = null_key_delete; vap->iv_key_update_begin = null_key_update; vap->iv_key_update_end = null_key_update;#ifdef ATH_SUPERG_COMP vap->iv_comp_set = null_comp_set;#endif}EXPORT_SYMBOL(ieee80211_crypto_vattach);/* * Teardown crypto support for a vap. */voidieee80211_crypto_vdetach(struct ieee80211vap *vap){ ieee80211_crypto_delglobalkeys(vap);}EXPORT_SYMBOL(ieee80211_crypto_vdetach);/* * Register a crypto cipher module. */voidieee80211_crypto_register(const struct ieee80211_cipher *cip){ if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { printf("%s: cipher %s has an invalid cipher index %u\n", __func__, cip->ic_name, cip->ic_cipher); return; } if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) { printf("%s: cipher %s registered with a different template\n", __func__, cip->ic_name); return; } ciphers[cip->ic_cipher] = cip;}EXPORT_SYMBOL(ieee80211_crypto_register);/* * Unregister a crypto cipher module. */voidieee80211_crypto_unregister(const struct ieee80211_cipher *cip){ if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { printf("%s: cipher %s has an invalid cipher index %u\n", __func__, cip->ic_name, cip->ic_cipher); return; } if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) { printf("%s: cipher %s registered with a different template\n", __func__, cip->ic_name); return; } /* NB: don't complain about not being registered */ /* XXX disallow if references */ ciphers[cip->ic_cipher] = NULL;}EXPORT_SYMBOL(ieee80211_crypto_unregister);intieee80211_crypto_available(u_int cipher){ return cipher < IEEE80211_CIPHER_MAX && ciphers[cipher] != NULL;}EXPORT_SYMBOL(ieee80211_crypto_available);/* XXX well-known names! */static const char *cipher_modnames[] = { "wlan_wep", /* IEEE80211_CIPHER_WEP */ "wlan_tkip", /* IEEE80211_CIPHER_TKIP */ "wlan_aes_ocb", /* IEEE80211_CIPHER_AES_OCB */ "wlan_ccmp", /* IEEE80211_CIPHER_AES_CCM */ "wlan_ckip", /* IEEE80211_CIPHER_CKIP */};/* * Establish a relationship between the specified key and cipher * and, if necessary, allocate a hardware index from the driver. * Note that when a fixed key index is required it must be specified * and we blindly assign it w/o consulting the driver (XXX). * * This must be the first call applied to a key; all the other key * routines assume wk_cipher is setup. * * Locking must be handled by the caller using: * ieee80211_key_update_begin(vap); * ieee80211_key_update_end(vap); */intieee80211_crypto_newkey(struct ieee80211vap *vap, int cipher, int flags, struct ieee80211_key *key){#define N(a) (sizeof(a) / sizeof(a[0])) const struct ieee80211_cipher *cip; void *keyctx; int oflags; /* * Validate cipher and set reference to cipher routines. */ if (cipher >= IEEE80211_CIPHER_MAX) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: invalid cipher %u\n", __func__, cipher); vap->iv_stats.is_crypto_badcipher++; return 0; } cip = ciphers[cipher]; if (cip == NULL) { /* * Auto-load cipher module if we have a well-known name * for it. It might be better to use string names rather * than numbers and craft a module name based on the cipher * name; e.g. wlan_cipher_<cipher-name>. */ if (cipher < N(cipher_modnames)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: unregistered cipher %u, load module %s\n", __func__, cipher, cipher_modnames[cipher]); ieee80211_load_module(cipher_modnames[cipher]); /* * If cipher module loaded it should immediately * call ieee80211_crypto_register which will fill * in the entry in the ciphers array. */ cip = ciphers[cipher]; } if (cip == NULL) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: unable to load cipher %u, module %s\n", __func__, cipher, cipher < N(cipher_modnames) ? cipher_modnames[cipher] : "<unknown>"); vap->iv_stats.is_crypto_nocipher++; return 0; } } oflags = key->wk_flags; flags &= IEEE80211_KEY_COMMON; /* * If the hardware does not support the cipher then * fallback to a host-based implementation. */ if ((vap->iv_caps & (1<<cipher)) == 0) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: no h/w support for cipher %s, falling back to s/w\n", __func__, cip->ic_name); flags |= IEEE80211_KEY_SWCRYPT; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -