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