Commit 50ec3951 authored by Andy Polyakov's avatar Andy Polyakov
Browse files

Handle wrap-arounds and revive missing assignment.

parent 11cd2397
Loading
Loading
Loading
Loading
+56 −30
Original line number Diff line number Diff line
@@ -121,27 +121,53 @@
#include <openssl/buffer.h>
#include <openssl/pqueue.h>

/* mod 256 saturating subtract of two 64-bit values in big-endian order */
/* mod 128 saturating subtract of two 64-bit values in big-endian order */
static int satsub64be(const unsigned char *v1,const unsigned char *v2)
	{
	int i;
	unsigned char c1,c2;

	for (i=0;i<8;i++,v1++,v2++)
		{
		c1=*v1; c2=*v2;
		if (c1!=c2) break;
{	int ret,sat,brw,i;

	if (sizeof(long) == 8) do
	{	const union { long one; char little; } is_endian = {1};
		long l;

		if (is_endian.little)			break;
		/* not reached on little-endians */
		/* following test is redundant, because input is
		 * always aligned, but I take no chances... */
		if (((size_t)v1|(size_t)v2)&0x7)	break;

		l =  *((long *)v1);
		l =- *((long *)v2);
		if (l>128)		return 128;
		else if (l<-128)	return -128;
		else			return (int)l;
	} while (0);

	ret = (int)v1[7]-(int)v2[7];
	sat = 0;
	brw = ret>>8;	/* brw is either 0 or -1 */
	if (ret & 0x80)
	{	for (i=6;i>=0;i--)
		{	brw += (int)v1[i]-(int)v2[i];
			sat |= ~brw;
			brw >>= 8;
		}
	}
	if (i==8)	return 0;
	else if (i==7)	return (int)c1-(int)c2;
	else if (c1>c2)	return 256;
	else		return -256;
	else
	{	for (i=6;i>=0;i--)
		{	brw += (int)v1[i]-(int)v2[i];
			sat |= brw;
			brw >>= 8;
		}
	}
	brw <<= 8;	/* brw is either 0 or -256 */

	if (sat&0xff)	return brw | 0x80;
	else		return brw + (ret&0xFF);
}

static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
	int len, int peek);
static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
	unsigned char *seq_num);
static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 
    unsigned int *is_next_epoch);
@@ -607,7 +633,7 @@ again:
		}

	/* check whether this is a repeat, or aged record */
	if ( ! dtls1_record_replay_check(s, bitmap, rr->seq_num))
	if ( ! dtls1_record_replay_check(s, bitmap))
		{
		s->packet_length=0; /* dump this record */
		goto again;     /* get another record */
@@ -1468,8 +1494,7 @@ err:



static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
	unsigned char *seq_num)
static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
	{
	int cmp;
	unsigned int shift;
@@ -1478,7 +1503,7 @@ static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
	cmp = satsub64be(seq,bitmap->max_seq_num);
	if (cmp > 0)
		{
		memcpy (seq_num,seq,8);
		memcpy (s->s3->rrec.seq_num,seq,8);
		return 1; /* this record in new */
		}
	shift = -cmp;
@@ -1487,6 +1512,7 @@ static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
	else if (bitmap->map & (1UL<<shift))
		return 0; /* record previously received */

	memcpy (s->s3->rrec.seq_num,seq,8);
	return 1;
	}