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