Commit 188b0579 authored by Richard Levitte's avatar Richard Levitte
Browse files

pqueue and dtls uses 64-bit values. Unfortunately, OpenSSL doesn't

have a uniform representation for those over all architectures, so a
little bit of hackery is needed.

Contributed by nagendra modadugu <nagendra@cs.stanford.edu>
parent 575901e5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ LIBOBJ=pqueue.o

SRC= $(LIBSRC)

EXHEADER= pqueue.h
EXHEADER= pqueue.h pq_compat.h
HEADER=	$(EXHEADER)

ALL=    $(GENERAL) $(SRC) $(HEADER)
+134 −0
Original line number Diff line number Diff line
/* crypto/pqueue/pqueue_compat.h */
/* 
 * DTLS implementation written by Nagendra Modadugu
 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
 */
/* ====================================================================
 * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include "opensslconf.h"
#include <openssl/bn.h>

/* 
 * The purpose of this header file is for supporting 64-bit integer
 * manipulation on 32-bit (and lower) machines.  Currently the only
 * such environment is VMS.  Other environments that do not natively
 * support 64-bit integers can safely use the code developed for VMS.
 *
 * The only clients of this code are (1) pqueue for priority, and
 * (2) DTLS, for sequence number manipulation.
 */

#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)

#define PQ_64BIT     BIGNUM
#define PQ_64BIT_CTX BN_CTX

#define pq_64bit_init(x)           BN_init(x)
#define pq_64bit_free(x)           BN_free(x)

#define pq_64bit_ctx_new(ctx)      BN_CTX_new()
#define pq_64bit_ctx_free(x)       BN_CTX_free(x)

#define pq_64bit_assign(x, y)      BN_copy(x, y)
#define pq_64bit_assign_word(x, y) BN_set_word(x, y)
#define pq_64bit_gt(x, y)          BN_ucmp(x, y) >= 1 ? 1 : 0
#define pq_64bit_eq(x, y)          BN_ucmp(x, y) == 0 ? 1 : 0
#define pq_64bit_add_word(x, w)    BN_add_word(x, w)
#define pq_64bit_sub(r, x, y)      BN_sub(r, x, y)
#define pq_64bit_sub_word(x, w)    BN_sub_word(x, w)
#define pq_64bit_mod(r, x, n, ctx) BN_mod(r, x, n, ctx)

#define pq_64bit_bin2num(bn, bytes, len)   BN_bin2bn(bytes, len, bn)
#define pq_64bit_num2bin(bn, bytes)        BN_bn2bin(bn, bytes)
#define pq_64bit_get_word(x)               BN_get_word(x)
#define pq_64bit_is_bit_set(x, offset)     BN_is_bit_set(x, offset)
#define pq_64bit_lshift(r, x, shift)       BN_lshift(r, x, shift)
#define pq_64bit_set_bit(x, num)           BN_set_bit(x, num)
#define pq_64bit_get_length(x)             BN_num_bits((x))

#else

#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
#define PQ_64BIT BN_ULONG
#elif defined(THIRTY_TWO_BIT)
#define PQ_64BIT BN_ULLONG
#endif

#define PQ_64BIT_CTX      void

#define pq_64bit_init(x)
#define pq_64bit_free(x)
#define pq_64bit_ctx_new(ctx)        (ctx)
#define pq_64bit_ctx_free(x)

#define pq_64bit_assign(x, y)        (*(x) = *(y))
#define pq_64bit_assign_word(x, y)   (*(x) = y)
#define pq_64bit_gt(x, y)	         (*(x) > *(y))
#define pq_64bit_eq(x, y)            (*(x) == *(y))
#define pq_64bit_add_word(x, w)      (*(x) = (*(x) + (w)))
#define pq_64bit_sub(r, x, y)        (*(r) = (*(x) - *(y)))
#define pq_64bit_sub_word(x, w)      (*(x) = (*(x) - (w)))
#define pq_64bit_mod(r, x, n, ctx)

#define pq_64bit_bin2num(num, bytes, len) bytes_to_long_long(bytes, num)
#define pq_64bit_num2bin(num, bytes)      long_long_to_bytes(num, bytes)
#define pq_64bit_get_word(x)              *(x)
#define pq_64bit_lshift(r, x, shift)      (*(r) = (*(x) << (shift)))
#define pq_64bit_set_bit(x, num)          do { \
                                              PQ_64BIT mask = 1; \
                                              mask = mask << (num); \
                                              *(x) |= mask; \
                                          } while(0)
#endif /* OPENSSL_SYS_VMS */
+13 −8
Original line number Diff line number Diff line
@@ -68,12 +68,14 @@ typedef struct _pqueue
	} pqueue_s;

pitem *
pitem_new(BN_ULLONG priority, void *data)
pitem_new(PQ_64BIT priority, void *data)
	{
	pitem *item = (pitem *) OPENSSL_malloc(sizeof(pitem));
	if (item == NULL) return NULL;

	item->priority = priority;
	pq_64bit_init(&(item->priority));
	pq_64bit_assign(&item->priority, &priority);

	item->data = data;
	item->next = NULL;

@@ -85,6 +87,7 @@ pitem_free(pitem *item)
	{
	if (item == NULL) return;

	pq_64bit_free(&(item->priority));
	OPENSSL_free(item);
	}

@@ -121,7 +124,7 @@ pqueue_insert(pqueue_s *pq, pitem *item)
		next != NULL;
		curr = next, next = next->next)
		{
		if (item->priority < next->priority)
		if (pq_64bit_gt(&(next->priority), &(item->priority)))
			{
			item->next = next;

@@ -133,7 +136,7 @@ pqueue_insert(pqueue_s *pq, pitem *item)
			return item;
			}
		/* duplicates not allowed */
		if (item->priority == next->priority)
		if (pq_64bit_eq(&(item->priority), &(next->priority)))
			return NULL;
		}

