1 /****************************************************************************
2 *																			*
3 *					cryptlib SSL v3/TLS Crypto Routines						*
4 *					 Copyright Peter Gutmann 1998-2010						*
5 *																			*
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9   #include "crypt.h"
10   #include "misc_rw.h"
11   #include "session.h"
12   #include "ssl.h"
13 #else
14   #include "crypt.h"
15   #include "enc_dec/misc_rw.h"
16   #include "session/session.h"
17   #include "session/ssl.h"
18 #endif /* Compiler-specific includes */
19 
20 #ifdef USE_SSL
21 
22 /****************************************************************************
23 *																			*
24 *								Utility Functions							*
25 *																			*
26 ****************************************************************************/
27 
28 /* Write packet metadata for input to the MAC/ICV authentication process:
29 
30 	seq_num || type || version || length */
31 
32 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
33 static int writePacketMetadata( OUT_BUFFER( dataMaxLength, *dataLength ) \
34 									void *data,
35 								IN_LENGTH_SHORT_MIN( 16 ) \
36 									const int dataMaxLength,
37 								OUT_LENGTH_BOUNDED_Z( dataMaxLength ) \
38 									int *dataLength,
39 								IN_RANGE( 0, 255 ) const int type,
40 								IN_INT_Z const long seqNo,
41 								IN_RANGE( SSL_MINOR_VERSION_TLS, \
42 										  SSL_MINOR_VERSION_TLS12 ) \
43 									const int version,
44 								IN_LENGTH_Z const int payloadLength )
45 	{
46 	STREAM stream;
47 	int status;
48 
49 	assert( isWritePtr( data, dataMaxLength ) );
50 	assert( isWritePtr( dataLength, sizeof( int ) ) );
51 
52 	REQUIRES( dataMaxLength >= 16 && dataMaxLength < MAX_INTLENGTH_SHORT );
53 	REQUIRES( type >= 0 && type <= 255 );
54 	REQUIRES( seqNo >= 0 );
55 	REQUIRES( version >= SSL_MINOR_VERSION_TLS && \
56 			  version <= SSL_MINOR_VERSION_TLS12 );
57 	REQUIRES( payloadLength >= 0 && payloadLength <= MAX_PACKET_SIZE );
58 
59 	/* Clear return values */
60 	memset( data, 0, min( 16, dataMaxLength ) );
61 	*dataLength = 0;
62 
63 	/* Write the sequence number, packet type, version, and length
64 	  information to the output buffer */
65 	sMemOpen( &stream, data, dataMaxLength );
66 	writeUint64( &stream, seqNo );
67 	sputc( &stream, type );
68 	sputc( &stream, SSL_MAJOR_VERSION );
69 	sputc( &stream, version );
70 	status = writeUint16( &stream, payloadLength );
71 	if( cryptStatusOK( status ) )
72 		*dataLength = stell( &stream );
73 	sMemDisconnect( &stream );
74 	return( status );
75 	}
76 
77 /****************************************************************************
78 *																			*
79 *							Encrypt/Decrypt Functions						*
80 *																			*
81 ****************************************************************************/
82 
83 /* Encrypt/decrypt a data block (in mose cases this also includes the MAC,
84    which has been added to the data by the caller).  The handling of length
85    arguments for these is a bit tricky, for encryption the input is { data,
86    payloadLength } which is padded (if necessary) and the padded length
87    returned in '*dataLength', for decryption the entire data block will be
88    processed but only 'processedDataLength' bytes of result are valid
89    output */
90 
91 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
encryptData(const SESSION_INFO * sessionInfoPtr,INOUT_BUFFER (dataMaxLength,* dataLength)BYTE * data,IN_DATALENGTH const int dataMaxLength,OUT_DATALENGTH_Z int * dataLength,IN_DATALENGTH const int payloadLength)92 int encryptData( const SESSION_INFO *sessionInfoPtr,
93 				 INOUT_BUFFER( dataMaxLength, *dataLength ) \
94 					BYTE *data,
95 				 IN_DATALENGTH const int dataMaxLength,
96 				 OUT_DATALENGTH_Z int *dataLength,
97 				 IN_DATALENGTH const int payloadLength )
98 	{
99 	int length = payloadLength, status;
100 
101 	assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
102 	assert( isWritePtr( data, dataMaxLength ) );
103 	assert( isWritePtr( dataLength, sizeof( int ) ) );
104 
105 	REQUIRES( dataMaxLength > 0 && dataMaxLength < MAX_BUFFER_SIZE );
106 	REQUIRES( payloadLength > 0 && \
107 			  payloadLength <= MAX_PACKET_SIZE + 20 && \
108 			  payloadLength <= sessionInfoPtr->sendBufSize && \
109 			  payloadLength <= dataMaxLength );
110 
111 	/* Clear return value */
112 	*dataLength = 0;
113 
114 	/* If it's a block cipher then we add end-of-block and message padding.
115 	   We can't pad GCM because the spec doesn't allow it */
116 	if( sessionInfoPtr->cryptBlocksize > 1 )
117 		{
118 #ifdef USE_SSL3
119 		const int maxPadSize = ( sessionInfoPtr->version == SSL_MINOR_VERSION_SSL ) ? \
120 								 sessionInfoPtr->cryptBlocksize : MESSAGE_PADDING_SIZE;
121 		const int padSize = ( maxPadSize - 1 ) - \
122 						    ( payloadLength & ( maxPadSize - 1 ) );
123 #else
124 		const int padSize = ( MESSAGE_PADDING_SIZE - 1 ) - \
125 						    ( payloadLength & ( MESSAGE_PADDING_SIZE - 1 ) );
126 #endif /* USE_SSL3 */
127 		int i;
128 
129 		ENSURES( padSize >= 0 && padSize < MESSAGE_PADDING_SIZE && \
130 				 length + padSize + 1 <= dataMaxLength );
131 
132 		/* Add the PKCS #5-style padding (PKCS #5 uses n, TLS uses n-1) */
133 		for( i = 0; i < padSize + 1; i++ )
134 			data[ length++ ] = intToByte( padSize );
135 		}
136 
137 	/* Encrypt the data and optional padding */
138 	status = krnlSendMessage( sessionInfoPtr->iCryptOutContext,
139 							  IMESSAGE_CTX_ENCRYPT, data, length );
140 	if( cryptStatusError( status ) )
141 		return( status );
142 	*dataLength = length;
143 
144 	/* If we're using GCM then we have to append the ICV to the data */
145 	if( sessionInfoPtr->protocolFlags & SSL_PFLAG_GCM )
146 		{
147 		MESSAGE_DATA msgData;
148 
149 		REQUIRES( length + sessionInfoPtr->authBlocksize <= dataMaxLength );
150 
151 		setMessageData( &msgData, data + length,
152 						sessionInfoPtr->authBlocksize );
153 		status = krnlSendMessage( sessionInfoPtr->iCryptOutContext,
154 								  IMESSAGE_GETATTRIBUTE_S, &msgData,
155 								  CRYPT_IATTRIBUTE_ICV );
156 		if( cryptStatusError( status ) )
157 			return( status );
158 		*dataLength += sessionInfoPtr->authBlocksize;
159 		}
160 
161 	return( CRYPT_OK );
162 	}
163 
164 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
decryptData(SESSION_INFO * sessionInfoPtr,INOUT_BUFFER_FIXED (dataLength)BYTE * data,IN_DATALENGTH const int dataLength,OUT_DATALENGTH_Z int * processedDataLength)165 int decryptData( SESSION_INFO *sessionInfoPtr,
166 				 INOUT_BUFFER_FIXED( dataLength ) \
167 					BYTE *data,
168 				 IN_DATALENGTH const int dataLength,
169 				 OUT_DATALENGTH_Z int *processedDataLength )
170 	{
171 	int length = dataLength, padSize, status;
172 
173 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
174 	assert( isWritePtr( data, dataLength ) );
175 	assert( isWritePtr( processedDataLength, sizeof( int ) ) );
176 
177 	REQUIRES( dataLength > 0 && \
178 			  dataLength <= sessionInfoPtr->receiveBufEnd && \
179 			  dataLength < MAX_BUFFER_SIZE );
180 
181 	/* Clear return value */
182 	*processedDataLength = 0;
183 
184 	/* Decrypt the data */
185 	status = krnlSendMessage( sessionInfoPtr->iCryptInContext,
186 							  IMESSAGE_CTX_DECRYPT, data, length );
187 	if( cryptStatusError( status ) )
188 		{
189 		retExt( status,
190 				( status, SESSION_ERRINFO,
191 				  "Packet decryption failed" ) );
192 		}
193 
194 	/* If we're using GCM then we have to check the ICV that follows the
195 	   data */
196 	if( sessionInfoPtr->protocolFlags & SSL_PFLAG_GCM )
197 		{
198 		MESSAGE_DATA msgData;
199 
200 		setMessageData( &msgData, data + length,
201 						sessionInfoPtr->authBlocksize );
202 		status = krnlSendMessage( sessionInfoPtr->iCryptInContext,
203 								  IMESSAGE_COMPARE, &msgData,
204 								  MESSAGE_COMPARE_ICV );
205 		if( cryptStatusError( status ) )
206 			{
207 			retExt( CRYPT_ERROR_SIGNATURE,
208 					( CRYPT_ERROR_SIGNATURE, SESSION_ERRINFO,
209 					  "Bad message ICV for packet type %d, length %d",
210 					  data[ 0 ], length ) );
211 			}
212 		}
213 
214 	/* If it's a stream cipher then there's no padding present */
215 	if( sessionInfoPtr->cryptBlocksize <= 1 )
216 		{
217 		*processedDataLength = length;
218 
219 		return( CRYPT_OK );
220 		}
221 
222 	/* If it's a block cipher, we need to remove end-of-block padding.  Up
223 	   until TLS 1.1 the spec was silent about any requirement to check the
224 	   padding (and for SSLv3 it didn't specify the padding format at all)
225 	   so it's not really safe to reject an SSL message if we don't find the
226 	   correct padding because many SSL implementations didn't process the
227 	   padded data space in any way, leaving it containing whatever was
228 	   there before (which can include old plaintext (!!)).  Almost all TLS
229 	   implementations get it right (even though in TLS 1.0 there was only a
230 	   requirement to generate, but not to check, the PKCS #5-style
231 	   padding).  Because of this we only check the padding bytes if we're
232 	   talking TLS.
233 
234 	   First we make sure that the padding information looks OK.  TLS allows
235 	   up to 256 bytes of padding (only GnuTLS actually seems to use this
236 	   capability though) so we can't check for a sensible (small) padding
237 	   length, however we can check this for SSL, which is good because for
238 	   that we can't check the padding itself.
239 
240 	   There's no easy way to perform these checks in a timing-independent
241 	   manner because we're using them to reject completely malformed
242 	   packets (out-of-bounds array references), but hopefully the few
243 	   cycles difference won't be measurable in the overall scheme of
244 	   things */
245 	padSize = byteToInt( data[ dataLength - 1 ] );
246 	if( padSize < 0 || padSize > 255 || \
247 		( sessionInfoPtr->version == SSL_MINOR_VERSION_SSL && \
248 		  padSize > sessionInfoPtr->cryptBlocksize - 1 ) )
249 		{
250 		retExt( CRYPT_ERROR_BADDATA,
251 				( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
252 				  "Invalid encryption padding value 0x%02X (%d)",
253 				  padSize, padSize ) );
254 		}
255 	length -= padSize + 1;
256 	if( length < 0 || length > MAX_BUFFER_SIZE )
257 		{
258 		retExt( CRYPT_ERROR_BADDATA,
259 				( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
260 				  "Encryption padding adjustment value %d is greater "
261 				  "than packet length %d", padSize, dataLength ) );
262 		}
263 
264 	/* Check for PKCS #5-type padding (PKCS #5 uses n, TLS uses n-1) if
265 	   necessary, in a timing-independent manner */
266 	if( sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS )
267 		{
268 		int value = 0, i;
269 
270 		for( i = 0; i < padSize; i++ )
271 			value |= data[ length + i ] ^ padSize;
272 		if( value != 0 )
273 			{
274 			retExt( CRYPT_ERROR_BADDATA,
275 					( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
276 					  "Invalid encryption padding byte, expected 0x%02X",
277 					  padSize ) );
278 			}
279 		}
280 	*processedDataLength = length;
281 
282 	return( CRYPT_OK );
283 	}
284 
285 /****************************************************************************
286 *																			*
287 *								SSL MAC Functions							*
288 *																			*
289 ****************************************************************************/
290 
291 #ifdef USE_SSL3
292 
293 /* Proto-HMAC padding data */
294 
295 #define PROTOHMAC_PAD1_VALUE	0x36
296 #define PROTOHMAC_PAD2_VALUE	0x5C
297 #define PROTOHMAC_PAD1			"\x36\x36\x36\x36\x36\x36\x36\x36" \
298 								"\x36\x36\x36\x36\x36\x36\x36\x36" \
299 								"\x36\x36\x36\x36\x36\x36\x36\x36" \
300 								"\x36\x36\x36\x36\x36\x36\x36\x36" \
301 								"\x36\x36\x36\x36\x36\x36\x36\x36" \
302 								"\x36\x36\x36\x36\x36\x36\x36\x36"
303 #define PROTOHMAC_PAD2			"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" \
304 								"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" \
305 								"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" \
306 								"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" \
307 								"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" \
308 								"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
309 
310 /* Perform an SSL MAC of a data block.  We have to provide special-case
311    handling of zero-length blocks since some versions of OpenSSL send these
312    as a kludge in SSL/TLS 1.0 to work around chosen-IV attacks.
313 
314    In the following functions we don't check the return value of every
315    single component MAC operation since it would lead to endless sequences
316    of 'status = x; if( cSOK( x ) ) ...' chains, on the remote chance that
317    there's some transient failure in a single component operation it'll be
318    picked up at the end anyway when the overall MAC check fails */
319 
320 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
321 static int macDataSSL( IN_HANDLE const CRYPT_CONTEXT iHashContext,
322 					   IN_ALGO const CRYPT_ALGO_TYPE hashAlgo,
323 					   IN_BUFFER( macSecretLength ) \
324 							const void *macSecret,
325 					   IN_LENGTH_SHORT const int macSecretLength,
326 					   IN_INT_Z const long seqNo,
327 					   IN_BUFFER_OPT( dataLength ) const void *data,
328 					   IN_DATALENGTH_Z const int dataLength,
329 					   IN_RANGE( 0, 255 ) const int type )
330 	{
331 	MESSAGE_DATA msgData;
332 	STREAM stream;
333 	BYTE buffer[ 128 + 8 ];
334 	const int padSize = ( hashAlgo == CRYPT_ALGO_MD5 ) ? 48 : 40;
335 	int length DUMMY_INIT, status;
336 
337 	assert( isReadPtr( macSecret, macSecretLength ) );
338 	assert( ( data == NULL && dataLength == 0 ) || \
339 			isReadPtr( data, dataLength ) );
340 
341 	REQUIRES( isHandleRangeValid( iHashContext ) );
342 	REQUIRES( hashAlgo == CRYPT_ALGO_MD5 || \
343 			  hashAlgo == CRYPT_ALGO_SHA1 );
344 	REQUIRES( macSecretLength > 0 && \
345 			  macSecretLength < MAX_INTLENGTH_SHORT );
346 	REQUIRES( seqNo >= 0 );
347 	REQUIRES( ( data == NULL && dataLength == 0 ) || \
348 			  ( data != NULL && \
349 				dataLength > 0 && dataLength <= MAX_PACKET_SIZE ) );
350 	REQUIRES( type >= 0 && type <= 255 );
351 
352 	/* Set up the sequence number and length data */
353 	memset( buffer, PROTOHMAC_PAD1_VALUE, padSize );
354 	sMemOpen( &stream, buffer + padSize, 128 - padSize );
355 	writeUint64( &stream, seqNo );
356 	sputc( &stream, type );
357 	status = writeUint16( &stream, dataLength );
358 	if( cryptStatusOK( status ) )
359 		length = stell( &stream );
360 	sMemDisconnect( &stream );
361 	if( cryptStatusError( status ) )
362 		return( status );
363 
364 	/* Reset the hash context and generate the inner portion of the MAC:
365 
366 		hash( MAC_secret || pad1 || seq_num || type || length || data ) */
367 	krnlSendMessage( iHashContext, IMESSAGE_DELETEATTRIBUTE, NULL,
368 					 CRYPT_CTXINFO_HASHVALUE );
369 	krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
370 					 ( MESSAGE_CAST ) macSecret, macSecretLength );
371 	krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, buffer,
372 					 padSize + length );
373 	if( dataLength > 0 )
374 		krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
375 						 ( MESSAGE_CAST ) data, dataLength );
376 	status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 );
377 	if( cryptStatusError( status ) )
378 		return( status );
379 
380 	/* Extract the inner hash value */
381 	memset( buffer, PROTOHMAC_PAD2_VALUE, padSize );
382 	setMessageData( &msgData, buffer + padSize, CRYPT_MAX_HASHSIZE );
383 	status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE_S,
384 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
385 	if( cryptStatusError( status ) )
386 		return( status );
387 
388 	/* Generate the outer portion of the handshake message's MAC:
389 
390 		hash( MAC_secret || pad2 || inner_hash ) */
391 	krnlSendMessage( iHashContext, IMESSAGE_DELETEATTRIBUTE, NULL,
392 					 CRYPT_CTXINFO_HASHVALUE );
393 	krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
394 					 ( MESSAGE_CAST ) macSecret, macSecretLength );
395 	krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, buffer,
396 					 padSize + msgData.length );
397 	return( krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 ) );
398 	}
399 
400 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
401 int createMacSSL( INOUT SESSION_INFO *sessionInfoPtr,
402 				  INOUT_BUFFER( dataMaxLength, *dataLength ) void *data,
403 				  IN_DATALENGTH const int dataMaxLength,
404 				  OUT_DATALENGTH_Z int *dataLength,
405 				  IN_DATALENGTH const int payloadLength,
406 				  IN_RANGE( 0, 255 ) const int type )
407 	{
408 	SSL_INFO *sslInfo = sessionInfoPtr->sessionSSL;
409 	MESSAGE_DATA msgData;
410 	int status;
411 
412 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
413 	assert( isWritePtr( data, dataMaxLength ) );
414 	assert( isWritePtr( dataLength, sizeof( int ) ) );
415 
416 	REQUIRES( dataMaxLength > 0 && dataMaxLength < MAX_BUFFER_SIZE );
417 	REQUIRES( payloadLength > 0 && payloadLength <= MAX_PACKET_SIZE && \
418 			  payloadLength + sessionInfoPtr->authBlocksize <= dataMaxLength );
419 	REQUIRES( type >= 0 && type <= 255 );
420 
421 	/* Clear return value */
422 	*dataLength = 0;
423 
424 	/* MAC the payload */
425 	status = macDataSSL( sessionInfoPtr->iAuthOutContext,
426 						 sessionInfoPtr->integrityAlgo,
427 						 sslInfo->macWriteSecret,
428 						 sessionInfoPtr->authBlocksize, sslInfo->writeSeqNo,
429 						 data, payloadLength, type );
430 	if( cryptStatusError( status ) )
431 		return( status );
432 	sslInfo->writeSeqNo++;
433 
434 	/* Append the MAC value to the end of the packet */
435 	ENSURES( rangeCheck( payloadLength, sessionInfoPtr->authBlocksize,
436 						 dataMaxLength ) );
437 	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
438 					sessionInfoPtr->authBlocksize );
439 	status = krnlSendMessage( sessionInfoPtr->iAuthOutContext,
440 							  IMESSAGE_GETATTRIBUTE_S, &msgData,
441 							  CRYPT_CTXINFO_HASHVALUE );
442 	if( cryptStatusError( status ) )
443 		return( status );
444 	*dataLength = payloadLength + msgData.length;
445 
446 	return( CRYPT_OK );
447 	}
448 
449 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
450 int checkMacSSL( INOUT SESSION_INFO *sessionInfoPtr,
451 				 IN_BUFFER( dataLength ) const void *data,
452 				 IN_DATALENGTH const int dataLength,
453 				 IN_DATALENGTH_Z const int payloadLength,
454 				 IN_RANGE( 0, 255 ) const int type,
455 				 const BOOLEAN noReportError )
456 	{
457 	SSL_INFO *sslInfo = sessionInfoPtr->sessionSSL;
458 	MESSAGE_DATA msgData;
459 	int status;
460 
461 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
462 	assert( isReadPtr( data, dataLength ) );
463 
464 	REQUIRES( dataLength > 0 && dataLength < MAX_BUFFER_SIZE );
465 	REQUIRES( payloadLength >= 0 && payloadLength <= MAX_PACKET_SIZE && \
466 			  payloadLength + sessionInfoPtr->authBlocksize <= dataLength );
467 	REQUIRES( type >= 0 && type <= 255 );
468 
469 	/* MAC the payload.  If the payload length is zero then there's no data
470 	   payload, this can happen with some versions of OpenSSL that send
471 	   zero-length blocks as a kludge to work around pre-TLS 1.1 chosen-IV
472 	   attacks */
473 	if( payloadLength <= 0 )
474 		{
475 		status = macDataSSL( sessionInfoPtr->iAuthInContext,
476 							 sessionInfoPtr->integrityAlgo,
477 							 sslInfo->macReadSecret,
478 							 sessionInfoPtr->authBlocksize,
479 							 sslInfo->readSeqNo, NULL, 0, type );
480 		}
481 	else
482 		{
483 		status = macDataSSL( sessionInfoPtr->iAuthInContext,
484 							 sessionInfoPtr->integrityAlgo,
485 							 sslInfo->macReadSecret,
486 							 sessionInfoPtr->authBlocksize,
487 							 sslInfo->readSeqNo, data, payloadLength, type );
488 		}
489 	if( cryptStatusError( status ) )
490 		return( status );
491 	sslInfo->readSeqNo++;
492 
493 	/* Compare the calculated MAC to the MAC present at the end of the
494 	   data */
495 	ENSURES( rangeCheckZ( payloadLength, sessionInfoPtr->authBlocksize,
496 						  dataLength ) );
497 	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
498 					sessionInfoPtr->authBlocksize );
499 	status = krnlSendMessage( sessionInfoPtr->iAuthInContext,
500 							  IMESSAGE_COMPARE, &msgData,
501 							  MESSAGE_COMPARE_HASH );
502 	if( cryptStatusError( status ) )
503 		{
504 		/* If the error message has already been set at a higher level,
505 		   don't update the error information */
506 		if( noReportError )
507 			return( CRYPT_ERROR_SIGNATURE );
508 
509 		retExt( CRYPT_ERROR_SIGNATURE,
510 				( CRYPT_ERROR_SIGNATURE, SESSION_ERRINFO,
511 				  "Bad message MAC for packet type %d, length %d",
512 				  type, dataLength ) );
513 		}
514 
515 	return( CRYPT_OK );
516 	}
517 #endif /* USE_SSL3 */
518 
519 /****************************************************************************
520 *																			*
521 *								TLS MAC Functions							*
522 *																			*
523 ****************************************************************************/
524 
525 /* Perform a TLS MAC of a data block.  We have to provide special-case
526    handling of zero-length blocks since some versions of OpenSSL send these
527    as a kludge in SSL/TLS 1.0 to work around chosen-IV attacks.
528 
529    In the following functions we don't check the return value of every
530    single component MAC operation since it would lead to endless sequences
531    of 'status = x; if( cSOK( x ) ) ...' chains, on the remote chance that
532    there's some transient failure in a single component operation it'll be
533    picked up at the end anyway when the overall MAC check fails */
534 
535 CHECK_RETVAL \
536 static int macDataTLS( IN_HANDLE const CRYPT_CONTEXT iHashContext,
537 					   IN_INT_Z const long seqNo,
538 					   IN_RANGE( SSL_MINOR_VERSION_TLS, \
539 								 SSL_MINOR_VERSION_TLS12 ) const int version,
540 					   IN_BUFFER_OPT( ivLength ) const void *iv,
541 					   IN_LENGTH_IV_Z const int ivLength,
542 					   IN_BUFFER_OPT( dataLength ) const void *data,
543 					   IN_DATALENGTH_Z const int dataLength,
544 					   IN_RANGE( 0, 255 ) const int type )
545 	{
546 	BYTE buffer[ 64 + CRYPT_MAX_IVSIZE + 8 ];
547 	int length, status;
548 
549 	assert( ( iv == NULL && ivLength == 0 ) || \
550 			isReadPtr( iv, ivLength ) );
551 	assert( ( data == NULL && dataLength == 0 ) || \
552 			isReadPtr( data, dataLength ) );
553 
554 	REQUIRES( isHandleRangeValid( iHashContext ) );
555 	REQUIRES( seqNo >= 0 );
556 	REQUIRES( version >= SSL_MINOR_VERSION_TLS && \
557 			  version <= SSL_MINOR_VERSION_TLS12 );
558 	REQUIRES( ( iv == NULL && ivLength == 0 ) || \
559 			  ( iv != NULL && \
560 				ivLength > 0 && ivLength <= CRYPT_MAX_IVSIZE ) );
561 	REQUIRES( ( data == NULL && dataLength == 0 ) || \
562 			  ( data != NULL && \
563 				dataLength > 0 && dataLength <= MAX_PACKET_SIZE ) );
564 	REQUIRES( type >= 0 && type <= 255 );
565 
566 	/* Set up the packet metadata to be MACed */
567 	status = writePacketMetadata( buffer, 64, &length, type, seqNo, version,
568 								  dataLength + ivLength );
569 	if( cryptStatusError( status ) )
570 		return( status );
571 	if( ivLength > 0 )
572 		{
573 		/* If we're using an explicit IV, append it to the metadata for
574 		   MAC'ing */
575 		memcpy( buffer + length, iv, ivLength );
576 		length += ivLength;
577 		}
578 
579 	/* Reset the hash context and generate the MAC:
580 
581 		HMAC( metadata || (IV) || data ) */
582 	krnlSendMessage( iHashContext, IMESSAGE_DELETEATTRIBUTE, NULL,
583 					 CRYPT_CTXINFO_HASHVALUE );
584 	krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, buffer, length );
585 	if( dataLength > 0 )
586 		{
587 		krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
588 						 ( MESSAGE_CAST ) data, dataLength );
589 		}
590 	return( krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 ) );
591 	}
592 
593 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
594 int createMacTLS( INOUT SESSION_INFO *sessionInfoPtr,
595 				  INOUT_BUFFER( dataMaxLength, *dataLength ) void *data,
596 				  IN_DATALENGTH const int dataMaxLength,
597 				  OUT_DATALENGTH_Z int *dataLength,
598 				  IN_DATALENGTH const int payloadLength,
599 				  IN_RANGE( 0, 255 ) const int type )
600 	{
601 	SSL_INFO *sslInfo = sessionInfoPtr->sessionSSL;
602 	MESSAGE_DATA msgData;
603 	int status;
604 
605 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
606 	assert( isWritePtr( data, dataMaxLength ) );
607 	assert( isWritePtr( dataLength, sizeof( int ) ) );
608 
609 	REQUIRES( dataMaxLength > 0 && dataMaxLength < MAX_BUFFER_SIZE );
610 	REQUIRES( payloadLength > 0 && payloadLength <= MAX_PACKET_SIZE && \
611 			  payloadLength + sessionInfoPtr->authBlocksize <= dataMaxLength );
612 	REQUIRES( type >= 0 && type <= 255 );
613 
614 	/* Clear return values */
615 	*dataLength = 0;
616 
617 	/* MAC the payload.  When wrapping a packet the IV is treaded as part of
618 	   the payload so it's always passed in as { NULL, 0 }, it's only when
619 	   unwrapping that it's stripped before the payload data is copied into
620 	   the session buffer and so needs to be passed in explicitly */
621 	status = macDataTLS( sessionInfoPtr->iAuthOutContext, sslInfo->writeSeqNo,
622 						 sessionInfoPtr->version, NULL, 0, data,
623 						 payloadLength, type );
624 	if( cryptStatusError( status ) )
625 		return( status );
626 	sslInfo->writeSeqNo++;
627 
628 	/* Append the MAC value to the end of the packet */
629 	ENSURES( rangeCheck( payloadLength, sessionInfoPtr->authBlocksize,
630 						 dataMaxLength ) );
631 	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
632 					sessionInfoPtr->authBlocksize );
633 	status = krnlSendMessage( sessionInfoPtr->iAuthOutContext,
634 							  IMESSAGE_GETATTRIBUTE_S, &msgData,
635 							  CRYPT_CTXINFO_HASHVALUE );
636 	if( cryptStatusError( status ) )
637 		return( status );
638 	*dataLength = payloadLength + msgData.length;
639 
640 	return( CRYPT_OK );
641 	}
642 
643 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
644 int checkMacTLS( INOUT SESSION_INFO *sessionInfoPtr,
645 				 IN_BUFFER( dataLength ) const void *data,
646 				 IN_DATALENGTH const int dataLength,
647 				 IN_DATALENGTH_Z const int payloadLength,
648 				 IN_RANGE( 0, 255 ) const int type,
649 				 const BOOLEAN noReportError )
650 	{
651 	SSL_INFO *sslInfo = sessionInfoPtr->sessionSSL;
652 	MESSAGE_DATA msgData;
653 	const void *ivPtr = NULL;
654 	int ivLength = 0, status;
655 
656 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
657 	assert( isReadPtr( data, dataLength ) );
658 
659 	REQUIRES( dataLength > 0 && dataLength < MAX_BUFFER_SIZE );
660 	REQUIRES( payloadLength >= 0 && payloadLength <= MAX_PACKET_SIZE && \
661 			  payloadLength + sessionInfoPtr->authBlocksize <= dataLength );
662 	REQUIRES( type >= 0 && type <= 255 );
663 
664 	/* MAC the payload.  If the payload length is zero then there's no data
665 	   payload, this can happen with some versions of OpenSSL that send
666 	   zero-length blocks as a kludge to work around pre-TLS 1.1 chosen-IV
667 	   attacks */
668 	if( ( sessionInfoPtr->protocolFlags & SSL_PFLAG_ENCTHENMAC ) && \
669 		sslInfo->ivSize > 0 )
670 		{
671 		/* When using encrypt-then-MAC and TLS 1.1+ explicit IVs, the IV is
672 		   authenticated alongside the encrypted payload data */
673 		ivPtr = sslInfo->iv;
674 		ivLength = sslInfo->ivSize;
675 		}
676 	if( payloadLength <= 0 )
677 		{
678 		status = macDataTLS( sessionInfoPtr->iAuthInContext,
679 							 sslInfo->readSeqNo, sessionInfoPtr->version,
680 							 ivPtr, ivLength, NULL, 0, type );
681 		}
682 	else
683 		{
684 		status = macDataTLS( sessionInfoPtr->iAuthInContext,
685 							 sslInfo->readSeqNo, sessionInfoPtr->version,
686 							 ivPtr, ivLength, data, payloadLength, type );
687 		}
688 	if( cryptStatusError( status ) )
689 		return( status );
690 	sslInfo->readSeqNo++;
691 
692 	/* Compare the calculated MAC to the MAC present at the end of the
693 	   data */
694 	ENSURES( rangeCheckZ( payloadLength, sessionInfoPtr->authBlocksize,
695 						  dataLength ) );
696 	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
697 					sessionInfoPtr->authBlocksize );
698 	status = krnlSendMessage( sessionInfoPtr->iAuthInContext,
699 							  IMESSAGE_COMPARE, &msgData,
700 							  MESSAGE_COMPARE_HASH );
701 	if( cryptStatusError( status ) )
702 		{
703 		/* If the error message has already been set at a higher level,
704 		   don't update the error information */
705 		if( noReportError )
706 			return( CRYPT_ERROR_SIGNATURE );
707 
708 		retExt( CRYPT_ERROR_SIGNATURE,
709 				( CRYPT_ERROR_SIGNATURE, SESSION_ERRINFO,
710 				  "Bad message MAC for packet type %d, length %d",
711 				  type, dataLength ) );
712 		}
713 
714 	return( CRYPT_OK );
715 	}
716 
717 /****************************************************************************
718 *																			*
719 *								TLS GCM Functions							*
720 *																			*
721 ****************************************************************************/
722 
723 #ifdef USE_GCM
724 
725 /* Perform a TLS GCM integrity check of a data block.  This differs somewhat
726    from the more conventional MACing routines because GCM combines the ICV
727    generation with encryption, so all that we're actually doing is
728    generating the initial stage of the ICV over the packet metadata handled
729    as GCM AAD */
730 
731 CHECK_RETVAL \
732 int macDataTLSGCM( IN_HANDLE const CRYPT_CONTEXT iCryptContext,
733 				   IN_INT_Z const long seqNo,
734 				   IN_RANGE( SSL_MINOR_VERSION_TLS, \
735 							 SSL_MINOR_VERSION_TLS12 ) const int version,
736 				   IN_LENGTH_Z const int payloadLength,
737 				   IN_RANGE( 0, 255 ) const int type )
738 	{
739 	MESSAGE_DATA msgData;
740 	BYTE buffer[ 64 + 8 ];
741 	int length, status;
742 
743 	REQUIRES( isHandleRangeValid( iCryptContext ) );
744 	REQUIRES( seqNo >= 0 );
745 	REQUIRES( version >= SSL_MINOR_VERSION_TLS && \
746 			  version <= SSL_MINOR_VERSION_TLS12 );
747 	REQUIRES( payloadLength >= 0 && payloadLength <= MAX_PACKET_SIZE );
748 	REQUIRES( type >= 0 && type <= 255 );
749 
750 	/* Set up the packet metadata to be MACed */
751 	status = writePacketMetadata( buffer, 64, &length, type, seqNo,
752 								  version, payloadLength );
753 	if( cryptStatusError( status ) )
754 		return( status );
755 
756 	/* Send the AAD to the GCM context for inclusion in the ICV
757 	   calculation */
758 	setMessageData( &msgData, buffer, length );
759 	return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
760 							 &msgData, CRYPT_IATTRIBUTE_AAD ) );
761 	}
762 #endif /* USE_GCM */
763 
764 /****************************************************************************
765 *																			*
766 *					Handshake Message Hash/MAC Functions					*
767 *																			*
768 ****************************************************************************/
769 
770 /* Perform assorted hashing of a data block, a dual dual MD5+SHA-1 hash for
771    SSL or straight SHA-2 hash for TLS 1.2+.  Since this is part of an
772    ongoing message exchange (in other words a failure potentially won't be
773    detected for some time) we check each return value.  This processing was
774    originally done using a dual MD5+SHA-1 hash, however TLS 1.2+ switched to
775    using a single SHA-2 hash, because of this we have to explicitly check
776    which hashing option we're using (in some cases it might be both since we
777    have to speculatively hash initial messages until we've agreed on a
778    version) and only use that hash.
779 
780    In addition to the overall hashing we may also be running a separate hash
781    of the messages that stops before the other hashing does if certificate-
782    based client authentication is being used.  This would add even more
783    overhead to the whole process, however since it's only used with TLS 1.2+
784    and in that case is restricted to using SHA-2 via hashing preferences
785    sent in the hello messages, we can obtain the necessary hash value by
786    cloning the SHA-2 context when we have to generate or verify the client
787    signature */
788 
789 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
hashHSData(const SSL_HANDSHAKE_INFO * handshakeInfo,IN_BUFFER (dataLength)const void * data,IN_DATALENGTH const int dataLength)790 static int hashHSData( const SSL_HANDSHAKE_INFO *handshakeInfo,
791 					   IN_BUFFER( dataLength ) const void *data,
792 					   IN_DATALENGTH const int dataLength )
793 	{
794 	int status;
795 
796 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
797 	assert( isReadPtr( data, dataLength ) );
798 
799 	REQUIRES( dataLength > 0 && dataLength < MAX_BUFFER_SIZE );
800 
801 	if( handshakeInfo->md5context != CRYPT_ERROR )
802 		{
803 		status = krnlSendMessage( handshakeInfo->md5context,
804 								  IMESSAGE_CTX_HASH, ( MESSAGE_CAST ) data,
805 								  dataLength );
806 		if( cryptStatusOK( status ) )
807 			status = krnlSendMessage( handshakeInfo->sha1context,
808 									  IMESSAGE_CTX_HASH, ( MESSAGE_CAST ) data,
809 									  dataLength );
810 		if( cryptStatusError( status ) )
811 			return( status );
812 		}
813 	if( handshakeInfo->sha2context != CRYPT_ERROR )
814 		{
815 		status = krnlSendMessage( handshakeInfo->sha2context,
816 								  IMESSAGE_CTX_HASH, ( MESSAGE_CAST ) data,
817 								  dataLength );
818 		if( cryptStatusError( status ) )
819 			return( status );
820 		}
821 #ifdef CONFIG_SUITEB
822 	if( handshakeInfo->sha384context != CRYPT_ERROR )
823 		{
824 		status = krnlSendMessage( handshakeInfo->sha384context,
825 								  IMESSAGE_CTX_HASH, ( MESSAGE_CAST ) data,
826 								  dataLength );
827 		if( cryptStatusError( status ) )
828 			return( status );
829 		}
830 #endif /* CONFIG_SUITEB */
831 
832 	return( CRYPT_OK );
833 	}
834 
835 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
hashHSPacketRead(const SSL_HANDSHAKE_INFO * handshakeInfo,INOUT STREAM * stream)836 int hashHSPacketRead( const SSL_HANDSHAKE_INFO *handshakeInfo,
837 					  INOUT STREAM *stream )
838 	{
839 	const int dataLength = sMemDataLeft( stream );
840 	void *data;
841 	int status;
842 
843 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
844 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
845 
846 	REQUIRES( dataLength > 0 && dataLength < MAX_BUFFER_SIZE );
847 
848 	/* On a read we've just processed the packet header and everything
849 	   that's left in the stream is the data to be MACd.  Note that we can't
850 	   use sMemGetDataBlockRemaining() for this because that returns the
851 	   entire available buffer, not just the amount of data in the buffer */
852 	status = sMemGetDataBlock( stream, &data, dataLength );
853 	if( cryptStatusOK( status ) )
854 		{
855 		ANALYSER_HINT( data != NULL );
856 		status = hashHSData( handshakeInfo, data, dataLength );
857 		}
858 	return( status );
859 	}
860 
861 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
hashHSPacketWrite(const SSL_HANDSHAKE_INFO * handshakeInfo,INOUT STREAM * stream,IN_DATALENGTH_Z const int offset)862 int hashHSPacketWrite( const SSL_HANDSHAKE_INFO *handshakeInfo,
863 					   INOUT STREAM *stream,
864 					   IN_DATALENGTH_Z const int offset )
865 	{
866 	const int dataStart = offset + SSL_HEADER_SIZE;
867 	const int dataLength = stell( stream ) - dataStart;
868 	void *data;
869 	int status;
870 
871 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
872 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
873 
874 	REQUIRES( offset >= 0 && offset < MAX_BUFFER_SIZE );
875 	REQUIRES( dataLength > 0 && dataLength < MAX_BUFFER_SIZE );
876 
877 	/* On a write we've just finished writing the packet and everything but
878 	   the header needs to be MACd */
879 	status = sMemGetDataBlockAbs( stream, dataStart, &data, dataLength );
880 	if( cryptStatusOK( status ) )
881 		{
882 		ANALYSER_HINT( data != NULL );
883 		status = hashHSData( handshakeInfo, data, dataLength );
884 		}
885 	return( status );
886 	}
887 
888 /* Complete the dual MD5/SHA1 hash/MAC or SHA2 MAC that's used in the
889    finished message.  There are no less than three variations of this, one
890    for SSL's dual MAC, one for TLS 1.0 - 1.1's IPsec cargo cult 96-bit
891    PRF'd dual MAC, and one for TLS 1.2's similarly cargo-cult 96-bit PRF'd
892    single MAC.
893 
894    We don't check the return value of every single component MAC operation
895    since it would lead to endless sequences of 'status = x;
896    if( cSOK( x ) ) ...' chains, on the remote chance that there's some
897    transient failure in a single component operation it'll be picked up at
898    the end anyway when the overall MAC check fails */
899 
900 #ifdef USE_SSL3
901 
902 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 5, 6, 8 ) ) \
903 int completeSSLDualMAC( IN_HANDLE const CRYPT_CONTEXT md5context,
904 						IN_HANDLE const CRYPT_CONTEXT sha1context,
905 						OUT_BUFFER( hashValuesMaxLen, *hashValuesLen )
906 							BYTE *hashValues,
907 						IN_LENGTH_SHORT_MIN( MD5MAC_SIZE + SHA1MAC_SIZE ) \
908 							const int hashValuesMaxLen,
909 						OUT_LENGTH_BOUNDED_Z( hashValuesMaxLen ) \
910 							int *hashValuesLen,
911 						IN_BUFFER( labelLength ) const char *label,
912 						IN_RANGE( 1, 64 ) const int labelLength,
913 						IN_BUFFER( masterSecretLen ) const BYTE *masterSecret,
914 						IN_LENGTH_SHORT const int masterSecretLen )
915 	{
916 	MESSAGE_DATA msgData;
917 	int status;
918 
919 	assert( isWritePtr( hashValues, hashValuesMaxLen ) );
920 	assert( isWritePtr( hashValuesLen, sizeof( int ) ) );
921 	assert( isReadPtr( label, labelLength ) );
922 	assert( isReadPtr( masterSecret, masterSecretLen ) );
923 
924 	REQUIRES( isHandleRangeValid( md5context ) );
925 	REQUIRES( isHandleRangeValid( sha1context ) );
926 	REQUIRES( hashValuesMaxLen >= MD5MAC_SIZE + SHA1MAC_SIZE && \
927 			  hashValuesMaxLen < MAX_INTLENGTH_SHORT );
928 	REQUIRES( labelLength > 0 && labelLength <= 64 );
929 	REQUIRES( masterSecretLen > 0 && masterSecretLen < MAX_INTLENGTH_SHORT );
930 
931 	/* Clear return value */
932 	*hashValuesLen = 0;
933 
934 	/* Generate the inner portion of the handshake message's MAC:
935 
936 		hash( handshake_messages || cl/svr_label || master_secret || pad1 )
937 
938 	   Note that the SHA-1 pad size is 40 bytes and not 44 (to get a total
939 	   length of 64 bytes), this is due to an error in the spec */
940 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH,
941 					 ( MESSAGE_CAST ) label, labelLength );
942 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH,
943 					 ( MESSAGE_CAST ) label, labelLength );
944 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH,
945 					 ( MESSAGE_CAST ) masterSecret, masterSecretLen );
946 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH,
947 					 ( MESSAGE_CAST ) masterSecret, masterSecretLen );
948 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD1, 48 );
949 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD1, 40 );
950 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, "", 0 );
951 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, "", 0 );
952 	setMessageData( &msgData, hashValues, MD5MAC_SIZE );
953 	status = krnlSendMessage( md5context, IMESSAGE_GETATTRIBUTE_S,
954 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
955 	if( cryptStatusOK( status ) )
956 		{
957 		setMessageData( &msgData, hashValues + MD5MAC_SIZE, SHA1MAC_SIZE );
958 		status = krnlSendMessage( sha1context, IMESSAGE_GETATTRIBUTE_S,
959 								  &msgData, CRYPT_CTXINFO_HASHVALUE );
960 		}
961 	if( cryptStatusError( status ) )
962 		return( status );
963 
964 	/* Reset the hash contexts */
965 	krnlSendMessage( md5context, IMESSAGE_DELETEATTRIBUTE, NULL,
966 					 CRYPT_CTXINFO_HASHVALUE );
967 	krnlSendMessage( sha1context, IMESSAGE_DELETEATTRIBUTE, NULL,
968 					 CRYPT_CTXINFO_HASHVALUE );
969 
970 	/* Generate the outer portion of the handshake message's MAC:
971 
972 		hash( master_secret || pad2 || inner_hash ) */
973 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH,
974 					 ( MESSAGE_CAST ) masterSecret, masterSecretLen );
975 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH,
976 					 ( MESSAGE_CAST ) masterSecret, masterSecretLen );
977 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD2, 48 );
978 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD2, 40 );
979 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, hashValues,
980 					 MD5MAC_SIZE );
981 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, hashValues + MD5MAC_SIZE,
982 					 SHA1MAC_SIZE );
983 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, "", 0 );
984 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, "", 0 );
985 	setMessageData( &msgData, hashValues, MD5MAC_SIZE );
986 	status = krnlSendMessage( md5context, IMESSAGE_GETATTRIBUTE_S,
987 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
988 	if( cryptStatusError( status ) )
989 		return( status );
990 	setMessageData( &msgData, hashValues + MD5MAC_SIZE, SHA1MAC_SIZE );
991 	status = krnlSendMessage( sha1context, IMESSAGE_GETATTRIBUTE_S,
992 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
993 	if( cryptStatusOK( status ) )
994 		*hashValuesLen = MD5MAC_SIZE + SHA1MAC_SIZE;
995 	return( status );
996 	}
997 #endif /* USE_SSL3 */
998 
999 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 5, 6, 8 ) ) \
1000 int completeTLSHashedMAC( IN_HANDLE const CRYPT_CONTEXT md5context,
1001 						  IN_HANDLE const CRYPT_CONTEXT sha1context,
1002 						  OUT_BUFFER( hashValuesMaxLen, *hashValuesLen )
1003 								BYTE *hashValues,
1004 						  IN_LENGTH_SHORT_MIN( TLS_HASHEDMAC_SIZE ) \
1005 								const int hashValuesMaxLen,
1006 						  OUT_LENGTH_BOUNDED_Z( hashValuesMaxLen ) \
1007 								int *hashValuesLen,
1008 						  IN_BUFFER( labelLength ) const char *label,
1009 						  IN_RANGE( 1, 64 ) const int labelLength,
1010 						  IN_BUFFER( masterSecretLen ) \
1011 								const BYTE *masterSecret,
1012 						  IN_LENGTH_SHORT const int masterSecretLen )
1013 	{
1014 	MECHANISM_DERIVE_INFO mechanismInfo;
1015 	MESSAGE_DATA msgData;
1016 	BYTE hashBuffer[ 64 + ( CRYPT_MAX_HASHSIZE * 2 ) + 8 ];
1017 	int status;
1018 
1019 	assert( isWritePtr( hashValues, hashValuesMaxLen ) );
1020 	assert( isWritePtr( hashValuesLen, sizeof( int ) ) );
1021 	assert( isReadPtr( label, labelLength ) );
1022 	assert( isReadPtr( masterSecret, masterSecretLen ) );
1023 
1024 	REQUIRES( isHandleRangeValid( md5context ) );
1025 	REQUIRES( isHandleRangeValid( sha1context ) );
1026 	REQUIRES( hashValuesMaxLen >= TLS_HASHEDMAC_SIZE && \
1027 			  hashValuesMaxLen < MAX_INTLENGTH_SHORT );
1028 	REQUIRES( labelLength > 0 && labelLength <= 64 && \
1029 			  labelLength + MD5MAC_SIZE + SHA1MAC_SIZE <= \
1030 						64 + ( CRYPT_MAX_HASHSIZE * 2 ) );
1031 
1032 	/* Clear return value */
1033 	*hashValuesLen = 0;
1034 
1035 	memcpy( hashBuffer, label, labelLength );
1036 
1037 	/* Complete the hashing and get the MD5 and SHA-1 hashes */
1038 	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, "", 0 );
1039 	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, "", 0 );
1040 	setMessageData( &msgData, hashBuffer + labelLength, MD5MAC_SIZE );
1041 	status = krnlSendMessage( md5context, IMESSAGE_GETATTRIBUTE_S,
1042 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
1043 	if( cryptStatusOK( status ) )
1044 		{
1045 		setMessageData( &msgData, hashBuffer + labelLength + MD5MAC_SIZE,
1046 						SHA1MAC_SIZE );
1047 		status = krnlSendMessage( sha1context, IMESSAGE_GETATTRIBUTE_S,
1048 								  &msgData, CRYPT_CTXINFO_HASHVALUE );
1049 		}
1050 	if( cryptStatusError( status ) )
1051 		return( status );
1052 
1053 	/* Generate the TLS check value.  This isn't really a hash or a MAC but
1054 	   is generated by feeding the MD5 and SHA1 hashes of the handshake
1055 	   messages into the TLS key derivation (PRF) function and truncating
1056 	   the result to 12 bytes (96 bits) IPsec cargo cult protocol design
1057 	   purposes:
1058 
1059 		TLS_PRF( label || MD5_hash || SHA1_hash ) */
1060 	setMechanismDeriveInfo( &mechanismInfo, hashValues,
1061 							TLS_HASHEDMAC_SIZE, ( MESSAGE_CAST ) masterSecret,
1062 							masterSecretLen,
1063 							( CRYPT_ALGO_TYPE ) CRYPT_USE_DEFAULT, hashBuffer,
1064 							labelLength + MD5MAC_SIZE + SHA1MAC_SIZE, 1 );
1065 	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_DERIVE,
1066 							  &mechanismInfo, MECHANISM_DERIVE_TLS );
1067 	if( cryptStatusOK( status ) )
1068 		*hashValuesLen = TLS_HASHEDMAC_SIZE;
1069 	return( status );
1070 	}
1071 
1072 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 4, 5, 7 ) ) \
1073 int completeTLS12HashedMAC( IN_HANDLE const CRYPT_CONTEXT sha2context,
1074 							OUT_BUFFER( hashValuesMaxLen, *hashValuesLen ) \
1075 								BYTE *hashValues,
1076 							IN_LENGTH_SHORT_MIN( TLS_HASHEDMAC_SIZE ) \
1077 								const int hashValuesMaxLen,
1078 							OUT_LENGTH_BOUNDED_Z( hashValuesMaxLen ) \
1079 								int *hashValuesLen,
1080 							IN_BUFFER( labelLength ) const char *label,
1081 							IN_RANGE( 1, 64 ) const int labelLength,
1082 							IN_BUFFER( masterSecretLen ) \
1083 								const BYTE *masterSecret,
1084 							IN_LENGTH_SHORT const int masterSecretLen )
1085 	{
1086 	MECHANISM_DERIVE_INFO mechanismInfo;
1087 	MESSAGE_DATA msgData;
1088 	BYTE hashBuffer[ 64 + ( CRYPT_MAX_HASHSIZE * 2 ) + 8 ];
1089 	int macSize, status;
1090 
1091 	assert( isWritePtr( hashValues, hashValuesMaxLen ) );
1092 	assert( isWritePtr( hashValuesLen, sizeof( int ) ) );
1093 	assert( isReadPtr( label, labelLength ) );
1094 	assert( isReadPtr( masterSecret, masterSecretLen ) );
1095 
1096 	REQUIRES( isHandleRangeValid( sha2context ) );
1097 	REQUIRES( hashValuesMaxLen >= TLS_HASHEDMAC_SIZE && \
1098 			  hashValuesMaxLen < MAX_INTLENGTH_SHORT );
1099 	REQUIRES( labelLength > 0 && labelLength <= 64 && \
1100 			  labelLength + CRYPT_MAX_HASHSIZE <= 64 + ( CRYPT_MAX_HASHSIZE ) );
1101 
1102 	/* Clear return value */
1103 	*hashValuesLen = 0;
1104 
1105 	memcpy( hashBuffer, label, labelLength );
1106 
1107 	/* Get the MAC size */
1108 	status = krnlSendMessage( sha2context, IMESSAGE_GETATTRIBUTE, &macSize,
1109 							  CRYPT_CTXINFO_BLOCKSIZE );
1110 	if( cryptStatusError( status ) )
1111 		return( status );
1112 
1113 	/* Complete the hashing and get the SHA-2 hash */
1114 	krnlSendMessage( sha2context, IMESSAGE_CTX_HASH, "", 0 );
1115 	setMessageData( &msgData, hashBuffer + labelLength, macSize );
1116 	status = krnlSendMessage( sha2context, IMESSAGE_GETATTRIBUTE_S,
1117 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
1118 	if( cryptStatusError( status ) )
1119 		return( status );
1120 
1121 	/* Generate the TLS check value.  This isn't really a hash or a MAC but
1122 	   is generated by feeding the SHA-2 hash of the handshake messages into
1123 	   the TLS key derivation (PRF) function and truncating the result to 12
1124 	   bytes (96 bits) for IPsec cargo cult protocol design purposes:
1125 
1126 		TLS_PRF( label || SHA2_hash ) */
1127 	setMechanismDeriveInfo( &mechanismInfo, hashValues,
1128 							TLS_HASHEDMAC_SIZE, ( MESSAGE_CAST ) masterSecret,
1129 							masterSecretLen, CRYPT_ALGO_SHA2, hashBuffer,
1130 							labelLength + macSize, 1 );
1131 	if( macSize != bitsToBytes( 256 ) )
1132 		mechanismInfo.hashParam = macSize;
1133 	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_DERIVE,
1134 							  &mechanismInfo, MECHANISM_DERIVE_TLS12 );
1135 	if( cryptStatusOK( status ) )
1136 		*hashValuesLen = TLS_HASHEDMAC_SIZE;
1137 	return( status );
1138 	}
1139 
1140 /****************************************************************************
1141 *																			*
1142 *						Client-Auth Signature Functions						*
1143 *																			*
1144 ****************************************************************************/
1145 
1146 /* Create/check the signature on an SSL certificate verify message.
1147    SSLv3/TLS use a weird signature format that dual-MACs (SSLv3) or hashes
1148    (TLS) all of the handshake messages exchanged to date (SSLv3 additionally
1149    hashes in further data like the master secret), then signs them using
1150    nonstandard PKCS #1 RSA without the ASN.1 wrapper (that is, it uses the
1151    raw concatenated SHA-1 and MD5 MAC (SSL) or hash (TLS) of the handshake
1152    messages with PKCS #1 padding prepended), unless we're using DSA in which
1153    case it drops the MD5 MAC/hash and uses only the SHA-1 one.
1154 
1155    This is an incredible pain to support because it requires running a
1156    parallel hash of handshake messages that terminates before the main
1157    hashing does, further hashing/MAC'ing of additional data, and the use of
1158    weird nonstandard data formats and signature mechanisms that aren't
1159    normally supported by anything.  For example if the signing is to be done
1160    via a smart card then we can't use the standard PKCS #1 sig mechanism, we
1161    can't even use raw RSA and kludge the format together ourselves because
1162    some PKCS #11 implementations don't support the _X509 (raw) mechanism,
1163    what we have to do is tunnel the nonstandard sig.format information down
1164    through several cryptlib layers and then hope that the PKCS #11
1165    implementation that we're using (a) supports this format and (b) gets it
1166    right.
1167 
1168    Another problem (which only occurs for SSLv3) is that the MAC requires
1169    the use of the master secret, which isn't available for several hundred
1170    more lines of code, so we have to delay producing any more data packets
1171    until the master secret is available (either that or squirrel all packets
1172    away in some buffer somewhere so that they can be hashed later), which
1173    severely screws up the handshake processing flow.  TLS is slightly better
1174    here since it simply signs MD5-hash || SHA1-hash without requiring the
1175    use of the master secret, but even then it requires speculatively running
1176    an MD5 and SHA-1 hash of all messages on every exchange on the remote
1177    chance that the client will be using client certificates.  TLS 1.2
1178    finally moved to using standard signatures (PKCS #1 for RSA, conventional
1179    signatures for DSA/ECDSA), but still requires the speculative hashing of
1180    handshake messages.
1181 
1182    The chances of all of this custom data and signature handling working
1183    correctly are fairly low, and in any case there's no advantage to the
1184    weird mechanism and format used in SSL/TLS, all that we actually need to
1185    do is sign the client and server nonces to ensure signature freshness.
1186    Because of this what we actually do is just this, after which we create a
1187    standard PKCS #1 signature via the normal cryptlib mechanisms, which
1188    guarantees that it'll work with native cryptlib as well as any crypto
1189    hardware implementation.  Since client certificates are hardly ever used
1190    and when they are it's in a closed environment, it's extremely unlikely
1191    that anyone will ever notice.  There'll be far more problems in trying to
1192    use the nonstandard SSL/TLS signature mechanism than there are with using
1193    a standard (but not-in-the-spec) one.
1194 
1195    The one exception to this is, as already mentioned above, TLS 1.2+, for
1196    which we can finally use a standard signature.  In this case we take
1197    a clone of the SHA-2 context that's been used to hash the handshake
1198    messages so far (the use of SHA-2 for this is enforced by the judicious
1199    use of TLS extensions, see the comments in ssl_ext.c for more on this)
1200    and sign that */
1201 
1202 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
createCertVerifyAltHash(const SSL_HANDSHAKE_INFO * handshakeInfo,OUT_HANDLE_OPT CRYPT_CONTEXT * iHashContext)1203 static int createCertVerifyAltHash( const SSL_HANDSHAKE_INFO *handshakeInfo,
1204 									OUT_HANDLE_OPT CRYPT_CONTEXT *iHashContext )
1205 	{
1206 	MESSAGE_CREATEOBJECT_INFO createInfo;
1207 	BYTE nonceBuffer[ 64 + SSL_NONCE_SIZE + SSL_NONCE_SIZE + 8 ];
1208 	int status;
1209 
1210 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1211 	assert( isWritePtr( iHashContext, sizeof( CRYPT_CONTEXT ) ) );
1212 
1213 	/* Clear return value */
1214 	*iHashContext = CRYPT_ERROR;
1215 
1216 	/* Hash the client and server nonces */
1217 	setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_SHA1 );
1218 	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1219 							  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1220 							  OBJECT_TYPE_CONTEXT );
1221 	if( cryptStatusError( status ) )
1222 		return( status );
1223 	memcpy( nonceBuffer, "certificate verify", 18 );
1224 	memcpy( nonceBuffer + 18, handshakeInfo->clientNonce, SSL_NONCE_SIZE );
1225 	memcpy( nonceBuffer + 18 + SSL_NONCE_SIZE, handshakeInfo->serverNonce,
1226 			SSL_NONCE_SIZE );
1227 	status = krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CTX_HASH,
1228 							  nonceBuffer,
1229 							  18 + SSL_NONCE_SIZE + SSL_NONCE_SIZE );
1230 	if( cryptStatusOK( status ) )
1231 		status = krnlSendMessage( createInfo.cryptHandle,
1232 								  IMESSAGE_CTX_HASH, nonceBuffer, 0 );
1233 	if( cryptStatusError( status ) )
1234 		{
1235 		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
1236 		return( status );
1237 		}
1238 	*iHashContext = createInfo.cryptHandle;
1239 
1240 	return( CRYPT_OK );
1241 	}
1242 
1243 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 4 ) ) \
getSessionHash(IN_HANDLE const CRYPT_CONTEXT iHashContext,OUT_BUFFER (hashValueMaxLen,* hashValueLen)void * hashValue,IN_LENGTH_HASH const int hashValueMaxLen,OUT_LENGTH_HASH_Z int * hashValueLen)1244 static int getSessionHash( IN_HANDLE const CRYPT_CONTEXT iHashContext,
1245 						   OUT_BUFFER( hashValueMaxLen, *hashValueLen ) \
1246 								void *hashValue,
1247 						   IN_LENGTH_HASH const int hashValueMaxLen,
1248 						   OUT_LENGTH_HASH_Z int *hashValueLen )
1249 	{
1250 	MESSAGE_DATA msgData;
1251 	int status;
1252 
1253 	assert( isWritePtr( hashValue, hashValueMaxLen ) );
1254 	assert( isWritePtr( hashValueLen, sizeof( int ) ) );
1255 
1256 	REQUIRES( isHandleRangeValid( iHashContext ) );
1257 	REQUIRES( hashValueMaxLen >= 16 && \
1258 			  hashValueMaxLen <= CRYPT_MAX_HASHSIZE );
1259 
1260 	/* Clear return values */
1261 	memset( hashValue, 0, min( 16, hashValueMaxLen ) );
1262 	*hashValueLen = 0;
1263 
1264 	/* Wrap up the hashing and record the hash value */
1265 	status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 );
1266 	if( cryptStatusError( status ) )
1267 		return( status );
1268 	setMessageData( &msgData, hashValue, hashValueMaxLen );
1269 	status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE_S,
1270 							  &msgData, CRYPT_CTXINFO_HASHVALUE );
1271 	if( cryptStatusError( status ) )
1272 		return( status );
1273 	*hashValueLen = msgData.length;
1274 
1275 	return( CRYPT_OK );
1276 	}
1277 
1278 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
createSessionHash(const SESSION_INFO * sessionInfoPtr,INOUT SSL_HANDSHAKE_INFO * handshakeInfo)1279 int createSessionHash( const SESSION_INFO *sessionInfoPtr,
1280 					   INOUT SSL_HANDSHAKE_INFO *handshakeInfo )
1281 	{
1282 	CRYPT_CONTEXT iHashContext;
1283 	int status;
1284 
1285 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1286 
1287 	/* Clone the current hash state, complete the hashing for the cloned
1288 	   context(s), and get the hash value(s) */
1289 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1290 		{
1291 		int hash1Size, hash2Size;
1292 
1293 		/* TLS < 1.2 uses an MD5/SHA1 dual hash so we have to extract both
1294 		   hash values and concatenate them */
1295 		status = cloneHashContext( handshakeInfo->md5context, &iHashContext );
1296 		if( cryptStatusError( status ) )
1297 			return( status );
1298 		status = getSessionHash( iHashContext, handshakeInfo->sessionHash,
1299 								 CRYPT_MAX_HASHSIZE, &hash1Size );
1300 		krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1301 		if( cryptStatusError( status ) )
1302 			return( status );
1303 		status = cloneHashContext( handshakeInfo->sha1context, &iHashContext );
1304 		if( cryptStatusError( status ) )
1305 			return( status );
1306 		status = getSessionHash( iHashContext,
1307 								 handshakeInfo->sessionHash + hash1Size,
1308 								 CRYPT_MAX_HASHSIZE - hash1Size, &hash2Size );
1309 		if( cryptStatusError( status ) )
1310 			{
1311 			krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1312 			return( status );
1313 			}
1314 		handshakeInfo->sessionHashSize = hash1Size + hash2Size;
1315 		}
1316 	else
1317 		{
1318 		/* TLS 1.2 uses a single hash value */
1319 		if( handshakeInfo->sha2context != CRYPT_ERROR )
1320 			status = cloneHashContext( handshakeInfo->sha2context, &iHashContext );
1321 		else
1322 			status = cloneHashContext( handshakeInfo->sha1context, &iHashContext );
1323 		if( cryptStatusError( status ) )
1324 			return( status );
1325 		status = getSessionHash( iHashContext, handshakeInfo->sessionHash,
1326 								 CRYPT_MAX_HASHSIZE,
1327 								 &handshakeInfo->sessionHashSize );
1328 		if( cryptStatusError( status ) )
1329 			{
1330 			krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1331 			return( status );
1332 			}
1333 		}
1334 	handshakeInfo->sessionHashContext = iHashContext;
1335 
1336 	DEBUG_PRINT(( "Session hash:\n" ));
1337 	DEBUG_DUMP_DATA( handshakeInfo->sessionHash,
1338 					 handshakeInfo->sessionHashSize );
1339 
1340 	return( CRYPT_OK );
1341 	}
1342 
1343 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
createCertVerify(const SESSION_INFO * sessionInfoPtr,INOUT SSL_HANDSHAKE_INFO * handshakeInfo,INOUT STREAM * stream)1344 int createCertVerify( const SESSION_INFO *sessionInfoPtr,
1345 					  INOUT SSL_HANDSHAKE_INFO *handshakeInfo,
1346 					  INOUT STREAM *stream )
1347 	{
1348 	void *dataPtr;
1349 	int dataLength, length DUMMY_INIT, status;
1350 
1351 	assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
1352 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1353 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1354 
1355 	/* Get a pointer to the signature data block */
1356 	status = sMemGetDataBlockRemaining( stream, &dataPtr, &dataLength );
1357 	if( cryptStatusError( status ) )
1358 		return( status );
1359 
1360 	/* Create the signature.  The reason for the min() part of the
1361 	   expression is that iCryptCreateSignature() gets suspicious of very
1362 	   large buffer sizes, for example when the user has specified the use
1363 	   of a huge send buffer */
1364 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1365 		{
1366 		CRYPT_CONTEXT iHashContext;
1367 
1368 		/* Create the hash of the data to sign if necessary */
1369 		status = createCertVerifyAltHash( handshakeInfo, &iHashContext );
1370 		if( cryptStatusError( status ) )
1371 			return( status );
1372 
1373 		/* See the note above about the complexities of handling the ever-
1374 		   changing pre-TLS 1.2 signature format */
1375 		status = iCryptCreateSignature( dataPtr,
1376 						min( dataLength, MAX_INTLENGTH_SHORT - 1 ), &length,
1377 						CRYPT_FORMAT_CRYPTLIB, sessionInfoPtr->privateKey,
1378 						iHashContext, NULL );
1379 		krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1380 		}
1381 	else
1382 		{
1383 		status = iCryptCreateSignature( dataPtr,
1384 						min( dataLength, MAX_INTLENGTH_SHORT - 1 ), &length,
1385 						CRYPT_IFORMAT_TLS12, sessionInfoPtr->privateKey,
1386 						handshakeInfo->sessionHashContext, NULL );
1387 		krnlSendNotifier( handshakeInfo->sessionHashContext,
1388 						  IMESSAGE_DECREFCOUNT );
1389 		handshakeInfo->sessionHashContext = CRYPT_ERROR;
1390 		}
1391 	if( cryptStatusOK( status ) )
1392 		status = sSkip( stream, length, MAX_INTLENGTH_SHORT );
1393 	return( status );
1394 	}
1395 
1396 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
checkCertVerify(INOUT SESSION_INFO * sessionInfoPtr,INOUT SSL_HANDSHAKE_INFO * handshakeInfo,INOUT STREAM * stream,IN_LENGTH_SHORT_MIN (MIN_CRYPT_OBJECTSIZE)const int sigLength)1397 int checkCertVerify( INOUT SESSION_INFO *sessionInfoPtr,
1398 					 INOUT SSL_HANDSHAKE_INFO *handshakeInfo,
1399 					 INOUT STREAM *stream,
1400 					 IN_LENGTH_SHORT_MIN( MIN_CRYPT_OBJECTSIZE ) \
1401 						const int sigLength )
1402 	{
1403 	void *dataPtr;
1404 	int status;
1405 
1406 	assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
1407 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1408 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1409 
1410 	REQUIRES( sigLength >= MIN_CRYPT_OBJECTSIZE && \
1411 			  sigLength < MAX_INTLENGTH_SHORT );
1412 
1413 	/* Get a pointer to the signature data block */
1414 	status = sMemGetDataBlock( stream, &dataPtr, sigLength );
1415 	if( cryptStatusError( status ) )
1416 		return( status );
1417 	ANALYSER_HINT( dataPtr != NULL );
1418 
1419 	/* Verify the signature.  The reason for the min() part of the
1420 	   expression is that iCryptCheckSignature() gets suspicious of very
1421 	   large buffer sizes, for example when the user has specified the use
1422 	   of a huge send buffer */
1423 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1424 		{
1425 		CRYPT_CONTEXT iHashContext;
1426 
1427 		/* See the note above about the complexities of handling the ever-
1428 		   changing pre-TLS 1.2 signature format.  To catch any use of one
1429 		   of these formats, we check for a non-cryptlib signature being
1430 		   passed to us by checking for the absence of an ASN.1 SEQUENCE
1431 		   tag and report it as a signature-verification failures.
1432 
1433 		   In theory if there's ever any demand for support for this, we
1434 		   could take advantage of the fact that the signature can really
1435 		   only be RSA (DSA is gone and ECC is TLS 1.2-only) and perform a
1436 		   raw RSA public-key operation on the signature data, extract the
1437 		   lowest 20 bytes (the SHA-1 portion), and compare it with the hash
1438 		   data */
1439 		if( *( ( BYTE * ) dataPtr ) != 0x30 )
1440 			{
1441 			assert( DEBUG_WARN );
1442 			retExt( CRYPT_ERROR_SIGNATURE,
1443 					( CRYPT_ERROR_SIGNATURE, SESSION_ERRINFO,
1444 					  "Couldn't verify old-style (pre-TLS 1.2) client "
1445 					  "certificate-verify message" ) );
1446 			}
1447 
1448 		/* Create the hash of the data to verify if necessary */
1449 		status = createCertVerifyAltHash( handshakeInfo, &iHashContext );
1450 		if( cryptStatusError( status ) )
1451 			return( status );
1452 
1453 		status = iCryptCheckSignature( dataPtr,
1454 						min( sigLength, MAX_INTLENGTH_SHORT - 1 ),
1455 						CRYPT_FORMAT_CRYPTLIB, sessionInfoPtr->iKeyexAuthContext,
1456 						iHashContext, CRYPT_UNUSED, NULL );
1457 		krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1458 		}
1459 	else
1460 		{
1461 		status = iCryptCheckSignature( dataPtr,
1462 						min( sigLength, MAX_INTLENGTH_SHORT - 1 ),
1463 						CRYPT_IFORMAT_TLS12, sessionInfoPtr->iKeyexAuthContext,
1464 						handshakeInfo->sessionHashContext, CRYPT_UNUSED, NULL );
1465 		krnlSendNotifier( handshakeInfo->sessionHashContext,
1466 						  IMESSAGE_DECREFCOUNT );
1467 		handshakeInfo->sessionHashContext = CRYPT_ERROR;
1468 #ifdef CONFIG_SUITEB_TESTS
1469 		if( cryptStatusOK( status ) )
1470 			{
1471 			int sigKeySize;
1472 
1473 			status = krnlSendMessage( sessionInfoPtr->iKeyexAuthContext,
1474 									  IMESSAGE_GETATTRIBUTE, &sigKeySize,
1475 									  CRYPT_CTXINFO_KEYSIZE );
1476 			if( cryptStatusOK( status ) )
1477 				{
1478 				DEBUG_PRINT(( "Verified client's P%d authentication.\n",
1479 							  bytesToBits( sigKeySize ) ));
1480 				}
1481 			}
1482 #endif /* CONFIG_SUITEB_TESTS */
1483 		}
1484 	if( cryptStatusError( status ) )
1485 		{
1486 		retExt( status,
1487 				( status, SESSION_ERRINFO,
1488 				  "Verification of client's certificate-verify message "
1489 				  "failed" ) );
1490 		}
1491 	return( CRYPT_OK );
1492 	}
1493 
1494 /****************************************************************************
1495 *																			*
1496 *						Keyex Signature Functions							*
1497 *																			*
1498 ****************************************************************************/
1499 
1500 /* Create/check the signature on the server key data */
1501 
1502 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
createKeyexHash(const SSL_HANDSHAKE_INFO * handshakeInfo,OUT_HANDLE_OPT CRYPT_CONTEXT * hashContext,IN_ALGO const CRYPT_ALGO_TYPE hashAlgo,IN_INT_SHORT_Z const int hashParam,IN_BUFFER (keyDataLength)const void * keyData,IN_LENGTH_SHORT const int keyDataLength)1503 static int createKeyexHash( const SSL_HANDSHAKE_INFO *handshakeInfo,
1504 							OUT_HANDLE_OPT CRYPT_CONTEXT *hashContext,
1505 							IN_ALGO const CRYPT_ALGO_TYPE hashAlgo,
1506 							IN_INT_SHORT_Z const int hashParam,
1507 							IN_BUFFER( keyDataLength ) const void *keyData,
1508 							IN_LENGTH_SHORT const int keyDataLength )
1509 	{
1510 	CRYPT_CONTEXT iHashContext;
1511 	MESSAGE_CREATEOBJECT_INFO createInfo;
1512 	BYTE nonceBuffer[ SSL_NONCE_SIZE + SSL_NONCE_SIZE + 8 ];
1513 	int status;
1514 
1515 	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1516 	assert( isWritePtr( hashContext, sizeof( CRYPT_CONTEXT ) ) );
1517 	assert( isReadPtr( keyData, keyDataLength ) );
1518 
1519 	REQUIRES( hashAlgo >= CRYPT_ALGO_FIRST_HASH && \
1520 			  hashAlgo <= CRYPT_ALGO_LAST_HASH );
1521 	REQUIRES( hashParam >= 0 && hashParam < MAX_INTLENGTH_SHORT );
1522 	REQUIRES( keyDataLength > 0 && keyDataLength < MAX_INTLENGTH_SHORT );
1523 
1524 	/* Clear return value */
1525 	*hashContext = CRYPT_ERROR;
1526 
1527 	/* Create the hash context */
1528 	setMessageCreateObjectInfo( &createInfo, hashAlgo );
1529 	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1530 							  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1531 							  OBJECT_TYPE_CONTEXT );
1532 	if( cryptStatusError( status ) )
1533 		return( status );
1534 	iHashContext = createInfo.cryptHandle;
1535 	if( hashParam != 0 )
1536 		{
1537 		status = krnlSendMessage( createInfo.cryptHandle,
1538 								  IMESSAGE_SETATTRIBUTE,
1539 								  ( MESSAGE_CAST ) &hashParam,
1540 								  CRYPT_CTXINFO_BLOCKSIZE );
1541 		if( cryptStatusError( status ) )
1542 			{
1543 			krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1544 			return( status );
1545 			}
1546 		}
1547 
1548 	/* Hash the client and server nonces and key data */
1549 	memcpy( nonceBuffer, handshakeInfo->clientNonce, SSL_NONCE_SIZE );
1550 	memcpy( nonceBuffer + SSL_NONCE_SIZE, handshakeInfo->serverNonce,
1551 			SSL_NONCE_SIZE );
1552 	status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
1553 							  nonceBuffer, SSL_NONCE_SIZE + SSL_NONCE_SIZE );
1554 	if( cryptStatusOK( status ) )
1555 		status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
1556 								  ( MESSAGE_CAST ) keyData, keyDataLength );
1557 	if( cryptStatusOK( status ) )
1558 		status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
1559 								  nonceBuffer, 0 );
1560 	if( cryptStatusError( status ) )
1561 		{
1562 		krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
1563 		return( status );
1564 		}
1565 
1566 	*hashContext = iHashContext;
1567 	return( CRYPT_OK );
1568 	}
1569 
1570 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4 ) ) \
createKeyexSignature(INOUT SESSION_INFO * sessionInfoPtr,INOUT SSL_HANDSHAKE_INFO * handshakeInfo,INOUT STREAM * stream,IN_BUFFER (keyDataLength)const void * keyData,IN_LENGTH_SHORT const int keyDataLength)1571 int createKeyexSignature( INOUT SESSION_INFO *sessionInfoPtr,
1572 						  INOUT SSL_HANDSHAKE_INFO *handshakeInfo,
1573 						  INOUT STREAM *stream,
1574 						  IN_BUFFER( keyDataLength ) const void *keyData,
1575 						  IN_LENGTH_SHORT const int keyDataLength )
1576 	{
1577 	CRYPT_CONTEXT md5Context DUMMY_INIT, shaContext;
1578 	void *dataPtr;
1579 	int dataLength, sigLength DUMMY_INIT, status;
1580 
1581 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
1582 	assert( isWritePtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1583 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1584 	assert( isReadPtr( keyData, keyDataLength ) );
1585 
1586 	REQUIRES( keyDataLength > 0 && keyDataLength < MAX_INTLENGTH_SHORT );
1587 
1588 	/* Hash the data to be signed */
1589 	status = createKeyexHash( handshakeInfo, &shaContext,
1590 				( handshakeInfo->keyexSigHashAlgo != CRYPT_ALGO_NONE ) ? \
1591 					handshakeInfo->keyexSigHashAlgo : CRYPT_ALGO_SHA1,
1592 				handshakeInfo->keyexSigHashAlgoParam, keyData, keyDataLength );
1593 	if( cryptStatusError( status ) )
1594 		return( status );
1595 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1596 		{
1597 		status = createKeyexHash( handshakeInfo, &md5Context,
1598 								  CRYPT_ALGO_MD5, 0, keyData, keyDataLength );
1599 		if( cryptStatusError( status ) )
1600 			{
1601 			krnlSendNotifier( shaContext, IMESSAGE_DECREFCOUNT );
1602 			return( status );
1603 			}
1604 		}
1605 	INJECT_FAULT( SESSION_BADSIG_HASH, SESSION_BADSIG_HASH_SSL_1 );
1606 
1607 	/* Sign the hashes.  The reason for the min() part of the expression is
1608 	   that iCryptCreateSignature() gets suspicious of very large buffer
1609 	   sizes, for example when the user has specified the use of a huge send
1610 	   buffer */
1611 	status = sMemGetDataBlockRemaining( stream, &dataPtr, &dataLength );
1612 	if( cryptStatusOK( status ) )
1613 		{
1614 		if( sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS12 )
1615 			{
1616 			status = iCryptCreateSignature( dataPtr,
1617 											min( dataLength, \
1618 												 MAX_INTLENGTH_SHORT - 1 ),
1619 											&sigLength, CRYPT_IFORMAT_TLS12,
1620 											sessionInfoPtr->privateKey,
1621 											shaContext, NULL );
1622 			}
1623 		else
1624 			{
1625 			SIGPARAMS sigParams;
1626 
1627 			initSigParams( &sigParams );
1628 			sigParams.iSecondHash = shaContext;
1629 			status = iCryptCreateSignature( dataPtr,
1630 											min( dataLength, \
1631 												 MAX_INTLENGTH_SHORT - 1 ),
1632 											&sigLength, CRYPT_IFORMAT_SSL,
1633 											sessionInfoPtr->privateKey,
1634 											md5Context, &sigParams );
1635 			}
1636 		}
1637 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1638 		krnlSendNotifier( md5Context, IMESSAGE_DECREFCOUNT );
1639 	krnlSendNotifier( shaContext, IMESSAGE_DECREFCOUNT );
1640 	if( cryptStatusError( status ) )
1641 		return( status );
1642 
1643 	return( sSkip( stream, sigLength, MAX_INTLENGTH_SHORT ) );
1644 	}
1645 
1646 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4 ) ) \
checkKeyexSignature(INOUT SESSION_INFO * sessionInfoPtr,INOUT SSL_HANDSHAKE_INFO * handshakeInfo,INOUT STREAM * stream,IN_BUFFER (keyDataLength)const void * keyData,IN_LENGTH_SHORT const int keyDataLength,const BOOLEAN isECC)1647 int checkKeyexSignature( INOUT SESSION_INFO *sessionInfoPtr,
1648 						 INOUT SSL_HANDSHAKE_INFO *handshakeInfo,
1649 						 INOUT STREAM *stream,
1650 						 IN_BUFFER( keyDataLength ) const void *keyData,
1651 						 IN_LENGTH_SHORT const int keyDataLength,
1652 						 const BOOLEAN isECC )
1653 	{
1654 	CRYPT_CONTEXT md5Context DUMMY_INIT, shaContext;
1655 	CRYPT_ALGO_TYPE hashAlgo = CRYPT_ALGO_SHA1;
1656 	void *dataPtr;
1657 	int dataLength, keyexKeySize, sigKeySize DUMMY_INIT, hashParam = 0;
1658 	int status;
1659 
1660 	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
1661 	assert( isWritePtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1662 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1663 	assert( isReadPtr( keyData, keyDataLength ) );
1664 
1665 	REQUIRES( keyDataLength > 0 && keyDataLength < MAX_INTLENGTH_SHORT );
1666 
1667 	/* Make sure that there's enough data present for at least a minimal-
1668 	   length signature and get a pointer to the signature data */
1669 	if( sMemDataLeft( stream ) < ( isECC ? \
1670 								   MIN_PKCSIZE_ECCPOINT : MIN_PKCSIZE ) )
1671 		return( CRYPT_ERROR_BADDATA );
1672 	status = sMemGetDataBlockRemaining( stream, &dataPtr, &dataLength );
1673 	if( cryptStatusError( status ) )
1674 		return( status );
1675 	ANALYSER_HINT( dataPtr != NULL );
1676 
1677 	/* TLS 1.2+ precedes the signature itself with an indication of the hash
1678 	   and signature algorithm that's required to verify it, so if we're
1679 	   using this format then we have to process the identifiers before we
1680 	   can create the signature-verification hashes.
1681 
1682 	   We disallow SHA1 since the whole point of TLS 1.2 was to move away
1683 	   from it, and a poll on the ietf-tls list indicated that all known
1684 	   implementations (both of them) work fine with this configuration */
1685 	if( sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS12 )
1686 		{
1687 		static const MAP_TABLE hashAlgoIDTbl[] = {
1688 			{ 1000, CRYPT_ALGO_SHAng },
1689 #ifdef CONFIG_SUITEB
1690 			{ TLS_HASHALGO_SHA384, CRYPT_ALGO_SHA2 },
1691 #endif /* CONFIG_SUITEB */
1692 			{ TLS_HASHALGO_SHA2, CRYPT_ALGO_SHA2 },
1693 #if 0	/* 2/11/11 Disabled option for SHA1 after poll on ietf-tls list */
1694 			{ TLS_HASHALGO_SHA1, CRYPT_ALGO_SHA1 },
1695 #endif /* 0 */
1696 			{ CRYPT_ERROR, 0 }, { CRYPT_ERROR, 0 }
1697 			};
1698 		int cryptHashAlgo, tlsHashAlgo;
1699 
1700 		/* Get the hash algorithm that we need to use.  We don't care about
1701 		   the signature algorithm since we've already been given the public
1702 		   key for it */
1703 		status = tlsHashAlgo = sgetc( stream );
1704 		if( cryptStatusError( status ) )
1705 			return( status );
1706 		( void ) sgetc( stream );
1707 		if( tlsHashAlgo <= TLS_HASHALGO_NONE || \
1708 			tlsHashAlgo >= TLS_HASHALGO_LAST )
1709 			return( CRYPT_ERROR_NOTAVAIL );
1710 		status = mapValue( tlsHashAlgo, &cryptHashAlgo, hashAlgoIDTbl,
1711 						   FAILSAFE_ARRAYSIZE( hashAlgoIDTbl, MAP_TABLE ) );
1712 		if( cryptStatusError( status ) )
1713 			return( CRYPT_ERROR_NOTAVAIL );
1714 		hashAlgo = cryptHashAlgo;	/* int vs.enum */
1715 		if( tlsHashAlgo == TLS_HASHALGO_SHA384 )
1716 			hashParam = bitsToBytes( 384 );
1717 		}
1718 
1719 	/* Hash the data to be signed */
1720 	status = createKeyexHash( handshakeInfo, &shaContext, hashAlgo,
1721 							  hashParam, keyData, keyDataLength );
1722 	if( cryptStatusError( status ) )
1723 		return( status );
1724 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1725 		{
1726 		status = createKeyexHash( handshakeInfo, &md5Context,
1727 								  CRYPT_ALGO_MD5, 0, keyData, keyDataLength );
1728 		if( cryptStatusError( status ) )
1729 			{
1730 			krnlSendNotifier( shaContext, IMESSAGE_DECREFCOUNT );
1731 			return( status );
1732 			}
1733 		}
1734 
1735 	/* Check the signature on the hashes.  The reason for the min() part of
1736 	   the expression is that iCryptCheckSignature() gets suspicious of
1737 	   very large buffer sizes, for example when the user has specified the
1738 	   use of a huge send buffer */
1739 	if( sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS12 )
1740 		{
1741 		status = iCryptCheckSignature( dataPtr,
1742 								min( dataLength, MAX_INTLENGTH_SHORT - 1 ),
1743 								CRYPT_IFORMAT_TLS12,
1744 								sessionInfoPtr->iKeyexCryptContext,
1745 								shaContext, CRYPT_UNUSED, NULL );
1746 		}
1747 	else
1748 		{
1749 		status = iCryptCheckSignature( dataPtr,
1750 								min( dataLength, MAX_INTLENGTH_SHORT - 1 ),
1751 								CRYPT_IFORMAT_SSL,
1752 								sessionInfoPtr->iKeyexCryptContext,
1753 								md5Context, shaContext, NULL );
1754 		}
1755 	if( sessionInfoPtr->version < SSL_MINOR_VERSION_TLS12 )
1756 		krnlSendNotifier( md5Context, IMESSAGE_DECREFCOUNT );
1757 	krnlSendNotifier( shaContext, IMESSAGE_DECREFCOUNT );
1758 	if( cryptStatusError( status ) )
1759 		return( status );
1760 
1761 	/* Make sure that the relative strengths of the keyex and signature keys
1762 	   match.  This is just a general precaution for RSA/DSA, but is
1763 	   mandated for ECC with Suite B in order to make the appropriate
1764 	   fashion statement (see the comment below).  When performing the check
1765 	   we allow a small amount of wiggle room to deal with keygen
1766 	   differences */
1767 	status = krnlSendMessage( handshakeInfo->dhContext,
1768 							  IMESSAGE_GETATTRIBUTE, &keyexKeySize,
1769 							  CRYPT_CTXINFO_KEYSIZE );
1770 	if( cryptStatusOK( status ) )
1771 		status = krnlSendMessage( sessionInfoPtr->iKeyexCryptContext,
1772 								  IMESSAGE_GETATTRIBUTE, &sigKeySize,
1773 								  CRYPT_CTXINFO_KEYSIZE );
1774 	if( cryptStatusError( status ) )
1775 		return( status );
1776 	if( isECC )
1777 		{
1778 		/* For ECC with Suite B the signature key size has to match the
1779 		   keyex key size otherwise fashion dictums are violated (if you
1780 		   could just sign size n with size n+1 then you wouldn't need
1781 		   hashsize n/n+1 and keysize n/n+1 and whatnot) */
1782 		if( sigKeySize < keyexKeySize - bitsToBytes( 8 ) )
1783 			{
1784 			DEBUG_PRINT(( "Server used P%d keyex but only P%d signature.\n",
1785 						  bytesToBits( keyexKeySize ),
1786 						  bytesToBits( sigKeySize ) ));
1787 			return( CRYPT_ERROR_NOSECURE );
1788 			}
1789 #ifdef CONFIG_SUITEB
1790 		if( ( sessionInfoPtr->protocolFlags & SSL_PFLAG_SUITEB ) && \
1791 			sigKeySize > keyexKeySize + bitsToBytes( 8 ) )
1792 			return( CRYPT_ERROR_NOSECURE );
1793   #ifdef CONFIG_SUITEB_TESTS
1794 		DEBUG_PRINT(( "Verified server's P%d keyex with P%d signature.\n",
1795 					  bytesToBits( keyexKeySize ),
1796 					  bytesToBits( sigKeySize ) ));
1797   #endif /* CONFIG_SUITEB_TESTS */
1798 #endif /* CONFIG_SUITEB */
1799 		}
1800 	else
1801 		{
1802 #if 1
1803 		/* For conventional keyex/signatures things get a bit complicated,
1804 		   using (say) a 1024-bit key to sign a 1536-bit keyex seems like a
1805 		   mismatch, but then the 1024-bit key may be regenerated relatively
1806 		   frequently while the 1536-bit DH parameters may be static and
1807 		   shared with everyone else on earth, making the high-value 1536-
1808 		   bit key a more viable target for attack than the singleton 1024-
1809 		   bit one.  Because of this we allow a difference of up to 512 bits
1810 		   between the signing key and the keyex key */
1811 		if( sigKeySize < keyexKeySize - bitsToBytes( 512 + 32 ) )
1812 			return( CRYPT_ERROR_NOSECURE );
1813 #else
1814 		/* For conventional keyex/signatures the bounds are a bit looser
1815 		   because non-ECC keygen mechanisms can result in a wider variation
1816 		   of actual vs. nominal key size */
1817 		if( sigKeySize < keyexKeySize - bitsToBytes( 32 ) )
1818 			return( CRYPT_ERROR_NOSECURE );
1819 #endif /* 0 */
1820 		}
1821 
1822 	/* Skip the signature data */
1823 	return( readUniversal16( stream ) );
1824 	}
1825 #endif /* USE_SSL */
1826