#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/pqueue.h>
+#include <openssl/rand.h>
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 long long *seq_num);
+ PQ_64BIT *seq_num);
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);
unsigned short *priority, unsigned long *offset);
#endif
static int dtls1_buffer_record(SSL *s, record_pqueue *q,
- unsigned long long priority);
+ PQ_64BIT priority);
static int dtls1_process_record(SSL *s);
-static unsigned long long bytes_to_long_long(unsigned char *bytes);
-static void long_long_to_bytes(unsigned long long num, unsigned char *bytes);
+#if PQ_64BIT_IS_INTEGER
+static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
+#endif
static void dtls1_clear_timeouts(SSL *s);
-
/* copy buffered record into SSL structure */
static int
dtls1_copy_record(SSL *s, pitem *item)
static int
-dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned long long priority)
+dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority)
{
DTLS1_RECORD_DATA *rdata;
pitem *item;
if (rdata != NULL) OPENSSL_free(rdata);
if (item != NULL) pitem_free(item);
- SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
return(0);
}
memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
- ssl3_setup_buffers(s);
+ if (!ssl3_setup_buffers(s))
+ {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ return(0);
+ }
return(1);
}
dtls1_get_buffered_record(SSL *s)
{
pitem *item;
- unsigned long long priority =
- (((unsigned long long)s->d1->handshake_read_seq) << 32) |
- ((unsigned long long)s->d1->r_msg_hdr.frag_off);
+ PQ_64BIT priority =
+ (((PQ_64BIT)s->d1->handshake_read_seq) << 32) |
+ ((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
if ( ! SSL_in_init(s)) /* if we're not (re)negotiating,
nothing buffered */
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
goto f_err;
}
{
#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
goto f_err;
#else
goto decryption_failed_or_bad_record_mac;
{
#if 0 /* OK only for stream ciphers */
al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
goto f_err;
#else
goto decryption_failed_or_bad_record_mac;
if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
goto f_err;
}
if (!ssl3_do_uncompress(s))
{
al=SSL_AD_DECOMPRESSION_FAILURE;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
goto f_err;
}
}
if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
* we should not reveal which kind of error occured -- this
* might become visible to an attacker (e.g. via logfile) */
al=SSL_AD_BAD_RECORD_MAC;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
SSL3_RECORD *rr;
SSL_SESSION *sess;
unsigned char *p;
- short version;
+ unsigned short version;
DTLS1_BITMAP *bitmap;
- unsigned long long read_sequence;
- unsigned int is_next_epoch;
+ unsigned int is_next_epoch;
rr= &(s->s3->rrec);
sess=s->session;
ssl_minor= *(p++);
version=(ssl_major<<8)|ssl_minor;
- /* sequence number is 64 bits, with top 2 bytes = epoch */
+ /* sequence number is 64 bits, with top 2 bytes = epoch */
n2s(p,rr->epoch);
- read_sequence = 0;
- n2l6(p, read_sequence);
- long_long_to_bytes(read_sequence, s->s3->read_sequence);
+ memcpy(&(s->s3->read_sequence[2]), p, 6);
+ p+=6;
+
n2s(p,rr->length);
/* Lets check version */
- if (s->first_packet)
- {
- s->first_packet=0;
- }
- else
+ if (!s->first_packet)
{
- if (version != s->version)
+ if (version != s->version && version != DTLS1_BAD_VER)
{
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
+ SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
/* Send back error using their
* version number :-) */
s->version=version;
}
}
- if ((version & 0xff00) != (DTLS1_VERSION & 0xff00))
+ if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
+ (version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
{
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
+ SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
goto err;
}
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
+ SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
goto f_err;
}
+ s->client_version = version;
/* now s->rstate == SSL_ST_READ_BODY */
}
(type != SSL3_RT_HANDSHAKE) && type) ||
(peek && (type != SSL3_RT_APPLICATION_DATA)))
{
- SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
return -1;
}
if (i < 0) return(i);
if (i == 0)
{
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
return(-1);
}
}
&& (rr->type != SSL3_RT_HANDSHAKE))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
goto err;
}
(s->enc_read_ctx == NULL))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
goto f_err;
}
* fill that so that we can process the data at a fixed place.
*/
{
- unsigned int i, dest_maxlen = 0;
+ unsigned int k, dest_maxlen = 0;
unsigned char *dest = NULL;
unsigned int *dest_len = NULL;
dest = s->d1->alert_fragment;
dest_len = &s->d1->alert_fragment_len;
}
- else /* else it's a CCS message */
- OPENSSL_assert(rr->type == SSL3_RT_CHANGE_CIPHER_SPEC);
+ /* else it's a CCS message, or it's wrong */
+ else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
+ {
+ /* Not certain if this is the right error handling */
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
if (dest_maxlen > 0)
}
/* now move 'n' bytes: */
- for ( i = 0; i < dest_maxlen; i++)
+ for ( k = 0; k < dest_maxlen; k++)
{
- dest[i] = rr->data[rr->off++];
+ dest[k] = rr->data[rr->off++];
rr->length--;
}
*dest_len = dest_maxlen;
(s->d1->handshake_fragment[3] != 0))
{
al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
goto err;
}
if (i < 0) return(i);
if (i == 0)
{
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
return(-1);
}
s->rwstate=SSL_NOTHING;
s->s3->fatal_alert = alert_descr;
- SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
ERR_add_error_data(2,"SSL alert number ",tmp);
s->shutdown|=SSL_RECEIVED_SHUTDOWN;
else
{
al=SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
goto f_err;
}
}
if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
- {
- struct ccs_header_st ccs_hdr;
+ {
+ struct ccs_header_st ccs_hdr;
dtls1_get_ccs_header(rr->data, &ccs_hdr);
- if ( ccs_hdr.seq == s->d1->handshake_read_seq)
- {
- /* 'Change Cipher Spec' is just a single byte, so we know
- * exactly what the record payload has to look like */
- /* XDTLS: check that epoch is consistent */
- if ( (rr->length != DTLS1_CCS_HEADER_LENGTH) ||
- (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
- {
- i=SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
- goto err;
- }
-
- rr->length=0;
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
- rr->data, 1, s, s->msg_callback_arg);
-
- s->s3->change_cipher_spec=1;
- if (!ssl3_do_change_cipher_spec(s))
- goto err;
-
- /* do this whenever CCS is processed */
- dtls1_reset_seq_numbers(s, SSL3_CC_READ);
-
- /* handshake read seq is reset upon handshake completion */
- s->d1->handshake_read_seq++;
-
- goto start;
- }
- else
+ /* 'Change Cipher Spec' is just a single byte, so we know
+ * exactly what the record payload has to look like */
+ /* XDTLS: check that epoch is consistent */
+ if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) ||
+ (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) ||
+ (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
{
- rr->length = 0;
- goto start;
+ i=SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
+ goto err;
}
+
+ rr->length=0;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
+ rr->data, 1, s, s->msg_callback_arg);
+
+ s->s3->change_cipher_spec=1;
+ if (!ssl3_do_change_cipher_spec(s))
+ goto err;
+
+ /* do this whenever CCS is processed */
+ dtls1_reset_seq_numbers(s, SSL3_CC_READ);
+
+ if (s->client_version == DTLS1_BAD_VER)
+ s->d1->handshake_read_seq++;
+
+ goto start;
}
/* Unexpected handshake message (Client Hello, or protocol violation) */
if (i < 0) return(i);
if (i == 0)
{
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
return(-1);
}
}
#endif
al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
goto f_err;
case SSL3_RT_CHANGE_CIPHER_SPEC:
case SSL3_RT_ALERT:
* of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
* should not happen when type != rr->type */
al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_READ_BYTES,ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
goto f_err;
case SSL3_RT_APPLICATION_DATA:
/* At this point, we were expecting handshake data,
else
{
al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
goto f_err;
}
}
if (i < 0) return(i);
if (i == 0)
{
- SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
return i;
}
- if ( s->s3->wnum + i == len)
+ if ( (int)s->s3->wnum + i == len)
s->s3->wnum = 0;
else
s->s3->wnum += i;
return tot + i;
}
-int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
- unsigned int len, int create_empty_fragment)
+int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
{
unsigned char *p,*pseq;
int i,mac_size,clear=0;
if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
{
/* insufficient space */
- SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
goto err;
}
}
*(p++)=type&0xff;
wr->type=type;
- *(p++)=(s->version>>8);
- *(p++)=s->version&0xff;
+ if (s->client_version == DTLS1_BAD_VER)
+ *(p++) = DTLS1_BAD_VER>>8,
+ *(p++) = DTLS1_BAD_VER&0xff;
+ else
+ *(p++)=(s->version>>8),
+ *(p++)=s->version&0xff;
/* field where we are to write out packet epoch, seq num and len */
pseq=p;
{
if (!ssl3_do_compress(s))
{
- SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE);
+ SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
goto err;
}
}
/* ssl3_enc can only have an error on read */
- wr->length += bs; /* bs != 0 in case of CBC. The enc fn provides
- * the randomness */
+ if (bs) /* bs != 0 in case of CBC */
+ {
+ RAND_pseudo_bytes(p,bs);
+ /* master IV and last CBC residue stand for
+ * the rest of randomness */
+ wr->length += bs;
+ }
+
s->method->ssl3_enc->enc(s,1);
/* record length after mac and block padding */
/* else
s2n(s->d1->handshake_epoch, pseq); */
- l2n6(bytes_to_long_long(s->s3->write_sequence), pseq);
+ memcpy(pseq, &(s->s3->write_sequence[2]), 6);
+ pseq+=6;
s2n(wr->length,pseq);
/* we should now have
/* buffer the record, making it easy to handle retransmits */
if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
dtls1_buffer_record(s, wr->data, wr->length,
- *((unsigned long long *)&(s->s3->write_sequence[0])));
+ *((PQ_64BIT *)&(s->s3->write_sequence[0])));
#endif
ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
- unsigned long long *seq_num)
+ PQ_64BIT *seq_num)
{
- unsigned long long mask = 0x0000000000000001LL;
- unsigned long long rcd_num;
+#if PQ_64BIT_IS_INTEGER
+ PQ_64BIT mask = 0x0000000000000001L;
+#endif
+ PQ_64BIT rcd_num, tmp;
+
+ pq_64bit_init(&rcd_num);
+ pq_64bit_init(&tmp);
+
+ /* this is the sequence number for the record just read */
+ pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
- rcd_num = bytes_to_long_long(s->s3->read_sequence);
- if (rcd_num >= bitmap->max_seq_num)
+ if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
+ pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
{
- *seq_num = rcd_num;
+ pq_64bit_assign(seq_num, &rcd_num);
+ pq_64bit_free(&rcd_num);
+ pq_64bit_free(&tmp);
return 1; /* this record is new */
}
-
- if (bitmap->max_seq_num - rcd_num > bitmap->length)
+
+ pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
+
+ if ( pq_64bit_get_word(&tmp) > bitmap->length)
+ {
+ pq_64bit_free(&rcd_num);
+ pq_64bit_free(&tmp);
return 0; /* stale, outside the window */
+ }
+#if PQ_64BIT_IS_BIGNUM
+ {
+ int offset;
+ pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
+ pq_64bit_sub_word(&tmp, 1);
+ offset = pq_64bit_get_word(&tmp);
+ if ( pq_64bit_is_bit_set(&(bitmap->map), offset))
+ {
+ pq_64bit_free(&rcd_num);
+ pq_64bit_free(&tmp);
+ return 0;
+ }
+ }
+#else
mask <<= (bitmap->max_seq_num - rcd_num - 1);
if (bitmap->map & mask)
return 0; /* record previously received */
+#endif
- *seq_num = rcd_num;
+ pq_64bit_assign(seq_num, &rcd_num);
+ pq_64bit_free(&rcd_num);
+ pq_64bit_free(&tmp);
return 1;
}
static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
{
unsigned int shift;
- unsigned long long mask = 0x0000000000000001L;
- unsigned long long rcd_num;
+ PQ_64BIT rcd_num;
+ PQ_64BIT tmp;
+ PQ_64BIT_CTX *ctx;
+
+ pq_64bit_init(&rcd_num);
+ pq_64bit_init(&tmp);
- rcd_num = bytes_to_long_long(s->s3->read_sequence);
+ pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
- if (rcd_num >= bitmap->max_seq_num)
+ /* unfortunate code complexity due to 64-bit manipulation support
+ * on 32-bit machines */
+ if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
+ pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
{
- shift = rcd_num - bitmap->max_seq_num + 1;
- bitmap->max_seq_num = rcd_num + 1;
- bitmap->map <<= shift;
- bitmap->map |= 0x0000000000000001LL;
+ pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num));
+ pq_64bit_add_word(&tmp, 1);
+
+ shift = (unsigned int)pq_64bit_get_word(&tmp);
+
+ pq_64bit_lshift(&(tmp), &(bitmap->map), shift);
+ pq_64bit_assign(&(bitmap->map), &tmp);
+
+ pq_64bit_set_bit(&(bitmap->map), 0);
+ pq_64bit_add_word(&rcd_num, 1);
+ pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num);
+
+ pq_64bit_assign_word(&tmp, 1);
+ pq_64bit_lshift(&tmp, &tmp, bitmap->length);
+ ctx = pq_64bit_ctx_new(&ctx);
+ pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx);
+ pq_64bit_ctx_free(ctx);
}
else
{
- mask <<= (bitmap->max_seq_num - rcd_num - 1);
- bitmap->map |= mask;
+ pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
+ pq_64bit_sub_word(&tmp, 1);
+ shift = (unsigned int)pq_64bit_get_word(&tmp);
+
+ pq_64bit_set_bit(&(bitmap->map), shift);
}
+
+ pq_64bit_free(&rcd_num);
+ pq_64bit_free(&tmp);
}
{
int i,j;
void (*cb)(const SSL *ssl,int type,int val)=NULL;
- char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */
- char *ptr = &buf[0];
+ unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */
+ unsigned char *ptr = &buf[0];
s->s3->alert_dispatch=0;
return &s->d1->bitmap;
/* Only HM and ALERT messages can be from the next epoch */
- else if (rr->epoch == s->d1->r_epoch + 1 &&
+ else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
(rr->type == SSL3_RT_HANDSHAKE ||
rr->type == SSL3_RT_ALERT))
{
{
seq = s->s3->read_sequence;
s->d1->r_epoch++;
- memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
+
+ pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map));
+ s->d1->bitmap.length = s->d1->next_bitmap.length;
+ pq_64bit_assign(&(s->d1->bitmap.max_seq_num),
+ &(s->d1->next_bitmap.max_seq_num));
+
+ pq_64bit_free(&(s->d1->next_bitmap.map));
+ pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
+ pq_64bit_init(&(s->d1->next_bitmap.map));
+ pq_64bit_init(&(s->d1->next_bitmap.max_seq_num));
}
else
{
memset(seq, 0x00, seq_bytes);
}
+#if PQ_64BIT_IS_INTEGER
+static PQ_64BIT
+bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num)
+ {
+ PQ_64BIT _num;
+
+ _num = (((PQ_64BIT)bytes[0]) << 56) |
+ (((PQ_64BIT)bytes[1]) << 48) |
+ (((PQ_64BIT)bytes[2]) << 40) |
+ (((PQ_64BIT)bytes[3]) << 32) |
+ (((PQ_64BIT)bytes[4]) << 24) |
+ (((PQ_64BIT)bytes[5]) << 16) |
+ (((PQ_64BIT)bytes[6]) << 8) |
+ (((PQ_64BIT)bytes[7]) );
+
+ *num = _num ;
+ return _num;
+ }
+#endif
-static unsigned long long
-bytes_to_long_long(unsigned char *bytes)
- {
- unsigned long long num;
-
- num = (((unsigned long long)bytes[0]) << 56) |
- (((unsigned long long)bytes[1]) << 48) |
- (((unsigned long long)bytes[2]) << 40) |
- (((unsigned long long)bytes[3]) << 32) |
- (((unsigned long long)bytes[4]) << 24) |
- (((unsigned long long)bytes[5]) << 16) |
- (((unsigned long long)bytes[6]) << 8) |
- (((unsigned long long)bytes[7]) );
-
- return num;
- }
-
-static void
-long_long_to_bytes(unsigned long long num, unsigned char *bytes)
- {
- bytes[0] = (unsigned char)((num >> 56)&0xff);
- bytes[1] = (unsigned char)((num >> 48)&0xff);
- bytes[2] = (unsigned char)((num >> 40)&0xff);
- bytes[3] = (unsigned char)((num >> 32)&0xff);
- bytes[4] = (unsigned char)((num >> 24)&0xff);
- bytes[5] = (unsigned char)((num >> 16)&0xff);
- bytes[6] = (unsigned char)((num >> 8)&0xff);
- bytes[7] = (unsigned char)((num )&0xff);
- }
static void
dtls1_clear_timeouts(SSL *s)