#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;
u_int8_t wk_key[IEEE80211_KEYBUF_SIZE];
};
struct ieee80211_cipher;
typedef u_int16_t ieee80211_keyix;
struct ieee80211_key {
u_int8_t wk_keylen;
u_int8_t wk_pad;
u_int16_t wk_flags;
#define IEEE80211_KEY_XMIT 0x01
#define IEEE80211_KEY_RECV 0x02
#define IEEE80211_KEY_GROUP 0x04
#define IEEE80211_KEY_SWCRYPT 0x10
#define IEEE80211_KEY_SWMIC 0x20
ieee80211_keyix wk_keyix;
ieee80211_keyix wk_rxkeyix;
u_int8_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
u_int64_t wk_keyrsc;
u_int64_t wk_keytsc;
const struct ieee80211_cipher *wk_cipher;
void *wk_private;
};
#define IEEE80211_KEY_COMMON \
(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
#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_CKIP 5
#define IEEE80211_CIPHER_NONE 6
#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
#define IEEE80211_KEYIX_NONE ((ieee80211_keyix) -1)
#define IEEE80211_KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none)
#if defined(__KERNEL__) || defined(_KERNEL)
struct ieee80211com;
struct ieee80211_node;
struct mbuf;
struct ieee80211_crypto_state {
struct ieee80211_key cs_nw_keys[IEEE80211_WEP_NKID];
ieee80211_keyix cs_def_txkey;
u_int16_t cs_max_keyix;
int (*cs_key_alloc)(struct ieee80211com *,
const struct ieee80211_key *,
ieee80211_keyix *, ieee80211_keyix *);
int (*cs_key_delete)(struct ieee80211com *,
const struct ieee80211_key *);
int (*cs_key_set)(struct ieee80211com *,
const struct ieee80211_key *,
const u_int8_t mac[IEEE80211_ADDR_LEN]);
void (*cs_key_update_begin)(struct ieee80211com *);
void (*cs_key_update_end)(struct ieee80211com *);
};
void ieee80211_crypto_attach(struct ieee80211com *);
void ieee80211_crypto_detach(struct ieee80211com *);
int ieee80211_crypto_newkey(struct ieee80211com *,
int cipher, int flags, struct ieee80211_key *);
int ieee80211_crypto_delkey(struct ieee80211com *,
struct ieee80211_key *);
int ieee80211_crypto_setkey(struct ieee80211com *,
struct ieee80211_key *, const u_int8_t macaddr[IEEE80211_ADDR_LEN]);
void ieee80211_crypto_delglobalkeys(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 ieee80211com *, struct ieee80211_key *);
void (*ic_detach)(struct ieee80211_key *);
int (*ic_setkey)(struct ieee80211_key *);
int (*ic_encap)(struct ieee80211_key *, struct mbuf *,
u_int8_t keyid);
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;
extern const struct ieee80211_cipher ieee80211_cipher_wep;
extern const struct ieee80211_cipher ieee80211_cipher_tkip;
extern const struct ieee80211_cipher ieee80211_cipher_ccmp;
void ieee80211_crypto_register(const struct ieee80211_cipher *);
void ieee80211_crypto_unregister(const struct ieee80211_cipher *);
int ieee80211_crypto_available(u_int cipher);
struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211com *,
struct ieee80211_node *, struct mbuf *);
struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211com *,
struct ieee80211_node *, struct mbuf **, int);
static __inline int
ieee80211_crypto_demic(struct ieee80211com *ic,
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 ieee80211com *ic,
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 ieee80211com *ic,
struct ieee80211_key *k, ieee80211_keyix ix)
{
k->wk_cipher = &ieee80211_cipher_none;
k->wk_private = k->wk_cipher->ic_attach(ic, k);
k->wk_keyix = k->wk_rxkeyix = ix;
k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
}
void ieee80211_notify_replay_failure(struct ieee80211com *,
const struct ieee80211_frame *, const struct ieee80211_key *,
u_int64_t rsc);
void ieee80211_notify_michael_failure(struct ieee80211com *,
const struct ieee80211_frame *, u_int keyix);
#endif
#endif