summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/net80211_crypto.h
blob: 1d0bf250ec36b699bbe377105884d7271dd112e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * 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.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifndef _SYS_NET80211_CRYPTO_H
#define	_SYS_NET80211_CRYPTO_H

#include <sys/types.h>
#include <sys/mac.h>
#include <sys/net80211_proto.h>

/*
 * 802.11 protocol crypto-related definitions.
 */

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * NB: these values are ordered carefully; there are lots of
 * of implications in any reordering.
 */
#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		4
#define	IEEE80211_CIPHER_NONE		5	/* pseudo value */

#define	IEEE80211_CIPHER_MAX		(IEEE80211_CIPHER_NONE+1)

/*
 * Maxmium length of key in bytes
 * WEP key length present in the 802.11 standard is 40-bit.
 * Many implementations also support 104-bit WEP keys.
 * 802.11i standardize TKIP/CCMP use 128-bit key
 */
#define	IEEE80211_KEYBUF_SIZE		16
#define	IEEE80211_MICBUF_SIZE		(8+8)	/* space for both tx+rx keys */

/* Key Flags */
#define	IEEE80211_KEY_XMIT		0x01	/* key used for xmit */
#define	IEEE80211_KEY_RECV		0x02	/* key used for recv */
#define	IEEE80211_KEY_GROUP		/* key used for WPA group operation */ \
					0x04
#define	IEEE80211_KEY_SWCRYPT		0x10	/* host-based encrypt/decrypt */
#define	IEEE80211_KEY_SWMIC		0x20	/* host-based enmic/demic */
#define	IEEE80211_KEY_COMMON 		/* common flags passed in by apps */ \
	(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)

/* WEP */
#define	IEEE80211_WEP_KEYLEN		5	/* 40bit */
#define	IEEE80211_WEP_IVLEN		3	/* 24bit */
#define	IEEE80211_WEP_KIDLEN		1	/* 1 octet */
#define	IEEE80211_WEP_CRCLEN		4	/* CRC-32 */
#define	IEEE80211_WEP_NKID		4	/* number of key ids */

/*
 * 802.11i defines an extended IV for use with non-WEP ciphers.
 * When the EXTIV bit is set in the key id byte an additional
 * 4 bytes immediately follow the IV for TKIP.  For CCMP the
 * EXTIV bit is likewise set but the 8 bytes represent the
 * CCMP header rather than IV+extended-IV.
 */
#define	IEEE80211_WEP_EXTIV		0x20
#define	IEEE80211_WEP_EXTIVLEN		4	/* extended IV length */
#define	IEEE80211_WEP_MICLEN		8	/* trailing MIC */

