summaryrefslogtreecommitdiff
path: root/release/src/router/matrixssl/src/matrixInternal.h
blob: 8245a9e38fd63186b3db7d09b893406d4b1499ea (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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/*
 *	matrixInternal.h
 *	Release $Name: MATRIXSSL_1_8_8_OPEN $
 *
 *	Internal header file used for the MatrixSSL implementation.
 *	Only modifiers of the library should be intersted in this file
 */
/*
 *	Copyright (c) PeerSec Networks, 2002-2009. All Rights Reserved.
 *	The latest version of this code is available at http://www.matrixssl.org
 *
 *	This software is open source; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This General Public License does NOT permit incorporating this software 
 *	into proprietary programs.  If you are unable to comply with the GPL, a 
 *	commercial license for this software may be purchased from PeerSec Networks
 *	at http://www.peersec.com
 *	
 *	This program is distributed in WITHOUT ANY WARRANTY; without even the 
 *	implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 *	See the GNU General Public License for more details.
 *	
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *	http://www.gnu.org/copyleft/gpl.html
 */
/******************************************************************************/

#ifndef _h_MATRIXINTERNAL
#define _h_MATRIXINTERNAL
#define _h_EXPORT_SYMBOLS

#include "../matrixCommon.h"

/******************************************************************************/
/*
	At the highest SSL level.  Must include the lower level PKI
*/
#include "pki/pkiInternal.h"

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************/

#if WIN32
#define				fcntl(A, B, C)
#define				MSG_NOSIGNAL	0
#endif /* WIN32 */

#define	SSL_FLAGS_READ_SECURE	0x2
#define	SSL_FLAGS_WRITE_SECURE	0x4
#define SSL_FLAGS_PUBLIC_SECURE	0x8
#define SSL_FLAGS_RESUMED		0x10	
#define SSL_FLAGS_CLOSED		0x20
#define SSL_FLAGS_NEED_ENCODE	0x40
#define SSL_FLAGS_ERROR			0x80
	
#define SSL2_HEADER_LEN				2
#define SSL3_HEADER_LEN				5
#define SSL3_HANDSHAKE_HEADER_LEN	4

/*
	These are defines rather than enums because we want to store them as char,
	not int32 (enum size)
*/
#define SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC	20
#define SSL_RECORD_TYPE_ALERT				21
#define SSL_RECORD_TYPE_HANDSHAKE			22
#define SSL_RECORD_TYPE_APPLICATION_DATA	23

#define SSL_HS_HELLO_REQUEST		0
#define SSL_HS_CLIENT_HELLO			1
#define SSL_HS_SERVER_HELLO			2
#define SSL_HS_HELLO_VERIFY_REQUEST	3
#define SSL_HS_CERTIFICATE			11
#define SSL_HS_SERVER_KEY_EXCHANGE	12
#define SSL_HS_CERTIFICATE_REQUEST	13
#define SSL_HS_SERVER_HELLO_DONE	14
#define SSL_HS_CERTIFICATE_VERIFY	15
#define SSL_HS_CLIENT_KEY_EXCHANGE	16
#define SSL_HS_FINISHED				20
#define SSL_HS_DONE					255	/* Handshake complete (internal) */

#define	INIT_ENCRYPT_CIPHER		0
#define INIT_DECRYPT_CIPHER		1

#define RSA_SIGN	1

/*
	Additional ssl alert value, indicating no error has ocurred.
*/
#define SSL_ALERT_NONE					255	/* No error */

#define SSL_HS_RANDOM_SIZE			32
#define SSL_HS_RSA_PREMASTER_SIZE	48

#define SSL2_MAJ_VER	2
#define SSL3_MAJ_VER	3
#define SSL3_MIN_VER	0
#define TLS_MIN_VER		1



/*
	SSL cipher suite values
*/
#define SSL_NULL_WITH_NULL_NULL				0x0000
#define SSL_RSA_WITH_NULL_MD5				0x0001
#define SSL_RSA_WITH_NULL_SHA				0x0002
#define SSL_RSA_WITH_RC4_128_MD5			0x0004
#define SSL_RSA_WITH_RC4_128_SHA			0x0005
#define SSL_RSA_WITH_3DES_EDE_CBC_SHA		0x000A

/*
	Maximum key block size for any defined cipher
	This must be validated if new ciphers are added
	Value is largest total among all cipher suites for
		2*macSize + 2*keySize + 2*ivSize
*/
#define SSL_MAX_KEY_BLOCK_SIZE			2*20 + 2*24 + 2*8

/*
	Master secret is 48 bytes, sessionId is 32 bytes max
*/
#define		SSL_HS_MASTER_SIZE		48
#define		SSL_MAX_SESSION_ID_SIZE	32


/*
	Round up the given length to the correct length with SSLv3 padding
*/
#define sslRoundup018(LEN, BLOCKSIZE) \
	BLOCKSIZE <= 1 ? BLOCKSIZE : (((LEN) + 8) & ~7)

/******************************************************************************/
/*
	SSL record and session structures
*/
typedef struct {
	unsigned short	len;
	unsigned char	majVer;
	unsigned char	minVer;
	unsigned char	type;
	unsigned char	pad[3];		/* Padding for 64 bit compat */
} sslRec_t;

typedef struct {
	unsigned char	clientRandom[SSL_HS_RANDOM_SIZE];	/* From ClientHello */
	unsigned char	serverRandom[SSL_HS_RANDOM_SIZE];	/* From ServerHello */
	unsigned char	masterSecret[SSL_HS_MASTER_SIZE];
	unsigned char	*premaster;							/* variable size */
	int32			premasterSize;

	unsigned char	keyBlock[SSL_MAX_KEY_BLOCK_SIZE];	/* Storage for the next six items */
	unsigned char	*wMACptr;
	unsigned char	*rMACptr;
	unsigned char	*wKeyptr;
	unsigned char	*rKeyptr;
	unsigned char	*wIVptr;
	unsigned char	*rIVptr;

	/*	All maximum sizes for current cipher suites */
	unsigned char	writeMAC[SSL_MAX_MAC_SIZE];
	unsigned char	readMAC[SSL_MAX_MAC_SIZE];
	unsigned char	writeKey[SSL_MAX_SYM_KEY_SIZE];
	unsigned char	readKey[SSL_MAX_SYM_KEY_SIZE];
	unsigned char	writeIV[SSL_MAX_IV_SIZE];
	unsigned char	readIV[SSL_MAX_IV_SIZE];

	unsigned char	seq[8];
	unsigned char	remSeq[8];

#ifdef USE_CLIENT_SIDE_SSL
	sslCert_t		*cert;
	int32 (*validateCert)(sslCertInfo_t *certInfo, void *arg);
	void			*validateCertArg;
	int32				certMatch;
#endif /* USE_CLIENT_SIDE_SSL */

	sslMd5Context_t		msgHashMd5;
	sslSha1Context_t	msgHashSha1;

	sslCipherContext_t	encryptCtx;
	sslCipherContext_t	decryptCtx;
	int32				anon;
} sslSec_t;

typedef struct {
	uint32	id;
	unsigned char	macSize;
	unsigned char	keySize;
	unsigned char	ivSize;
	unsigned char	blockSize;
	/* Init function */
	int32 (*init)(sslSec_t *sec, int32 type);
	/* Cipher functions */
	int32 (*encrypt)(sslCipherContext_t *ctx, unsigned char *in,
		unsigned char *out, int32 len);
	int32 (*decrypt)(sslCipherContext_t *ctx, unsigned char *in,
		unsigned char *out, int32 len);
	int32 (*encryptPriv)(psPool_t *pool, sslRsaKey_t *key,	
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	int32 (*decryptPub)(psPool_t *pool, sslRsaKey_t *key,	
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);	
	int32 (*encryptPub)(psPool_t *pool, sslRsaKey_t *key, 
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	int32 (*decryptPriv)(psPool_t *pool, sslRsaKey_t *key, 
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	int32 (*generateMac)(void *ssl, unsigned char type, unsigned char *data,
		int32 len, unsigned char *mac);
	int32 (*verifyMac)(void *ssl, unsigned char type, unsigned char *data,
		int32 len, unsigned char *mac);
} sslCipherSpec_t;

typedef struct ssl {
	sslRec_t		rec;			/* Current SSL record information*/
									
	sslSec_t		sec;			/* Security structure */

	sslKeys_t		*keys;			/* SSL public and private keys */

	psPool_t		*pool;			/* SSL session pool */
	psPool_t		*hsPool;		/* Full session handshake pool */

	unsigned char	sessionIdLen;
	char			sessionId[SSL_MAX_SESSION_ID_SIZE];

	/* Pointer to the negotiated cipher information */
	sslCipherSpec_t	*cipher;

	/* 	Symmetric cipher callbacks

		We duplicate these here from 'cipher' because we need to set the
		various callbacks at different times in the handshake protocol
		Also, there are 64 bit alignment issues in using the function pointers
		within 'cipher' directly
	*/
	int32 (*encrypt)(sslCipherContext_t *ctx, unsigned char *in,
		unsigned char *out, int32 len);
	int32 (*decrypt)(sslCipherContext_t *ctx, unsigned char *in,
		unsigned char *out, int32 len);
	/* Public key ciphers */
	int32 (*encryptPriv)(psPool_t *pool, sslRsaKey_t *key, 
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	int32 (*decryptPub)(psPool_t *pool, sslRsaKey_t *key, 
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	int32 (*encryptPub)(psPool_t *pool, sslRsaKey_t *key, 
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	int32 (*decryptPriv)(psPool_t *pool, sslRsaKey_t *key, 
		unsigned char *in, int32 inlen,
		unsigned char *out, int32 outlen);
	/* Message Authentication Codes */
	int32 (*generateMac)(void *ssl, unsigned char type, unsigned char *data,
		int32 len, unsigned char *mac);
	int32 (*verifyMac)(void *ssl, unsigned char type, unsigned char *data,
		int32 len, unsigned char *mac);

	/* Current encryption/decryption parameters */
	unsigned char	enMacSize;
	unsigned char	enIvSize;
	unsigned char	enBlockSize;
	unsigned char	deMacSize;
	unsigned char	deIvSize;
	unsigned char	deBlockSize;

	int32			flags;
	int32			hsState;		/* Next expected handshake message type */
	int32			err;			/* SSL errno of last api call */
	int32			ignoredMessageCount;

	unsigned char	reqMajVer;
	unsigned char	reqMinVer;
	unsigned char	majVer;
	unsigned char	minVer;
	int32			recordHeadLen;
	int32			hshakeHeadLen;
} ssl_t;

typedef struct {
	unsigned char	id[SSL_MAX_SESSION_ID_SIZE];
	unsigned char	masterSecret[SSL_HS_MASTER_SIZE];
	uint32	cipherId;
} sslSessionId_t;

typedef struct {
	unsigned char	id[SSL_MAX_SESSION_ID_SIZE];
	unsigned char	masterSecret[SSL_HS_MASTER_SIZE];
	sslCipherSpec_t	*cipher;
	unsigned char	majVer;
	unsigned char	minVer;
	char			flag;
	sslTime_t		startTime;
	sslTime_t		accessTime;
	int32			inUse;
} sslSessionEntry_t;

/******************************************************************************/
/*
	Have ssl_t and sslSessionId_t now for addition of the public api set
*/
#include "../matrixSsl.h"

/******************************************************************************/
/*
	sslEncode.c and sslDecode.c
*/
extern int32 psWriteRecordInfo(ssl_t *ssl, unsigned char type, int32 len,
							 unsigned char *c);
extern int32 psWriteHandshakeHeader(ssl_t *ssl, unsigned char type, int32 len, 
								int32 seq, int32 fragOffset, int32 fragLen,
								unsigned char *c);
extern int32 sslEncodeResponse(ssl_t *ssl, sslBuf_t *out);
extern int32 sslActivateReadCipher(ssl_t *ssl);
extern int32 sslActivateWriteCipher(ssl_t *ssl);
extern int32 sslActivatePublicCipher(ssl_t *ssl);
extern int32 sslUpdateHSHash(ssl_t *ssl, unsigned char *in, int32 len);
extern int32 sslInitHSHash(ssl_t *ssl);
extern int32 sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag);
extern int32 sslWritePad(unsigned char *p, unsigned char padLen);
extern void sslResetContext(ssl_t *ssl);

#ifdef USE_SERVER_SIDE_SSL
extern int32 matrixRegisterSession(ssl_t *ssl);
extern int32 matrixResumeSession(ssl_t *ssl);
extern int32 matrixClearSession(ssl_t *ssl, int32 remove);
extern int32 matrixUpdateSession(ssl_t *ssl);
#endif /* USE_SERVER_SIDE_SSL */


/*
	cipherSuite.c
*/
extern sslCipherSpec_t *sslGetCipherSpec(int32 id);
extern int32 sslGetCipherSpecListLen(void);
extern int32 sslGetCipherSpecList(unsigned char *c, int32 len);

/******************************************************************************/
/*
	sslv3.c
*/
extern int32 sslGenerateFinishedHash(sslMd5Context_t *md5, sslSha1Context_t *sha1,
								unsigned char *masterSecret,
								unsigned char *out, int32 sender);

extern int32 sslDeriveKeys(ssl_t *ssl);

#ifdef USE_SHA1_MAC
extern int32 ssl3HMACSha1(unsigned char *key, unsigned char *seq, 
						unsigned char type, unsigned char *data, int32 len,
						unsigned char *mac);
#endif /* USE_SHA1_MAC */

#ifdef USE_MD5_MAC
extern int32 ssl3HMACMd5(unsigned char *key, unsigned char *seq, 
						unsigned char type, unsigned char *data, int32 len,
						unsigned char *mac);
#endif /* USE_MD5_MAC */




/******************************************************************************/

#ifdef __cplusplus
}
#endif

#endif /* _h_MATRIXINTERNAL */

/******************************************************************************/