Blame SOURCES/openssl-fips-0.9.8e-dtls-fixes2.patch

c4366c
diff -up openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-fixes2 openssl-fips-0.9.8e/ssl/d1_pkt.c
c4366c
--- openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-fixes2	2012-01-16 11:00:34.242797904 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/d1_pkt.c	2012-01-18 15:45:25.144865068 +0100
c4366c
@@ -134,7 +134,7 @@ static int dtls1_record_needs_buffering(
c4366c
 	unsigned short *priority, unsigned long *offset);
c4366c
 #endif
c4366c
 static int dtls1_buffer_record(SSL *s, record_pqueue *q,
c4366c
-	PQ_64BIT priority);
c4366c
+	PQ_64BIT *priority);
c4366c
 static int dtls1_process_record(SSL *s);
c4366c
 #if PQ_64BIT_IS_INTEGER
c4366c
 static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
c4366c
@@ -156,13 +156,16 @@ dtls1_copy_record(SSL *s, pitem *item)
c4366c
     s->packet_length = rdata->packet_length;
c4366c
     memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
c4366c
     memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
c4366c
+	
c4366c
+	/* Set proper sequence number for mac calculation */
c4366c
+	memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
c4366c
     
c4366c
     return(1);
c4366c
     }
c4366c
 
c4366c
 
c4366c
 static int
