ieee80211_crypto.h revision 144618
1116742Ssam/*- 2116904Ssam * Copyright (c) 2001 Atsushi Onoe 3139530Ssam * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4116742Ssam * All rights reserved. 5116742Ssam * 6116742Ssam * Redistribution and use in source and binary forms, with or without 7116742Ssam * modification, are permitted provided that the following conditions 8116742Ssam * are met: 9116742Ssam * 1. Redistributions of source code must retain the above copyright 10116742Ssam * notice, this list of conditions and the following disclaimer. 11116742Ssam * 2. Redistributions in binary form must reproduce the above copyright 12116742Ssam * notice, this list of conditions and the following disclaimer in the 13116742Ssam * documentation and/or other materials provided with the distribution. 14116904Ssam * 3. The name of the author may not be used to endorse or promote products 15116904Ssam * derived from this software without specific prior written permission. 16116742Ssam * 17116904Ssam * Alternatively, this software may be distributed under the terms of the 18116904Ssam * GNU General Public License ("GPL") version 2 as published by the Free 19116904Ssam * Software Foundation. 20116742Ssam * 21116904Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22116904Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23116904Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24116904Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25116904Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26116904Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27116904Ssam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28116904Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29116904Ssam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30116904Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31116904Ssam * 32116742Ssam * $FreeBSD: head/sys/net80211/ieee80211_crypto.h 144618 2005-04-04 04:27:20Z sam $ 33116742Ssam */ 34116742Ssam#ifndef _NET80211_IEEE80211_CRYPTO_H_ 35116742Ssam#define _NET80211_IEEE80211_CRYPTO_H_ 36116742Ssam 37116742Ssam/* 38116742Ssam * 802.11 protocol crypto-related definitions. 39116742Ssam */ 40116742Ssam#define IEEE80211_KEYBUF_SIZE 16 41138568Ssam#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx+rx keys */ 42116742Ssam 43138568Ssam/* 44138568Ssam * Old WEP-style key. Deprecated. 45138568Ssam */ 46116742Ssamstruct ieee80211_wepkey { 47138568Ssam u_int wk_len; /* key length in bytes */ 48138568Ssam u_int8_t wk_key[IEEE80211_KEYBUF_SIZE]; 49116742Ssam}; 50116742Ssam 51138568Ssamstruct ieee80211_cipher; 52138568Ssam 53138568Ssam/* 54138568Ssam * Crypto key state. There is sufficient room for all supported 55138568Ssam * ciphers (see below). The underlying ciphers are handled 56138568Ssam * separately through loadable cipher modules that register with 57138568Ssam * the generic crypto support. A key has a reference to an instance 58138568Ssam * of the cipher; any per-key state is hung off wk_private by the 59138568Ssam * cipher when it is attached. Ciphers are automatically called 60138568Ssam * to detach and cleanup any such state when the key is deleted. 61138568Ssam * 62138568Ssam * The generic crypto support handles encap/decap of cipher-related 63138568Ssam * frame contents for both hardware- and software-based implementations. 64138568Ssam * A key requiring software crypto support is automatically flagged and 65138568Ssam * the cipher is expected to honor this and do the necessary work. 66138568Ssam * Ciphers such as TKIP may also support mixed hardware/software 67138568Ssam * encrypt/decrypt and MIC processing. 68138568Ssam */ 69138568Ssam/* XXX need key index typedef */ 70138568Ssam/* XXX pack better? */ 71138568Ssam/* XXX 48-bit rsc/tsc */ 72138568Ssamstruct ieee80211_key { 73138568Ssam u_int8_t wk_keylen; /* key length in bytes */ 74138568Ssam u_int8_t wk_flags; 75138568Ssam#define IEEE80211_KEY_XMIT 0x01 /* key used for xmit */ 76138568Ssam#define IEEE80211_KEY_RECV 0x02 /* key used for recv */ 77138568Ssam#define IEEE80211_KEY_SWCRYPT 0x04 /* host-based encrypt/decrypt */ 78138568Ssam#define IEEE80211_KEY_SWMIC 0x08 /* host-based enmic/demic */ 79138568Ssam u_int16_t wk_keyix; /* key index */ 80138568Ssam u_int8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; 81138568Ssam#define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ 82138568Ssam#define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ 83138568Ssam u_int64_t wk_keyrsc; /* key receive sequence counter */ 84138568Ssam u_int64_t wk_keytsc; /* key transmit sequence counter */ 85138568Ssam const struct ieee80211_cipher *wk_cipher; 86138568Ssam void *wk_private; /* private cipher state */ 87138568Ssam}; 88138568Ssam 89138568Ssam/* 90138568Ssam * NB: these values are ordered carefully; there are lots of 91138568Ssam * of implications in any reordering. In particular beware 92138568Ssam * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. 93138568Ssam */ 94138568Ssam#define IEEE80211_CIPHER_WEP 0 95138568Ssam#define IEEE80211_CIPHER_TKIP 1 96138568Ssam#define IEEE80211_CIPHER_AES_OCB 2 97138568Ssam#define IEEE80211_CIPHER_AES_CCM 3 98138568Ssam#define IEEE80211_CIPHER_CKIP 5 99138568Ssam#define IEEE80211_CIPHER_NONE 6 /* pseudo value */ 100138568Ssam 101138568Ssam#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) 102138568Ssam 103138568Ssam#define IEEE80211_KEYIX_NONE ((u_int16_t) -1) 104138568Ssam 105138568Ssam#if defined(__KERNEL__) || defined(_KERNEL) 106138568Ssam 107138568Ssamstruct ieee80211com; 108138568Ssamstruct ieee80211_node; 109138568Ssamstruct mbuf; 110138568Ssam 111138568Ssam/* 112138568Ssam * Crypto state kept in each ieee80211com. Some of this 113138568Ssam * can/should be shared when virtual AP's are supported. 114138568Ssam * 115138568Ssam * XXX save reference to ieee80211com to properly encapsulate state. 116138568Ssam * XXX split out crypto capabilities from ic_caps 117138568Ssam */ 118138568Ssamstruct ieee80211_crypto_state { 119138568Ssam struct ieee80211_key cs_nw_keys[IEEE80211_WEP_NKID]; 120138568Ssam u_int16_t cs_def_txkey; /* default/group tx key index */ 121138568Ssam 122138568Ssam int (*cs_key_alloc)(struct ieee80211com *, 123138568Ssam const struct ieee80211_key *); 124138568Ssam int (*cs_key_delete)(struct ieee80211com *, 125138568Ssam const struct ieee80211_key *); 126138568Ssam int (*cs_key_set)(struct ieee80211com *, 127138568Ssam const struct ieee80211_key *, 128138568Ssam const u_int8_t mac[IEEE80211_ADDR_LEN]); 129138568Ssam void (*cs_key_update_begin)(struct ieee80211com *); 130138568Ssam void (*cs_key_update_end)(struct ieee80211com *); 131138568Ssam}; 132138568Ssam 133144618Ssamvoid ieee80211_crypto_attach(struct ieee80211com *); 134144618Ssamvoid ieee80211_crypto_detach(struct ieee80211com *); 135144618Ssamint ieee80211_crypto_newkey(struct ieee80211com *, 136138568Ssam int cipher, struct ieee80211_key *); 137144618Ssamint ieee80211_crypto_delkey(struct ieee80211com *, 138138568Ssam struct ieee80211_key *); 139144618Ssamint ieee80211_crypto_setkey(struct ieee80211com *, 140138568Ssam struct ieee80211_key *, const u_int8_t macaddr[IEEE80211_ADDR_LEN]); 141144618Ssamvoid ieee80211_crypto_delglobalkeys(struct ieee80211com *); 142138568Ssam 143138568Ssam/* 144138568Ssam * Template for a supported cipher. Ciphers register with the 145138568Ssam * crypto code and are typically loaded as separate modules 146138568Ssam * (the null cipher is always present). 147138568Ssam * XXX may need refcnts 148138568Ssam */ 149138568Ssamstruct ieee80211_cipher { 150138568Ssam const char *ic_name; /* printable name */ 151138568Ssam u_int ic_cipher; /* IEEE80211_CIPHER_* */ 152138568Ssam u_int ic_header; /* size of privacy header (bytes) */ 153138568Ssam u_int ic_trailer; /* size of privacy trailer (bytes) */ 154138568Ssam u_int ic_miclen; /* size of mic trailer (bytes) */ 155138568Ssam void* (*ic_attach)(struct ieee80211com *, struct ieee80211_key *); 156138568Ssam void (*ic_detach)(struct ieee80211_key *); 157138568Ssam int (*ic_setkey)(struct ieee80211_key *); 158138568Ssam int (*ic_encap)(struct ieee80211_key *, struct mbuf *, 159138568Ssam u_int8_t keyid); 160138568Ssam int (*ic_decap)(struct ieee80211_key *, struct mbuf *); 161138568Ssam int (*ic_enmic)(struct ieee80211_key *, struct mbuf *); 162138568Ssam int (*ic_demic)(struct ieee80211_key *, struct mbuf *); 163138568Ssam}; 164138568Ssamextern const struct ieee80211_cipher ieee80211_cipher_none; 165138568Ssam 166144618Ssamvoid ieee80211_crypto_register(const struct ieee80211_cipher *); 167144618Ssamvoid ieee80211_crypto_unregister(const struct ieee80211_cipher *); 168144618Ssamint ieee80211_crypto_available(u_int cipher); 169138568Ssam 170144618Ssamstruct ieee80211_key *ieee80211_crypto_encap(struct ieee80211com *, 171138568Ssam struct ieee80211_node *, struct mbuf *); 172144618Ssamstruct ieee80211_key *ieee80211_crypto_decap(struct ieee80211com *, 173138568Ssam struct ieee80211_node *, struct mbuf *); 174138568Ssam 175138568Ssam/* 176138568Ssam * Check and remove any MIC. 177138568Ssam */ 178138568Ssamstatic __inline int 179138568Ssamieee80211_crypto_demic(struct ieee80211com *ic, struct ieee80211_key *k, 180138568Ssam struct mbuf *m) 181138568Ssam{ 182138568Ssam const struct ieee80211_cipher *cip = k->wk_cipher; 183138568Ssam return (cip->ic_miclen > 0 ? cip->ic_demic(k, m) : 1); 184138568Ssam} 185138568Ssam 186138568Ssam/* 187138568Ssam * Add any MIC. 188138568Ssam */ 189138568Ssamstatic __inline int 190138568Ssamieee80211_crypto_enmic(struct ieee80211com *ic, 191138568Ssam struct ieee80211_key *k, struct mbuf *m) 192138568Ssam{ 193138568Ssam const struct ieee80211_cipher *cip = k->wk_cipher; 194138568Ssam return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m) : 1); 195138568Ssam} 196138568Ssam 197138568Ssam/* 198138568Ssam * Reset key state to an unused state. The crypto 199138568Ssam * key allocation mechanism insures other state (e.g. 200138568Ssam * key data) is properly setup before a key is used. 201138568Ssam */ 202138568Ssamstatic __inline void 203138568Ssamieee80211_crypto_resetkey(struct ieee80211com *ic, 204138568Ssam struct ieee80211_key *k, u_int16_t ix) 205138568Ssam{ 206138568Ssam k->wk_cipher = &ieee80211_cipher_none;; 207138568Ssam k->wk_private = k->wk_cipher->ic_attach(ic, k); 208138568Ssam k->wk_keyix = ix; 209138568Ssam k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; 210138568Ssam} 211138568Ssam 212138568Ssam/* 213138568Ssam * Crypt-related notification methods. 214138568Ssam */ 215144618Ssamvoid ieee80211_notify_replay_failure(struct ieee80211com *, 216138568Ssam const struct ieee80211_frame *, const struct ieee80211_key *, 217138568Ssam u_int64_t rsc); 218144618Ssamvoid ieee80211_notify_michael_failure(struct ieee80211com *, 219138568Ssam const struct ieee80211_frame *, u_int keyix); 220138568Ssam#endif /* defined(__KERNEL__) || defined(_KERNEL) */ 221116742Ssam#endif /* _NET80211_IEEE80211_CRYPTO_H_ */ 222