summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/kssl/ksslproto.h
blob: c982fe9dfd21ff232636b28183da4dab0428fa64 (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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef	_INET_KSSL_KSSLPROTO_H
#define	_INET_KSSL_KSSLPROTO_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/stream.h>
#include <sys/md5.h>
#include <sys/sha1.h>
#include <sys/crypto/common.h>
#include <sys/crypto/api.h>
#include <inet/kssl/kssl.h>	/* Cipher suite definitions */
#include <inet/kssl/ksslapi.h>
#include <inet/kssl/ksslimpl.h>

#define	SSL3_RANDOM_LENGTH		32
#define	SSL3_SESSIONID_BYTES		32
#define	SSL3_HDR_LEN			5
#define	SSL3_ALERT_LEN			2
#define	SSL3_MAX_RECORD_LENGTH		16384
#define	SSL3_PRE_MASTER_SECRET_LEN	48
#define	SSL3_MASTER_SECRET_LEN		48
#define	SSL3_MD5_PAD_LEN		48
#define	SSL3_SHA1_PAD_LEN		40

#define	SSL_MIN_CHALLENGE_BYTES		16
#define	SSL_MAX_CHALLENGE_BYTES		32

#define	SHA1_HASH_LEN			20
#define	MD5_HASH_LEN			16
#define	MAX_HASH_LEN			SHA1_HASH_LEN

#define	KSSL_READ			0
#define	KSSL_WRITE			1

#define	KSSL_ENCRYPT			0
#define	KSSL_DECRYPT			1

#define	MSG_INIT			0
#define	MSG_INIT_LEN			1
#define	MSG_BODY			2

/*
 * More than enough for the cipher suite that needs the
 * largest key material (AES_256_CBC_SHA needs 136 bytes).
 */
#define	MAX_KEYBLOCK_LENGTH		160

#define	TLS_MASTER_SECRET_LABEL		"master secret"
#define	TLS_CLIENT_WRITE_KEY_LABEL	"client write key"
#define	TLS_SERVER_WRITE_KEY_LABEL	"server write key"
#define	TLS_CLIENT_FINISHED_LABEL	"client finished"
#define	TLS_SERVER_FINISHED_LABEL	"server finished"
#define	TLS_KEY_EXPANSION_LABEL		"key expansion"
#define	TLS_IV_BLOCK_LABEL		"IV block"
#define	TLS_MAX_LABEL_SIZE		24

#define	TLS_FINISHED_SIZE		12

/*
 * The following constants try to insure an input buffer is optimally aligned
 * for MAC hash computation.  SHA1/MD5 code prefers 4 byte alignment of each
 * 64byte input block to avoid a copy. Our goal is to reach 4 byte alignment
 * starting form the 3rd MAC block (input buffer starts in the 3rd block). The
 * 3rd block includes the first 53 (MD5 SSL3 MAC) or 57 (SHA1 SSL3 MAC) bytes
 * of the input buffer. This means input buffer should start at offset 3
 * within a 4 byte word so that its next block is 4 byte aligned. Since the
 * SSL3 record header is 5 bytes long it should start at at offset 2 within a
 * 4 byte word. To insure the next record (for buffers that don't fit into 1
 * SSL3 record) also starts at offset 2 within a 4 byte word the previous
 * record length should be 3 mod 8 since 5 + 3 mod 8 is 0 i.e. the next record
 * starts at the same offset within a 4 byte word as the the previous record.
 */
#define	SSL3_MAX_OPTIMAL_RECORD_LENGTH	(SSL3_MAX_RECORD_LENGTH - 1)
#define	SSL3_OPTIMAL_RECORD_ALIGNMENT	2

/* session state */
typedef struct sslSessionIDStr {
	uchar_t		session_id[SSL3_SESSIONID_BYTES];
	uchar_t 	master_secret[SSL3_MASTER_SECRET_LEN];
	clock_t 	time;
	in6_addr_t 	client_addr;
	boolean_t	cached;
	uint16_t	cipher_suite;
} sslSessionID;

/* An element of the session cache */
typedef struct kssl_sid_ent {
	kmutex_t	se_lock;
	uint64_t	se_used;	/* Counter to check hash distribution */
	sslSessionID	se_sid;
} kssl_sid_ent_t;

typedef enum {
	content_change_cipher_spec	= 20,
	content_alert			= 21,
	content_handshake		= 22,
	content_application_data	= 23,
	content_handshake_v2		= 128
} SSL3ContentType;

typedef enum {
	hello_request		= 0,
	client_hello		= 1,
	server_hello		= 2,
	certificate		= 11,
	server_key_exchange	= 12,
	certificate_request	= 13,
	server_hello_done	= 14,
	certificate_verify	= 15,
	client_key_exchange	= 16,
	finished		= 20
} SSL3HandshakeType;

typedef struct SSL3HandshakeMsgStr {
	int			state;
	SSL3HandshakeType	type;
	int			msglen;
	int			msglen_bytes;
	mblk_t			*head;
	mblk_t			*tail;
} SSL3HandshakeMsg;

typedef struct KSSLJOBStr {
	struct ssl_s	*ssl;
	crypto_req_id_t	kjob;
	char		*buf;
	size_t		buflen;
	int		status;
} KSSLJOB;


typedef struct {
	uchar_t md5[MD5_HASH_LEN];
	uchar_t sha1[SHA1_HASH_LEN];
	uchar_t tlshash[TLS_FINISHED_SIZE];
} SSL3Hashes;

typedef enum {
	close_notify		= 0,
	unexpected_message	= 10,
	bad_record_mac		= 20,
	decompression_failure	= 30,
	handshake_failure	= 40,
	no_certificate		= 41,
	bad_certificate		= 42,
	unsupported_certificate	= 43,
	certificate_revoked	= 44,
	certificate_expired	= 45,
	certificate_unknown	= 46,
	illegal_parameter	= 47,
	unknown_ca		= 48,
	access_denied		= 49,
	decode_error		= 50,
	decrypt_error		= 51,
	export_restriction	= 60,
	protocol_version	= 70,
	insufficient_security	= 71,
	internal_error		= 80,
	user_canceled		= 90,
	no_renegotiation	= 100
} SSL3AlertDescription;

typedef enum {
	alert_warning = 1,
	alert_fatal = 2
} SSL3AlertLevel;

typedef enum {
	wait_client_hello = 0,
	wait_client_key = 1,
	wait_client_key_done = 2,
	wait_change_cipher = 3,
	wait_finished = 4,
	idle_handshake = 5
} SSL3WaitState;

typedef enum {
	sender_client = 0x434c4e54,
	sender_server = 0x53525652
} SSL3Sender;

typedef enum {
	mac_md5	= 0,
	mac_sha	= 1
} SSL3MACAlgorithm;

/* The SSL bulk cipher definition */
typedef enum {
	cipher_null = 0,
	cipher_rc4 = 1,
	cipher_des = 2,
	cipher_3des = 3,
	cipher_aes128 = 4,
	cipher_aes256 = 5,
} SSL3BulkCipher;

typedef enum { type_stream = 0, type_block = 1 } CipherType;

typedef struct ssl3CipherSuiteDefStr {
	uint16_t		suite;
	SSL3BulkCipher		calg;
	SSL3MACAlgorithm	malg;
	int			keyblksz;
} ssl3CipherSuiteDef;

typedef void (*hashinit_func_t)(void *);
typedef void (*hashupdate_func_t)(void *, uchar_t *, uint32_t);
typedef void (*hashfinal_func_t)(uchar_t *, void *);

typedef struct KSSLMACDefStr {
	int			hashsz;
	int			padsz;
	hashinit_func_t		HashInit;
	hashupdate_func_t	HashUpdate;
	hashfinal_func_t	HashFinal;
} KSSLMACDef;

typedef struct KSSLCipherDefStr {
	CipherType		type;
	int			bsize;
	int			keysz;
	crypto_mech_type_t	mech_type;
} KSSLCipherDef;

typedef union KSSL_HASHCTXUnion {
	SHA1_CTX	sha;
	MD5_CTX		md5;
} KSSL_HASHCTX;

typedef struct KSSLCipherSpecStr {
	int		mac_hashsz;
	int		mac_padsz;
	void		(*MAC_HashInit)(void *);
	void		(*MAC_HashUpdate)(void *, uchar_t *, uint32_t);
	void		(*MAC_HashFinal)(uchar_t *, void *);

	CipherType	cipher_type;
	int		cipher_bsize;
	int		cipher_keysz;

	crypto_mechanism_t	cipher_mech;
	crypto_mechanism_t	hmac_mech;	/* for TLS */
	crypto_key_t		cipher_key;
	crypto_key_t		hmac_key;	/* for TLS */

	crypto_context_t	cipher_ctx;
	crypto_data_t		cipher_data;

} KSSLCipherSpec;

/*
 * SSL connection state. This one hangs off of a ksslf_t structure.
 */
typedef struct ssl_s {
	kmutex_t		kssl_lock;
	struct kssl_entry_s	*kssl_entry;
	mblk_t			*rec_ass_head;
	mblk_t			*rec_ass_tail;
	in6_addr_t		faddr;
	uint32_t		tcp_mss;
	SSL3WaitState		hs_waitstate;
	boolean_t		resumed;
	boolean_t		close_notify_clnt;
	boolean_t		close_notify_srvr;
	boolean_t		fatal_alert;
	boolean_t		fatal_error;
	boolean_t		alert_sent;
	boolean_t		appdata_sent;
	boolean_t		activeinput;
	SSL3AlertLevel		sendalert_level;
	SSL3AlertDescription	sendalert_desc;
	mblk_t			*handshake_sendbuf;
	mblk_t			*alert_sendbuf;
	kssl_callback_t		cke_callback_func;
	void			*cke_callback_arg;
	uint16_t		pending_cipher_suite;
	SSL3MACAlgorithm	pending_malg;
	SSL3BulkCipher		pending_calg;
	int			pending_keyblksz;
	uint64_t		seq_num[2];
	SSL3HandshakeMsg	msg;
	KSSLJOB			job;
	KSSLCipherSpec		spec[2];
	uchar_t			pending_keyblock[MAX_KEYBLOCK_LENGTH];
	uchar_t			mac_secret[2][MAX_HASH_LEN];
	KSSL_HASHCTX		mac_ctx[2][2];	/* inner 'n outer per dir */
	sslSessionID		sid;
	SHA1_CTX		hs_sha1;
	MD5_CTX			hs_md5;
	SSL3Hashes		hs_hashes;
	uchar_t			client_random[SSL3_RANDOM_LENGTH];
	uchar_t			server_random[SSL3_RANDOM_LENGTH];
	int			sslcnt;
	uchar_t			major_version;
	uchar_t			minor_version;
	boolean_t		secure_renegotiation;
	uint_t			async_ops_pending;
	kcondvar_t		async_cv;
} ssl_t;

#define	IS_TLS(s) (s->major_version == 3 && s->minor_version == 1)

#define	SSL3_REC_SIZE(mp)	(uint8_t *)(mp)->b_rptr + 3

extern int kssl_spec_init(ssl_t *, int);
extern void kssl_send_alert(ssl_t *, SSL3AlertLevel, SSL3AlertDescription);

#ifdef	__cplusplus
}
#endif

#endif	/* _INET_KSSL_KSSLPROTO_H */