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

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