@@ -161,7 +164,7 @@ pqueue_pop(pqueue_s *pq)
	}

pitem *
pqueue_find(pqueue_s *pq, BN_ULLONG priority)
pqueue_find(pqueue_s *pq, PQ_64BIT priority)
	{
	pitem *next, *prev = NULL;
	pitem *found = NULL;
@@ -172,7 +175,7 @@ pqueue_find(pqueue_s *pq, BN_ULLONG priority)
	for ( next = pq->items; next->next != NULL; 
		  prev = next, next = next->next)
		{
		if ( next->priority == priority)
		if ( pq_64bit_eq(&(next->priority), &priority))
			{
			found = next;
			break;
@@ -180,7 +183,7 @@ pqueue_find(pqueue_s *pq, BN_ULLONG priority)
		}
	
	/* check the one last node */
	if ( next->priority == priority)
	if ( pq_64bit_eq(&(next->priority), &priority))
		found = next;

	if ( ! found)
@@ -196,6 +199,7 @@ pqueue_find(pqueue_s *pq, BN_ULLONG priority)
	return found;
	}

#if !(defined(OPENSSL_SYS_VMS) || defined(VMS_TEST))
void
pqueue_print(pqueue_s *pq)
	{
@@ -207,6 +211,7 @@ pqueue_print(pqueue_s *pq)
		item = item->next;
		}
	}
#endif

pitem *
pqueue_iterator(pqueue_s *pq)
+5 −3
Original line number Diff line number Diff line
@@ -64,18 +64,20 @@
#include <stdlib.h>
#include <string.h>

#include <openssl/pq_compat.h>

typedef struct _pqueue *pqueue;

typedef struct _pitem
	{
	BN_ULLONG priority;
	PQ_64BIT priority;
	void *data;
	struct _pitem *next;
	} pitem;

typedef struct _pitem *piterator;

pitem *pitem_new(BN_ULLONG priority, void *data);
pitem *pitem_new(PQ_64BIT priority, void *data);
void   pitem_free(pitem *item);

pqueue pqueue_new(void);
@@ -84,7 +86,7 @@ void pqueue_free(pqueue pq);
pitem *pqueue_insert(pqueue pq, pitem *item);
pitem *pqueue_peek(pqueue pq);
pitem *pqueue_pop(pqueue pq);
pitem *pqueue_find(pqueue pq, BN_ULLONG priority);
pitem *pqueue_find(pqueue pq, PQ_64BIT priority);
pitem *pqueue_iterator(pqueue pq);
pitem *pqueue_next(piterator *iter);

+19 −3
Original line number Diff line number Diff line
@@ -442,6 +442,7 @@ dtls1_buffer_handshake_fragment(SSL *s, struct hm_header_st* msg_hdr)
{
    hm_fragment *frag = NULL;
    pitem *item = NULL;
	PQ_64BIT seq64;

    frag = dtls1_hm_fragment_new(msg_hdr->frag_len);
    if ( frag == NULL)
@@ -452,10 +453,15 @@ dtls1_buffer_handshake_fragment(SSL *s, struct hm_header_st* msg_hdr)

    memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));

    item = pitem_new(msg_hdr->seq, frag);
    pq_64bit_init(&seq64);
    pq_64bit_assign_word(&seq64, msg_hdr->seq);

    item = pitem_new(seq64, frag);
    if ( item == NULL)
        goto err;

    pq_64bit_free(&seq64);

    pqueue_insert(s->d1->buffered_messages, item);
    return 1;

@@ -1037,6 +1043,7 @@ dtls1_buffer_message(SSL *s, int is_ccs)
    {
    pitem *item;
    hm_fragment *frag;
	PQ_64BIT seq64;

    /* this function is called immediately after a message has 
     * been serialized */
@@ -1064,7 +1071,11 @@ dtls1_buffer_message(SSL *s, int is_ccs)
    frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
    frag->msg_header.is_ccs = is_ccs;

    item = pitem_new(frag->msg_header.seq, frag);
    pq_64bit_init(&seq64);
    pq_64bit_assign_word(&seq64, frag->msg_header.seq);

    item = pitem_new(seq64, frag);
    pq_64bit_free(&seq64);
    if ( item == NULL)
        {
        dtls1_hm_fragment_free(frag);
@@ -1090,6 +1101,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
    pitem *item;
    hm_fragment *frag ;
    unsigned long header_length;
	PQ_64BIT seq64;

    /*
      OPENSSL_assert(s->init_num == 0);
@@ -1097,7 +1109,11 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
     */

    /* XDTLS:  the requested message ought to be found, otherwise error */
    item = pqueue_find(s->d1->sent_messages, seq);
    pq_64bit_init(&seq64);
    pq_64bit_assign_word(&seq64, seq);

    item = pqueue_find(s->d1->sent_messages, seq64);
    pq_64bit_free(&seq64);
    if ( item == NULL)
        {
        fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
Loading