18a1b9b6aSSam Leffler /* $NetBSD: ieee80211_crypto.h,v 1.2 2003/09/14 01:14:55 dyoung Exp $ */ 21a1e1d21SSam Leffler /*- 37535e66aSSam Leffler * Copyright (c) 2001 Atsushi Onoe 48a1b9b6aSSam Leffler * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting 51a1e1d21SSam Leffler * All rights reserved. 61a1e1d21SSam Leffler * 71a1e1d21SSam Leffler * Redistribution and use in source and binary forms, with or without 81a1e1d21SSam Leffler * modification, are permitted provided that the following conditions 91a1e1d21SSam Leffler * are met: 101a1e1d21SSam Leffler * 1. Redistributions of source code must retain the above copyright 111a1e1d21SSam Leffler * notice, this list of conditions and the following disclaimer. 121a1e1d21SSam Leffler * 2. Redistributions in binary form must reproduce the above copyright 131a1e1d21SSam Leffler * notice, this list of conditions and the following disclaimer in the 141a1e1d21SSam Leffler * documentation and/or other materials provided with the distribution. 157535e66aSSam Leffler * 3. The name of the author may not be used to endorse or promote products 167535e66aSSam Leffler * derived from this software without specific prior written permission. 171a1e1d21SSam Leffler * 187535e66aSSam Leffler * Alternatively, this software may be distributed under the terms of the 197535e66aSSam Leffler * GNU General Public License ("GPL") version 2 as published by the Free 207535e66aSSam Leffler * Software Foundation. 217535e66aSSam Leffler * 227535e66aSSam Leffler * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 237535e66aSSam Leffler * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 247535e66aSSam Leffler * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 257535e66aSSam Leffler * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 267535e66aSSam Leffler * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 277535e66aSSam Leffler * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 287535e66aSSam Leffler * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 297535e66aSSam Leffler * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 307535e66aSSam Leffler * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 317535e66aSSam Leffler * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321a1e1d21SSam Leffler * 331a1e1d21SSam Leffler * $FreeBSD$ 341a1e1d21SSam Leffler */ 351a1e1d21SSam Leffler #ifndef _NET80211_IEEE80211_CRYPTO_H_ 361a1e1d21SSam Leffler #define _NET80211_IEEE80211_CRYPTO_H_ 371a1e1d21SSam Leffler 381a1e1d21SSam Leffler /* 391a1e1d21SSam Leffler * 802.11 protocol crypto-related definitions. 401a1e1d21SSam Leffler */ 411a1e1d21SSam Leffler #define IEEE80211_KEYBUF_SIZE 16 428a1b9b6aSSam Leffler #define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx+rx keys */ 431a1e1d21SSam Leffler 448a1b9b6aSSam Leffler /* 458a1b9b6aSSam Leffler * Old WEP-style key. Deprecated. 468a1b9b6aSSam Leffler */ 471a1e1d21SSam Leffler struct ieee80211_wepkey { 488a1b9b6aSSam Leffler u_int wk_len; /* key length in bytes */ 491a1e1d21SSam Leffler u_int8_t wk_key[IEEE80211_KEYBUF_SIZE]; 501a1e1d21SSam Leffler }; 511a1e1d21SSam Leffler 528a1b9b6aSSam Leffler struct ieee80211_cipher; 538a1b9b6aSSam Leffler 548a1b9b6aSSam Leffler /* 558a1b9b6aSSam Leffler * Crypto key state. There is sufficient room for all supported 568a1b9b6aSSam Leffler * ciphers (see below). The underlying ciphers are handled 578a1b9b6aSSam Leffler * separately through loadable cipher modules that register with 588a1b9b6aSSam Leffler * the generic crypto support. A key has a reference to an instance 598a1b9b6aSSam Leffler * of the cipher; any per-key state is hung off wk_private by the 608a1b9b6aSSam Leffler * cipher when it is attached. Ciphers are automatically called 618a1b9b6aSSam Leffler * to detach and cleanup any such state when the key is deleted. 628a1b9b6aSSam Leffler * 638a1b9b6aSSam Leffler * The generic crypto support handles encap/decap of cipher-related 648a1b9b6aSSam Leffler * frame contents for both hardware- and software-based implementations. 658a1b9b6aSSam Leffler * A key requiring software crypto support is automatically flagged and 668a1b9b6aSSam Leffler * the cipher is expected to honor this and do the necessary work. 678a1b9b6aSSam Leffler * Ciphers such as TKIP may also support mixed hardware/software 688a1b9b6aSSam Leffler * encrypt/decrypt and MIC processing. 698a1b9b6aSSam Leffler */ 708a1b9b6aSSam Leffler /* XXX need key index typedef */ 718a1b9b6aSSam Leffler /* XXX pack better? */ 728a1b9b6aSSam Leffler /* XXX 48-bit rsc/tsc */ 738a1b9b6aSSam Leffler struct ieee80211_key { 748a1b9b6aSSam Leffler u_int8_t wk_keylen; /* key length in bytes */ 758a1b9b6aSSam Leffler u_int8_t wk_flags; 768a1b9b6aSSam Leffler #define IEEE80211_KEY_XMIT 0x01 /* key used for xmit */ 778a1b9b6aSSam Leffler #define IEEE80211_KEY_RECV 0x02 /* key used for recv */ 788a1b9b6aSSam Leffler #define IEEE80211_KEY_SWCRYPT 0x04 /* host-based encrypt/decrypt */ 798a1b9b6aSSam Leffler #define IEEE80211_KEY_SWMIC 0x08 /* host-based enmic/demic */ 808a1b9b6aSSam Leffler u_int16_t wk_keyix; /* key index */ 818a1b9b6aSSam Leffler u_int8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; 828a1b9b6aSSam Leffler #define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ 838a1b9b6aSSam Leffler #define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ 848a1b9b6aSSam Leffler u_int64_t wk_keyrsc; /* key receive sequence counter */ 858a1b9b6aSSam Leffler u_int64_t wk_keytsc; /* key transmit sequence counter */ 868a1b9b6aSSam Leffler const struct ieee80211_cipher *wk_cipher; 878a1b9b6aSSam Leffler void *wk_private; /* private cipher state */ 888a1b9b6aSSam Leffler }; 898a1b9b6aSSam Leffler 908a1b9b6aSSam Leffler /* 918a1b9b6aSSam Leffler * NB: these values are ordered carefully; there are lots of 928a1b9b6aSSam Leffler * of implications in any reordering. In particular beware 938a1b9b6aSSam Leffler * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. 948a1b9b6aSSam Leffler */ 958a1b9b6aSSam Leffler #define IEEE80211_CIPHER_WEP 0 968a1b9b6aSSam Leffler #define IEEE80211_CIPHER_TKIP 1 978a1b9b6aSSam Leffler #define IEEE80211_CIPHER_AES_OCB 2 988a1b9b6aSSam Leffler #define IEEE80211_CIPHER_AES_CCM 3 998a1b9b6aSSam Leffler #define IEEE80211_CIPHER_CKIP 5 1008a1b9b6aSSam Leffler #define IEEE80211_CIPHER_NONE 6 /* pseudo value */ 1018a1b9b6aSSam Leffler 1028a1b9b6aSSam Leffler #define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) 1038a1b9b6aSSam Leffler 1048a1b9b6aSSam Leffler #define IEEE80211_KEYIX_NONE ((u_int16_t) -1) 1058a1b9b6aSSam Leffler 1068a1b9b6aSSam Leffler #if defined(__KERNEL__) || defined(_KERNEL) 1078a1b9b6aSSam Leffler 1088a1b9b6aSSam Leffler struct ieee80211com; 1098a1b9b6aSSam Leffler struct ieee80211_node; 1108a1b9b6aSSam Leffler struct mbuf; 1118a1b9b6aSSam Leffler 1128a1b9b6aSSam Leffler /* 1138a1b9b6aSSam Leffler * Crypto state kept in each ieee80211com. Some of this 1148a1b9b6aSSam Leffler * can/should be shared when virtual AP's are supported. 1158a1b9b6aSSam Leffler * 1168a1b9b6aSSam Leffler * XXX save reference to ieee80211com to properly encapsulate state. 1178a1b9b6aSSam Leffler * XXX split out crypto capabilities from ic_caps 1188a1b9b6aSSam Leffler */ 1198a1b9b6aSSam Leffler struct ieee80211_crypto_state { 1208a1b9b6aSSam Leffler struct ieee80211_key cs_nw_keys[IEEE80211_WEP_NKID]; 1218a1b9b6aSSam Leffler u_int16_t cs_def_txkey; /* default/group tx key index */ 1228a1b9b6aSSam Leffler 1238a1b9b6aSSam Leffler int (*cs_key_alloc)(struct ieee80211com *, 1248a1b9b6aSSam Leffler const struct ieee80211_key *); 1258a1b9b6aSSam Leffler int (*cs_key_delete)(struct ieee80211com *, 1268a1b9b6aSSam Leffler const struct ieee80211_key *); 1278a1b9b6aSSam Leffler int (*cs_key_set)(struct ieee80211com *, 1288a1b9b6aSSam Leffler const struct ieee80211_key *, 1298a1b9b6aSSam Leffler const u_int8_t mac[IEEE80211_ADDR_LEN]); 1308a1b9b6aSSam Leffler void (*cs_key_update_begin)(struct ieee80211com *); 1318a1b9b6aSSam Leffler void (*cs_key_update_end)(struct ieee80211com *); 1328a1b9b6aSSam Leffler }; 1338a1b9b6aSSam Leffler 1348a1b9b6aSSam Leffler extern void ieee80211_crypto_attach(struct ieee80211com *); 1358a1b9b6aSSam Leffler extern void ieee80211_crypto_detach(struct ieee80211com *); 1368a1b9b6aSSam Leffler extern int ieee80211_crypto_newkey(struct ieee80211com *, 1378a1b9b6aSSam Leffler int cipher, struct ieee80211_key *); 1388a1b9b6aSSam Leffler extern int ieee80211_crypto_delkey(struct ieee80211com *, 1398a1b9b6aSSam Leffler struct ieee80211_key *); 1408a1b9b6aSSam Leffler extern int ieee80211_crypto_setkey(struct ieee80211com *, 1418a1b9b6aSSam Leffler struct ieee80211_key *, const u_int8_t macaddr[IEEE80211_ADDR_LEN]); 1428a1b9b6aSSam Leffler extern void ieee80211_crypto_delglobalkeys(struct ieee80211com *); 1438a1b9b6aSSam Leffler 1448a1b9b6aSSam Leffler /* 1458a1b9b6aSSam Leffler * Template for a supported cipher. Ciphers register with the 1468a1b9b6aSSam Leffler * crypto code and are typically loaded as separate modules 1478a1b9b6aSSam Leffler * (the null cipher is always present). 1488a1b9b6aSSam Leffler * XXX may need refcnts 1498a1b9b6aSSam Leffler */ 1508a1b9b6aSSam Leffler struct ieee80211_cipher { 1518a1b9b6aSSam Leffler const char *ic_name; /* printable name */ 1528a1b9b6aSSam Leffler u_int ic_cipher; /* IEEE80211_CIPHER_* */ 1538a1b9b6aSSam Leffler u_int ic_header; /* size of privacy header (bytes) */ 1548a1b9b6aSSam Leffler u_int ic_trailer; /* size of privacy trailer (bytes) */ 1558a1b9b6aSSam Leffler u_int ic_miclen; /* size of mic trailer (bytes) */ 1568a1b9b6aSSam Leffler void* (*ic_attach)(struct ieee80211com *, struct ieee80211_key *); 1578a1b9b6aSSam Leffler void (*ic_detach)(struct ieee80211_key *); 1588a1b9b6aSSam Leffler int (*ic_setkey)(struct ieee80211_key *); 1598a1b9b6aSSam Leffler int (*ic_encap)(struct ieee80211_key *, struct mbuf *, 1608a1b9b6aSSam Leffler u_int8_t keyid); 1618a1b9b6aSSam Leffler int (*ic_decap)(struct ieee80211_key *, struct mbuf *); 1628a1b9b6aSSam Leffler int (*ic_enmic)(struct ieee80211_key *, struct mbuf *); 1638a1b9b6aSSam Leffler int (*ic_demic)(struct ieee80211_key *, struct mbuf *); 1648a1b9b6aSSam Leffler }; 1658a1b9b6aSSam Leffler extern const struct ieee80211_cipher ieee80211_cipher_none; 1668a1b9b6aSSam Leffler 1678a1b9b6aSSam Leffler extern void ieee80211_crypto_register(const struct ieee80211_cipher *); 1688a1b9b6aSSam Leffler extern void ieee80211_crypto_unregister(const struct ieee80211_cipher *); 1698a1b9b6aSSam Leffler extern int ieee80211_crypto_available(u_int cipher); 1708a1b9b6aSSam Leffler 1718a1b9b6aSSam Leffler extern struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211com *, 1728a1b9b6aSSam Leffler struct ieee80211_node *, struct mbuf *); 1738a1b9b6aSSam Leffler extern struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211com *, 1748a1b9b6aSSam Leffler struct ieee80211_node *, struct mbuf *); 1758a1b9b6aSSam Leffler 1768a1b9b6aSSam Leffler /* 1778a1b9b6aSSam Leffler * Check and remove any MIC. 1788a1b9b6aSSam Leffler */ 1798a1b9b6aSSam Leffler static __inline int 1808a1b9b6aSSam Leffler ieee80211_crypto_demic(struct ieee80211com *ic, struct ieee80211_key *k, 1818a1b9b6aSSam Leffler struct mbuf *m) 1828a1b9b6aSSam Leffler { 1838a1b9b6aSSam Leffler const struct ieee80211_cipher *cip = k->wk_cipher; 1848a1b9b6aSSam Leffler return (cip->ic_miclen > 0 ? cip->ic_demic(k, m) : 1); 1858a1b9b6aSSam Leffler } 1868a1b9b6aSSam Leffler 1878a1b9b6aSSam Leffler /* 1888a1b9b6aSSam Leffler * Add any MIC. 1898a1b9b6aSSam Leffler */ 1908a1b9b6aSSam Leffler static __inline int 1918a1b9b6aSSam Leffler ieee80211_crypto_enmic(struct ieee80211com *ic, 1928a1b9b6aSSam Leffler struct ieee80211_key *k, struct mbuf *m) 1938a1b9b6aSSam Leffler { 1948a1b9b6aSSam Leffler const struct ieee80211_cipher *cip = k->wk_cipher; 1958a1b9b6aSSam Leffler return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m) : 1); 1968a1b9b6aSSam Leffler } 1978a1b9b6aSSam Leffler 1988a1b9b6aSSam Leffler /* 1998a1b9b6aSSam Leffler * Reset key state to an unused state. The crypto 2008a1b9b6aSSam Leffler * key allocation mechanism insures other state (e.g. 2018a1b9b6aSSam Leffler * key data) is properly setup before a key is used. 2028a1b9b6aSSam Leffler */ 2038a1b9b6aSSam Leffler static __inline void 2048a1b9b6aSSam Leffler ieee80211_crypto_resetkey(struct ieee80211com *ic, 2058a1b9b6aSSam Leffler struct ieee80211_key *k, u_int16_t ix) 2068a1b9b6aSSam Leffler { 2078a1b9b6aSSam Leffler k->wk_cipher = &ieee80211_cipher_none;; 2088a1b9b6aSSam Leffler k->wk_private = k->wk_cipher->ic_attach(ic, k); 2098a1b9b6aSSam Leffler k->wk_keyix = ix; 2108a1b9b6aSSam Leffler k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; 2118a1b9b6aSSam Leffler } 2128a1b9b6aSSam Leffler 2138a1b9b6aSSam Leffler /* 2148a1b9b6aSSam Leffler * Crypt-related notification methods. 2158a1b9b6aSSam Leffler */ 2168a1b9b6aSSam Leffler extern void ieee80211_notify_replay_failure(struct ieee80211com *, 2178a1b9b6aSSam Leffler const struct ieee80211_frame *, const struct ieee80211_key *, 2188a1b9b6aSSam Leffler u_int64_t rsc); 2198a1b9b6aSSam Leffler extern void ieee80211_notify_michael_failure(struct ieee80211com *, 2208a1b9b6aSSam Leffler const struct ieee80211_frame *, u_int keyix); 2218a1b9b6aSSam Leffler #endif /* defined(__KERNEL__) || defined(_KERNEL) */ 2221a1e1d21SSam Leffler #endif /* _NET80211_IEEE80211_CRYPTO_H_ */ 223