#define	IEEE80211_WEP_HDRLEN					\
	(IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
#define	IEEE80211_WEP_MINLEN					\
	(sizeof (struct ieee80211_frame) +			\
	IEEE80211_WEP_HDRLEN + IEEE80211_WEP_CRCLEN)

/* Maximum number of keys */
#define	IEEE80211_KEY_MAX		IEEE80211_WEP_NKID

struct ieee80211com;
struct ieee80211_node;
struct ieee80211_key;
typedef uint16_t	ieee80211_keyix;	/* h/w key index */

#define	IEEE80211_KEYIX_NONE	((ieee80211_keyix) -1)

/*
 * Template for a supported cipher.  Ciphers register with the
 * crypto code.
 *
 * ic_attach - Initialize cipher. The return value is set to wk_private
 * ic_detach - Destruct a cipher.
 * ic_setkey - Validate key contents
 * ic_encap  - Encrypt the 802.11 MAC payload
 * ic_decap  - Decrypt the 802.11 MAC payload
 * ic_enmic  - Add MIC
 * ic_demic  - Check and remove MIC
 */
struct ieee80211_cipher {
	const char	*ic_name;	/* printable name */
	uint32_t	ic_cipher;	/* IEEE80211_CIPHER_* */
	uint32_t	ic_header;	/* size of privacy header (bytes) */
	uint32_t	ic_trailer;	/* size of privacy trailer (bytes) */
	uint32_t	ic_miclen;	/* size of mic trailer (bytes) */
	void		*(*ic_attach)(struct ieee80211com *,
				struct ieee80211_key *);
	void		(*ic_detach)(struct ieee80211_key *);
	int32_t		(*ic_setkey)(struct ieee80211_key *);
	int32_t		(*ic_encap)(struct ieee80211_key *, mblk_t *,
				uint8_t keyid);
	int32_t		(*ic_decap)(struct ieee80211_key *, mblk_t *, int);
	int32_t		(*ic_enmic)(struct ieee80211_key *, mblk_t *, int);
	int32_t		(*ic_demic)(struct ieee80211_key *, mblk_t *, int);
};
extern	const struct ieee80211_cipher ieee80211_cipher_none;

struct ieee80211_key {
	uint8_t		wk_keylen;	/* key length in bytes */
	uint8_t		wk_pad;
	uint16_t	wk_flags;
	uint8_t		wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
	ieee80211_keyix	wk_keyix;	/* h/w key index */
	ieee80211_keyix	wk_rxkeyix;	/* optional h/w rx key index */
	uint64_t	wk_keyrsc;	/* key receive sequence counter */
	uint64_t	wk_keytsc;	/* key transmit sequence counter */
	const struct ieee80211_cipher	*wk_cipher;
	void		*wk_private;	/* private cipher state */
};
#define	wk_txmic	wk_key+IEEE80211_KEYBUF_SIZE+0
#define	wk_rxmic	wk_key+IEEE80211_KEYBUF_SIZE+8

/*
 * Crypto state kept in each ieee80211com.
 */
struct ieee80211_crypto_state {
	struct ieee80211_key	cs_nw_keys[IEEE80211_KEY_MAX];
	ieee80211_keyix		cs_def_txkey;	/* default/group tx key index */
	uint16_t		cs_max_keyix;	/* max h/w key index */

	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 uint8_t mac[IEEE80211_ADDR_LEN]);
	void			(*cs_key_update_begin)(struct ieee80211com *);
	void			(*cs_key_update_end)(struct ieee80211com *);
};

/*
 * Key update synchronization methods.
 */
#define	KEY_UPDATE_BEGIN(ic)		\
	(ic)->ic_crypto.cs_key_update_begin(ic)
#define	KEY_UPDATE_END(ic)		\
	(ic)->ic_crypto.cs_key_update_end(ic)
#define	KEY_UNDEFINED(k)		\
	((k).wk_cipher == &ieee80211_cipher_none)

#define	DEV_KEY_ALLOC(ic, k, kix, rkix) \
	(ic)->ic_crypto.cs_key_alloc(ic, k, kix, rkix)
#define	DEV_KEY_DELETE(ic, k)		\
	(ic)->ic_crypto.cs_key_delete(ic, k)
#define	DEV_KEY_SET(ic, k, m)		\
	(ic)->ic_crypto.cs_key_set(ic, k, m)

#define	CIPHER_DETACH(k)		\
	(k)->wk_cipher->ic_detach(k)
#define	CIPHER_ATTACH(k)		\
	(k)->wk_cipher->ic_attach(k)

#define	ieee80211_crypto_demic(ic, k, m, force)		\
	(((k)->wk_cipher->ic_miclen > 0) ?		\
	(k)->wk_cipher->ic_demic(k, m, force) :		\
	1)

#define	ieee80211_crypto_enmic(ic, k, m, force)		\
	((k)->wk_cipher->ic_miclen > 0 ?		\
	(k)->wk_cipher->ic_enmic(k, m, force) :		\
	1)

void ieee80211_crypto_attach(struct ieee80211com *ic);
void ieee80211_crypto_detach(struct ieee80211com *ic);
void ieee80211_crypto_register(struct ieee80211com *ic,
    const struct ieee80211_cipher *);
void ieee80211_crypto_unregister(struct ieee80211com *ic,
    const struct ieee80211_cipher *);
void ieee80211_crypto_resetkey(struct ieee80211com *, struct ieee80211_key *,
	ieee80211_keyix);

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_NET80211_CRYPTO_H */