c4366c
-dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority)
c4366c
+dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority)
c4366c
 {
c4366c
     DTLS1_RECORD_DATA *rdata;
c4366c
 	pitem *item;
c4366c
@@ -172,7 +175,7 @@ dtls1_buffer_record(SSL *s, record_pqueu
c4366c
 		return 0;
c4366c
 		
c4366c
 	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
c4366c
-	item = pitem_new(priority, rdata);
c4366c
+	item = pitem_new(*priority, rdata);
c4366c
 	if (rdata == NULL || item == NULL)
c4366c
 		{
c4366c
 		if (rdata != NULL) OPENSSL_free(rdata);
c4366c
@@ -253,9 +256,6 @@ dtls1_process_buffered_records(SSL *s)
c4366c
     item = pqueue_peek(s->d1->unprocessed_rcds.q);
c4366c
     if (item)
c4366c
         {
c4366c
-        DTLS1_RECORD_DATA *rdata;
c4366c
-        rdata = (DTLS1_RECORD_DATA *)item->data;
c4366c
-        
c4366c
         /* Check if epoch is current. */
c4366c
         if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
c4366c
             return(1);  /* Nothing to do. */
c4366c
@@ -267,7 +267,7 @@ dtls1_process_buffered_records(SSL *s)
c4366c
             if ( ! dtls1_process_record(s))
c4366c
                 return(0);
c4366c
             dtls1_buffer_record(s, &(s->d1->processed_rcds), 
c4366c
-                s->s3->rrec.seq_num);
c4366c
+                &s->s3->rrec.seq_num);
c4366c
             }
c4366c
         }
c4366c
 
c4366c
@@ -328,13 +328,15 @@ dtls1_get_buffered_record(SSL *s)
c4366c
 static int
c4366c
 dtls1_process_record(SSL *s)
c4366c
 {
c4366c
-    int i,al;
c4366c
+    int al;
c4366c
 	int clear=0;
c4366c
     int enc_err;
c4366c
 	SSL_SESSION *sess;
c4366c
     SSL3_RECORD *rr;
c4366c
 	unsigned int mac_size;
c4366c
 	unsigned char md[EVP_MAX_MD_SIZE];
c4366c
+	int decryption_failed_or_bad_record_mac = 0;
c4366c
+	unsigned char *mac = NULL;
c4366c
 
c4366c
 
c4366c
 	rr= &(s->s3->rrec);
c4366c
@@ -369,12 +371,10 @@ dtls1_process_record(SSL *s)
c4366c
 	enc_err = s->method->ssl3_enc->enc(s,0);
c4366c
 	if (enc_err <= 0)
c4366c
 		{
c4366c
-		if (enc_err == 0)
c4366c
-			/* SSLerr() and ssl3_send_alert() have been called */
c4366c
-			goto err;
c4366c
-
c4366c
-		/* otherwise enc_err == -1 */
c4366c
-		goto decryption_failed_or_bad_record_mac;
c4366c
+		/* To minimize information leaked via timing, we will always
c4366c
+		 * perform all computations before discarding the message.
c4366c
+		 */
c4366c
+		decryption_failed_or_bad_record_mac = 1;
c4366c
 		}
c4366c
 
c4366c
 #ifdef TLS_DEBUG
c4366c
@@ -400,28 +400,32 @@ if (	(sess == NULL) ||
c4366c
 			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
c4366c
 			goto f_err;
c4366c
 #else
c4366c
-			goto decryption_failed_or_bad_record_mac;
c4366c
+			decryption_failed_or_bad_record_mac = 1;
c4366c
 #endif			
c4366c
 			}
c4366c
 		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
c4366c
-		if (rr->length < mac_size)
c4366c
+		if (rr->length >= mac_size)
c4366c
 			{
c4366c
-#if 0 /* OK only for stream ciphers */
c4366c
-			al=SSL_AD_DECODE_ERROR;
c4366c
-			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
c4366c
-			goto f_err;
c4366c
-#else
c4366c
-			goto decryption_failed_or_bad_record_mac;
c4366c
-#endif
c4366c
+			rr->length -= mac_size;
c4366c
+			mac = &rr->data[rr->length];
c4366c
 			}
c4366c
-		rr->length-=mac_size;
c4366c
-		i=s->method->ssl3_enc->mac(s,md,0);
c4366c
-		if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
c4366c
+		else
c4366c
+			rr->length = 0;
c4366c
+		s->method->ssl3_enc->mac(s,md,0);
c4366c
+		if (mac == NULL || memcmp(md, mac, mac_size) != 0)
c4366c
 			{
c4366c
-			goto decryption_failed_or_bad_record_mac;
c4366c
+			decryption_failed_or_bad_record_mac = 1;
c4366c
 			}
c4366c
 		}
c4366c
 
c4366c
+	if (decryption_failed_or_bad_record_mac)
c4366c
+		{
c4366c
+		/* decryption failed, silently discard message */
c4366c
+		rr->length = 0;
c4366c
+		s->packet_length = 0;
c4366c
+		goto err;
c4366c
+		}
c4366c
+
c4366c
 	/* r->length is now just compressed */
c4366c
 	if (s->expand != NULL)
c4366c
 		{
c4366c
@@ -460,14 +464,6 @@ if (	(sess == NULL) ||
c4366c
     dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
c4366c
     return(1);
c4366c
 
c4366c
-decryption_failed_or_bad_record_mac:
c4366c
-	/* Separate 'decryption_failed' alert was introduced with TLS 1.0,
c4366c
-	 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
c4366c
-	 * failure is directly visible from the ciphertext anyway,
c4366c
-	 * we should not reveal which kind of error occured -- this
c4366c
-	 * might become visible to an attacker (e.g. via logfile) */
c4366c
-	al=SSL_AD_BAD_RECORD_MAC;
c4366c
-	SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
c4366c
 f_err:
c4366c
 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
c4366c
 err:
c4366c
@@ -486,22 +482,19 @@ err:
c4366c
 /* used only by dtls1_read_bytes */
c4366c
 int dtls1_get_record(SSL *s)
c4366c
 	{
c4366c
-	int ssl_major,ssl_minor,al;
c4366c
+	int ssl_major,ssl_minor;
c4366c
 	int i,n;
c4366c
 	SSL3_RECORD *rr;
c4366c
-	SSL_SESSION *sess;
c4366c
-	unsigned char *p;
c4366c
+	unsigned char *p = NULL;
c4366c
 	unsigned short version;
c4366c
 	DTLS1_BITMAP *bitmap;
c4366c
 	unsigned int is_next_epoch;
c4366c
 
c4366c
 	rr= &(s->s3->rrec);
c4366c
-	sess=s->session;
c4366c
 
c4366c
     /* The epoch may have changed.  If so, process all the
c4366c
      * pending records.  This is a non-blocking operation. */
c4366c
-    if ( ! dtls1_process_buffered_records(s))
c4366c
-        return 0;
c4366c
+    dtls1_process_buffered_records(s);
c4366c
 
c4366c
 	/* if we're renegotiating, then there may be buffered records */
c4366c
 	if (dtls1_get_processed_record(s))
c4366c
@@ -517,7 +510,12 @@ again:
c4366c
 		/* read timeout is handled by dtls1_read_bytes */
c4366c
 		if (n <= 0) return(n); /* error or non-blocking */
c4366c
 
c4366c
-		OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH);
c4366c
+		/* this packet contained a partial record, dump it */
c4366c
+		if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
c4366c
+			{
c4366c
+			s->packet_length = 0;
c4366c
+			goto again;
c4366c
+			}
c4366c
 
c4366c
 		s->rstate=SSL_ST_READ_BODY;
c4366c
 
c4366c
@@ -542,27 +540,28 @@ again:
c4366c
 			{
c4366c
 			if (version != s->version && version != DTLS1_BAD_VER)
c4366c
 				{
c4366c
-				SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
c4366c
-				/* Send back error using their
c4366c
-				 * version number :-) */
c4366c
-				s->version=version;
c4366c
-				al=SSL_AD_PROTOCOL_VERSION;
c4366c
-				goto f_err;
c4366c
+				/* unexpected version, silently discard */
c4366c
+				rr->length = 0;
c4366c
+				s->packet_length = 0;
c4366c
+				goto again;
c4366c
 				}
c4366c
 			}
c4366c
 
c4366c
 		if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
c4366c
 		    (version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
c4366c
 			{
c4366c
-			SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
c4366c
-			goto err;
c4366c
+			/* wrong version, silently discard record */
c4366c
+			rr->length = 0;
c4366c
+			s->packet_length = 0;
c4366c
+			goto again;
c4366c
 			}
c4366c
 
c4366c
 		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
c4366c
 			{
c4366c
-			al=SSL_AD_RECORD_OVERFLOW;
c4366c
-			SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
c4366c
-			goto f_err;
c4366c
+			/* record too long, silently discard it */
c4366c
+			rr->length = 0;
c4366c
+			s->packet_length = 0;
c4366c
+			goto again;
c4366c
 			}
c4366c
 
c4366c
 		s->client_version = version;
c4366c
@@ -581,6 +580,7 @@ again:
c4366c
 		/* this packet contained a partial record, dump it */
c4366c
 		if ( n != i)
c4366c
 			{
c4366c
+			rr->length = 0;
c4366c
 			s->packet_length = 0;
c4366c
 			goto again;
c4366c
 			}
c4366c
@@ -594,6 +594,7 @@ again:
c4366c
 	bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
c4366c
 	if ( bitmap == NULL)
c4366c
         {
c4366c
+	rr->length = 0;
c4366c
         s->packet_length = 0;  /* dump this record */
c4366c
         goto again;   /* get another record */
c4366c
 		}
c4366c
@@ -601,6 +602,7 @@ again:
c4366c
 	/* check whether this is a repeat, or aged record */
c4366c
 	if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
c4366c
 		{
c4366c
+		rr->length = 0;
c4366c
 		s->packet_length=0; /* dump this record */
c4366c
 		goto again;     /* get another record */
c4366c
 		}
c4366c
@@ -615,21 +617,22 @@ again:
c4366c
     if (is_next_epoch)
c4366c
         {
c4366c
         dtls1_record_bitmap_update(s, bitmap);
c4366c
-        dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
c4366c
+        dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num);
c4366c
+		rr->length = 0;
c4366c
         s->packet_length = 0;
c4366c
         goto again;
c4366c
         }
c4366c
 
c4366c
-    if ( ! dtls1_process_record(s))
c4366c
-        return(0);
c4366c
+    if (!dtls1_process_record(s))
c4366c
+		{
c4366c
+		rr->length = 0;
c4366c
+		s->packet_length=0; /* dump this record */
c4366c
+		goto again;     /* get another record */
c4366c
+		}
c4366c
 
c4366c
 	dtls1_clear_timeouts(s);  /* done waiting */
c4366c
 	return(1);
c4366c
 
c4366c
-f_err:
c4366c
-	ssl3_send_alert(s,SSL3_AL_FATAL,al);
c4366c
-err:
c4366c
-	return(0);
c4366c
 	}
c4366c
 
c4366c
 /* Return up to 'len' payload bytes received in 'type' records.