#ifndef _NET80211_IEEE80211_CRYPTO_H_
#define _NET80211_IEEE80211_CRYPTO_H_
#define IEEE80211_KEYBUF_SIZE 16
#define IEEE80211_MICBUF_SIZE (8+8)
struct ieee80211_wepkey {
u_int wk_len;
uint8_t wk_key[IEEE80211_KEYBUF_SIZE];
};
struct ieee80211_rsnparms {
uint8_t rsn_mcastcipher;
uint8_t rsn_mcastkeylen;
uint8_t rsn_ucastcipher;
uint8_t rsn_ucastkeylen;
uint8_t rsn_keymgmt;
uint16_t rsn_caps;
};
struct ieee80211_cipher;
typedef uint16_t ieee80211_keyix;
struct ieee80211_key {
uint8_t wk_keylen;
uint8_t wk_pad;
uint16_t wk_flags;
#define IEEE80211_KEY_XMIT 0x0001
#define IEEE80211_KEY_RECV 0x0002
#define IEEE80211_KEY_GROUP 0x0004
#define IEEE80211_KEY_NOREPLAY 0x0008
#define IEEE80211_KEY_SWENCRYPT 0x0010
#define IEEE80211_KEY_SWDECRYPT 0x0020
#define IEEE80211_KEY_SWENMIC 0x0040
#define IEEE80211_KEY_SWDEMIC 0x0080
#define IEEE80211_KEY_DEVKEY 0x0100
#define IEEE80211_KEY_CIPHER0 0x1000
#define IEEE80211_KEY_CIPHER1 0x2000
ieee80211_keyix wk_keyix;
ieee80211_keyix wk_rxkeyix;
uint8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
#define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0
#define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8
uint64_t wk_keyrsc[IEEE80211_TID_SIZE];
uint64_t wk_keytsc;
const struct ieee80211_cipher *wk_cipher;
void *wk_private;
uint8_t wk_macaddr[IEEE80211_ADDR_LEN];
};
#define IEEE80211_KEY_COMMON \
(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \
IEEE80211_KEY_NOREPLAY)
#define IEEE80211_KEY_DEVICE \
(IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1)
#define IEEE80211_KEY_SWCRYPT \
(IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT)
#define IEEE80211_KEY_SWMIC (IEEE80211_KEY_SWENMIC | IEEE80211_KEY_SWDEMIC)
#define IEEE80211_KEY_BITS \
"\20\1XMIT\2RECV\3GROUP\4SWENCRYPT\5SWDECRYPT\6SWENMIC\7SWDEMIC" \
"\10DEVKEY\11CIPHER0\12CIPHER1"
#define IEEE80211_KEYIX_NONE ((ieee80211_keyix) -1)
#define IEEE80211_CIPHER_WEP 0
#define IEEE80211_CIPHER_TKIP 1
#define IEEE80211_CIPHER_AES_OCB 2
#define IEEE80211_CIPHER_AES_CCM 3
#define IEEE80211_CIPHER_TKIPMIC 4
#define IEEE80211_CIPHER_CKIP 5
#define IEEE80211_CIPHER_NONE 6
#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
#define IEEE80211_CRYPTO_WEP (1<<IEEE80211_CIPHER_WEP)
#define IEEE80211_CRYPTO_TKIP (1<<IEEE80211_CIPHER_TKIP)
#define IEEE80211_CRYPTO_AES_OCB (1<<IEEE80211_CIPHER_AES_OCB)
#define IEEE80211_CRYPTO_AES_CCM (1<<IEEE80211_CIPHER_AES_CCM)
#define IEEE80211_CRYPTO_TKIPMIC (1<<IEEE80211_CIPHER_TKIPMIC)
#define IEEE80211_CRYPTO_CKIP (1<<IEEE80211_CIPHER_CKIP)
#define IEEE80211_CRYPTO_BITS \
"\20\1WEP\2TKIP\3AES\4AES_CCM\5TKIPMIC\6CKIP"
#if defined(__KERNEL__) || defined(_KERNEL)
struct ieee80211com;
struct ieee80211vap;
struct ieee80211_node;
struct mbuf;
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_80211_CRYPTO);
#endif
void ieee80211_crypto_attach(struct ieee80211com *);
void ieee80211_crypto_detach(struct ieee80211com *);
void ieee80211_crypto_vattach(struct ieee80211vap *);
void ieee80211_crypto_vdetach(struct ieee80211vap *);
int ieee80211_crypto_newkey(struct ieee80211vap *,
int cipher, int flags, struct ieee80211_key *);
int ieee80211_crypto_delkey(struct ieee80211vap *,
struct ieee80211_key *);
int ieee80211_crypto_setkey(struct ieee80211vap *, struct ieee80211_key *);
void ieee80211_crypto_delglobalkeys(struct ieee80211vap *);
void ieee80211_crypto_reload_keys(struct ieee80211com *);
struct ieee80211_cipher {
const char *ic_name;
u_int ic_cipher;
u_int ic_header;
u_int ic_trailer;
u_int ic_miclen;
void* (*ic_attach)(struct ieee80211vap *, struct ieee80211_key *);
void (*ic_detach)(struct ieee80211_key *);
int (*ic_setkey)(struct ieee80211_key *);
void (*ic_setiv)(struct ieee80211_key *, uint8_t *);
int (*ic_encap)(struct ieee80211_key *, struct mbuf *);
int (*ic_decap)(struct ieee80211_key *, struct mbuf *, int);
int (*ic_enmic)(struct ieee80211_key *, struct mbuf *, int);
int (*ic_demic)(struct ieee80211_key *, struct mbuf *, int);
};
extern const struct ieee80211_cipher ieee80211_cipher_none;
#define IEEE80211_KEY_UNDEFINED(k) \
((k)->wk_cipher == &ieee80211_cipher_none)
void ieee80211_crypto_register(const struct ieee80211_cipher *);
void ieee80211_crypto_unregister(const struct ieee80211_cipher *);
int ieee80211_crypto_available(u_int cipher);
uint8_t ieee80211_crypto_get_keyid(struct ieee80211vap *vap,
struct ieee80211_key *k);
struct ieee80211_key *ieee80211_crypto_get_txkey(struct ieee80211_node *,
struct mbuf *);
struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *,
struct mbuf *);
struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *,
struct mbuf *, int);
static __inline int
ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
struct mbuf *m, int force)
{
const struct ieee80211_cipher *cip = k->wk_cipher;
return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
}
static __inline int
ieee80211_crypto_enmic(struct ieee80211vap *vap,
struct ieee80211_key *k, struct mbuf *m, int force)
{
const struct ieee80211_cipher *cip = k->wk_cipher;
return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m, force) : 1);
}
static __inline void
ieee80211_crypto_resetkey(struct ieee80211vap *vap,
struct ieee80211_key *k, ieee80211_keyix ix)
{
k->wk_cipher = &ieee80211_cipher_none;
k->wk_private = k->wk_cipher->ic_attach(vap, k);
k->wk_keyix = k->wk_rxkeyix = ix;
k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
}
void ieee80211_notify_replay_failure(struct ieee80211vap *,
const struct ieee80211_frame *, const struct ieee80211_key *,
uint64_t rsc, int tid);
void ieee80211_notify_michael_failure(struct ieee80211vap *,
const struct ieee80211_frame *, u_int keyix);
#endif
#endif