/*
 * DTLS implementation written by Nagendra Modadugu
 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 
 */
/* ====================================================================
 * Copyright (c) 1998-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).
 *
 */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * 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 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 acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS 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 AUTHOR OR 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.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509.h>

#include "ssl_locl.h"

#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)

#define RSMBLY_BITMASK_MARK(bitmask, start, end)                     \
  {                                                                  \
    if ((end) - (start) <= 8) {                                      \
      long ii;                                                       \
      for (ii = (start); ii < (end); ii++)                           \
        bitmask[((ii) >> 3)] |= (1 << ((ii)&7));                     \
    } else {                                                         \
      long ii;                                                       \
      bitmask[((start) >> 3)] |= bitmask_start_values[((start)&7)];  \
      for (ii = (((start) >> 3) + 1); ii < ((((end)-1)) >> 3); ii++) \
        bitmask[ii] = 0xff;                                          \
      bitmask[(((end)-1) >> 3)] |= bitmask_end_values[((end)&7)];    \
    }                                                                \
  }

#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete)           \
  {                                                                         \
    long ii;                                                                \
    assert((msg_len) > 0);                                                  \
    is_complete = 1;                                                        \
    if (bitmask[(((msg_len)-1) >> 3)] != bitmask_end_values[((msg_len)&7)]) \
      is_complete = 0;                                                      \
    if (is_complete)                                                        \
      for (ii = (((msg_len)-1) >> 3) - 1; ii >= 0; ii--)                    \
        if (bitmask[ii] != 0xff) {                                          \
          is_complete = 0;                                                  \
          break;                                                            \
        }                                                                   \
  }

static const uint8_t bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8,
                                               0xf0, 0xe0, 0xc0, 0x80};
static const uint8_t bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07,
                                             0x0f, 0x1f, 0x3f, 0x7f};

/* TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable
 * for these values? Notably, why is kMinMTU a function of the transport
 * protocol's overhead rather than, say, what's needed to hold a minimally-sized
 * handshake fragment plus protocol overhead. */

/* kMinMTU is the minimum acceptable MTU value. */
static const unsigned int kMinMTU = 256 - 28;

/* kDefaultMTU is the default MTU value to use if neither the user nor
 * the underlying BIO supplies one. */
static const unsigned int kDefaultMTU = 1500 - 28;

static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                                     unsigned long frag_len);
static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
static long dtls1_get_message_fragment(SSL *s, int stn, long max, int *ok);

static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
                                          int reassembly) {
  hm_fragment *frag = NULL;
  unsigned char *buf = NULL;
  unsigned char *bitmask = NULL;

  frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
  if (frag == NULL) {
    return NULL;
  }

  if (frag_len) {
    buf = (unsigned char *)OPENSSL_malloc(frag_len);
    if (buf == NULL) {
      OPENSSL_free(frag);
      return NULL;
    }
  }

  /* zero length fragment gets zero frag->fragment */
  frag->fragment = buf;

  /* Initialize reassembly bitmask if necessary */
  if (reassembly) {
    bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
    if (bitmask == NULL) {
      if (buf != NULL) {
        OPENSSL_free(buf);
      }
      OPENSSL_free(frag);
      return NULL;
    }
    memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len));
  }

  frag->reassembly = bitmask;

  return frag;
}

void dtls1_hm_fragment_free(hm_fragment *frag) {
  if (frag->fragment) {
    OPENSSL_free(frag->fragment);
  }
  if (frag->reassembly) {
    OPENSSL_free(frag->reassembly);
  }
  OPENSSL_free(frag);
}

/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
 * SSL3_RT_CHANGE_CIPHER_SPEC) */
int dtls1_do_write(SSL *s, int type) {
  int ret;
  int curr_mtu;
  unsigned int len, frag_off;
  size_t max_overhead = 0;

  /* AHA!  Figure out the MTU, and stick to the right size */
  if (s->d1->mtu < dtls1_min_mtu() &&
      !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
    long mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
    if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
      s->d1->mtu = (unsigned)mtu;
    } else {
      s->d1->mtu = kDefaultMTU;
      BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, s->d1->mtu, NULL);
    }
  }

  /* should have something reasonable now */
  assert(s->d1->mtu >= dtls1_min_mtu());

  if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) {
    assert(s->init_num ==
           (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
  }

  /* Determine the maximum overhead of the current cipher. */
  if (s->aead_write_ctx != NULL) {
    max_overhead = EVP_AEAD_max_overhead(s->aead_write_ctx->ctx.aead);
    if (s->aead_write_ctx->variable_nonce_included_in_record) {
      max_overhead += s->aead_write_ctx->variable_nonce_len;
    }
  }

  frag_off = 0;
  while (s->init_num) {
    /* Account for data in the buffering BIO; multiple records may be packed
     * into a single packet during the handshake.
     *
     * TODO(davidben): This is buggy; if the MTU is larger than the buffer size,
     * the large record will be split across two packets. Moreover, in that
     * case, the |dtls1_write_bytes| call may not return synchronously. This
     * will break on retry as the |s->init_off| and |s->init_num| adjustment
     * will run a second time. */
    curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
        DTLS1_RT_HEADER_LENGTH - max_overhead;

    if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
      /* Flush the buffer and continue with a fresh packet.
       *
       * TODO(davidben): If |BIO_flush| is not synchronous and requires multiple
       * calls to |dtls1_do_write|, |frag_off| will be wrong. */
      ret = BIO_flush(SSL_get_wbio(s));
      if (ret <= 0) {
        return ret;
      }
      assert(BIO_wpending(SSL_get_wbio(s)) == 0);
      curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - max_overhead;
    }

    /* XDTLS: this function is too long.  split out the CCS part */
    if (type == SSL3_RT_HANDSHAKE) {
      /* If this isn't the first fragment, reserve space to prepend a new
       * fragment header. This will override the body of a previous fragment. */
      if (s->init_off != 0) {
        assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
        s->init_off -= DTLS1_HM_HEADER_LENGTH;
        s->init_num += DTLS1_HM_HEADER_LENGTH;
      }

      if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
        /* To make forward progress, the MTU must, at minimum, fit the handshake
         * header and one byte of handshake body. */
        OPENSSL_PUT_ERROR(SSL, dtls1_do_write, SSL_R_MTU_TOO_SMALL);
        return -1;
      }

      if (s->init_num > curr_mtu) {
        len = curr_mtu;
      } else {
        len = s->init_num;
      }
      assert(len >= DTLS1_HM_HEADER_LENGTH);

      dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);
      dtls1_write_message_header(
          s, (uint8_t *)&s->init_buf->data[s->init_off]);
    } else {
      assert(type == SSL3_RT_CHANGE_CIPHER_SPEC);
      /* ChangeCipherSpec cannot be fragmented. */
      if (s->init_num > curr_mtu) {
        OPENSSL_PUT_ERROR(SSL, dtls1_do_write, SSL_R_MTU_TOO_SMALL);
        return -1;
      }
      len = s->init_num;
    }

    ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len);
    if (ret < 0) {
      return -1;
    }

    /* bad if this assert fails, only part of the handshake message got sent.
     * But why would this happen? */
    assert(len == (unsigned int)ret);

    if (ret == s->init_num) {
      if (s->msg_callback) {
        s->msg_callback(1, s->version, type, s->init_buf->data,
                        (size_t)(s->init_off + s->init_num), s,
                        s->msg_callback_arg);
      }

      s->init_off = 0; /* done writing this message */
      s->init_num = 0;

      return 1;
    }
    s->init_off += ret;
    s->init_num -= ret;
    frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
  }

  return 0;
}


/* dtls1_get_message reads a handshake message of message type |msg_type| (any
 * if |msg_type| == -1), maximum acceptable body length |max|. Read an entire
 * handshake message. Handshake messages arrive in fragments. */
long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
                       enum ssl_hash_message_t hash_message, int *ok) {
  int i, al;
  struct hm_header_st *msg_hdr;
  uint8_t *p;
  unsigned long msg_len;

  /* s3->tmp is used to store messages that are unexpected, caused
   * by the absence of an optional handshake message */
  if (s->s3->tmp.reuse_message) {
    /* A ssl_dont_hash_message call cannot be combined with reuse_message; the
     * ssl_dont_hash_message would have to have been applied to the previous
     * call. */
    assert(hash_message == ssl_hash_message);
    s->s3->tmp.reuse_message = 0;
    if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
      goto f_err;
    }
    *ok = 1;
    s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
    s->init_num = (int)s->s3->tmp.message_size;
    return s->init_num;
  }

  msg_hdr = &s->d1->r_msg_hdr;
  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));

again:
  i = dtls1_get_message_fragment(s, stn, max, ok);
  if (i == DTLS1_HM_BAD_FRAGMENT ||
      i == DTLS1_HM_FRAGMENT_RETRY) {
    /* bad fragment received */
    goto again;
  } else if (i <= 0 && !*ok) {
    return i;
  }

  if (msg_type >= 0 && msg_hdr->type != msg_type) {
    al = SSL_AD_UNEXPECTED_MESSAGE;
    OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
    goto f_err;
  }

  p = (uint8_t *)s->init_buf->data;
  msg_len = msg_hdr->msg_len;

  /* reconstruct message header */
  *(p++) = msg_hdr->type;
  l2n3(msg_len, p);
  s2n(msg_hdr->seq, p);
  l2n3(0, p);
  l2n3(msg_len, p);
  p -= DTLS1_HM_HEADER_LENGTH;
  msg_len += DTLS1_HM_HEADER_LENGTH;

  s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;

  if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) {
    goto err;
  }
  if (s->msg_callback) {
    s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, msg_len, s,
                    s->msg_callback_arg);
  }

  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));

  s->d1->handshake_read_seq++;

  return s->init_num;

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
  *ok = 0;
  return -1;
}

static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr,
                                     int max) {
  size_t frag_off, frag_len, msg_len;

  msg_len = msg_hdr->msg_len;
  frag_off = msg_hdr->frag_off;
  frag_len = msg_hdr->frag_len;

  /* sanity checking */
  if ((frag_off + frag_len) > msg_len) {
    OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment,
                      SSL_R_EXCESSIVE_MESSAGE_SIZE);
    return SSL_AD_ILLEGAL_PARAMETER;
  }

  if ((frag_off + frag_len) > (unsigned long)max) {
    OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment,
                      SSL_R_EXCESSIVE_MESSAGE_SIZE);
    return SSL_AD_ILLEGAL_PARAMETER;
  }

  if (s->d1->r_msg_hdr.frag_off == 0) {
    /* first fragment */
    /* msg_len is limited to 2^24, but is effectively checked
     * against max above */
    if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
      OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment, ERR_R_BUF_LIB);
      return SSL_AD_INTERNAL_ERROR;
    }

    s->s3->tmp.message_size = msg_len;
    s->d1->r_msg_hdr.msg_len = msg_len;
    s->s3->tmp.message_type = msg_hdr->type;
    s->d1->r_msg_hdr.type = msg_hdr->type;
    s->d1->r_msg_hdr.seq = msg_hdr->seq;
  } else if (msg_len != s->d1->r_msg_hdr.msg_len) {
    /* They must be playing with us! BTW, failure to enforce
     * upper limit would open possibility for buffer overrun. */
    OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment,
                      SSL_R_EXCESSIVE_MESSAGE_SIZE);
    return SSL_AD_ILLEGAL_PARAMETER;
  }

  return 0; /* no error */
}


static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) {
  /* (0) check whether the desired fragment is available
   * if so:
   * (1) copy over the fragment to s->init_buf->data[]
   * (2) update s->init_num */
  pitem *item;
  hm_fragment *frag;
  int al;
  unsigned long frag_len;

  *ok = 0;
  item = pqueue_peek(s->d1->buffered_messages);
  if (item == NULL) {
    return 0;
  }

  frag = (hm_fragment *)item->data;

  /* Don't return if reassembly still in progress */
  if (frag->reassembly != NULL) {
    return 0;
  }

  if (s->d1->handshake_read_seq != frag->msg_header.seq) {
    return 0;
  }

  frag_len = frag->msg_header.frag_len;
  pqueue_pop(s->d1->buffered_messages);

  al = dtls1_preprocess_fragment(s, &frag->msg_header, max);

  if (al == 0) {
    /* no alert */
    uint8_t *p = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
    memcpy(&p[frag->msg_header.frag_off], frag->fragment,
           frag->msg_header.frag_len);
  }

  dtls1_hm_fragment_free(frag);
  pitem_free(item);

  if (al == 0) {
    *ok = 1;
    return frag_len;
  }

  ssl3_send_alert(s, SSL3_AL_FATAL, al);
  s->init_num = 0;
  *ok = 0;
  return -1;
}

/* dtls1_max_handshake_message_len returns the maximum number of bytes
 * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may
 * be greater if the maximum certificate list size requires it. */
static unsigned long dtls1_max_handshake_message_len(const SSL *s) {
  unsigned long max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
  if (max_len < (unsigned long)s->max_cert_list) {
    return s->max_cert_list;
  }
  return max_len;
}

static int dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr,
                                     int *ok) {
  hm_fragment *frag = NULL;
  pitem *item = NULL;
  int i = -1, is_complete;
  uint8_t seq64be[8];
  unsigned long frag_len = msg_hdr->frag_len;

  if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
      msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) {
    goto err;
  }

  if (frag_len == 0) {
    return DTLS1_HM_FRAGMENT_RETRY;
  }

  /* Try to find item in queue */
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(msg_hdr->seq >> 8);
  seq64be[7] = (uint8_t)msg_hdr->seq;
  item = pqueue_find(s->d1->buffered_messages, seq64be);

  if (item == NULL) {
    frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
    if (frag == NULL) {
      goto err;
    }
    memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
    frag->msg_header.frag_len = frag->msg_header.msg_len;
    frag->msg_header.frag_off = 0;
  } else {
    frag = (hm_fragment *)item->data;
    if (frag->msg_header.msg_len != msg_hdr->msg_len) {
      item = NULL;
      frag = NULL;
      goto err;
    }
  }

  /* If message is already reassembled, this must be a
   * retransmit and can be dropped. In this case item != NULL and so frag
   * does not need to be freed. */
  if (frag->reassembly == NULL) {
    uint8_t devnull[256];

    assert(item != NULL);
    while (frag_len) {
      i = s->method->ssl_read_bytes(
          s, SSL3_RT_HANDSHAKE, devnull,
          frag_len > sizeof(devnull) ? sizeof(devnull) : frag_len, 0);
      if (i <= 0) {
        goto err;
      }
      frag_len -= i;
    }
    return DTLS1_HM_FRAGMENT_RETRY;
  }

  /* read the body of the fragment (header has already been read */
  i = s->method->ssl_read_bytes(
      s, SSL3_RT_HANDSHAKE, frag->fragment + msg_hdr->frag_off, frag_len, 0);
  if ((unsigned long)i != frag_len) {
    i = -1;
  }
  if (i <= 0) {
    goto err;
  }

  RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
                      (long)(msg_hdr->frag_off + frag_len));

  RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
                             is_complete);

  if (is_complete) {
    OPENSSL_free(frag->reassembly);
    frag->reassembly = NULL;
  }

  if (item == NULL) {
    item = pitem_new(seq64be, frag);
    if (item == NULL) {
      i = -1;
      goto err;
    }

    item = pqueue_insert(s->d1->buffered_messages, item);
    /* pqueue_insert fails iff a duplicate item is inserted.
     * However, |item| cannot be a duplicate. If it were,
     * |pqueue_find|, above, would have returned it and control
     * would never have reached this branch. */
    assert(item != NULL);
  }

  return DTLS1_HM_FRAGMENT_RETRY;

err:
  if (frag != NULL && item == NULL) {
    dtls1_hm_fragment_free(frag);
  }
  *ok = 0;
  return i;
}

static int dtls1_process_out_of_seq_message(SSL *s,
                                            const struct hm_header_st *msg_hdr,
                                            int *ok) {
  int i = -1;
  hm_fragment *frag = NULL;
  pitem *item = NULL;
  uint8_t seq64be[8];
  unsigned long frag_len = msg_hdr->frag_len;

  if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) {
    goto err;
  }

  /* Try to find item in queue, to prevent duplicate entries */
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(msg_hdr->seq >> 8);
  seq64be[7] = (uint8_t)msg_hdr->seq;
  item = pqueue_find(s->d1->buffered_messages, seq64be);

  /* If we already have an entry and this one is a fragment,
   * don't discard it and rather try to reassemble it. */
  if (item != NULL && frag_len != msg_hdr->msg_len) {
    item = NULL;
  }

  /* Discard the message if sequence number was already there, is
   * too far in the future, or already in the queue. */
  if (msg_hdr->seq <= s->d1->handshake_read_seq ||
      msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL) {
    uint8_t devnull[256];

    while (frag_len) {
      i = s->method->ssl_read_bytes(
          s, SSL3_RT_HANDSHAKE, devnull,
          frag_len > sizeof(devnull) ? sizeof(devnull) : frag_len, 0);
      if (i <= 0) {
        goto err;
      }
      frag_len -= i;
    }
  } else {
    if (frag_len != msg_hdr->msg_len) {
      return dtls1_reassemble_fragment(s, msg_hdr, ok);
    }

    if (frag_len > dtls1_max_handshake_message_len(s)) {
      goto err;
    }

    frag = dtls1_hm_fragment_new(frag_len, 0);
    if (frag == NULL) {
      goto err;
    }

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

    if (frag_len) {
      /* read the body of the fragment (header has already been read */
      i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment,
                                    frag_len, 0);
      if ((unsigned long)i != frag_len) {
        i = -1;
      }
      if (i <= 0) {
        goto err;
      }
    }

    item = pitem_new(seq64be, frag);
    if (item == NULL) {
      goto err;
    }

    item = pqueue_insert(s->d1->buffered_messages, item);
    /* pqueue_insert fails iff a duplicate item is inserted.
     * However, |item| cannot be a duplicate. If it were,
     * |pqueue_find|, above, would have returned it. Then, either
     * |frag_len| != |msg_hdr->msg_len| in which case |item| is set
     * to NULL and it will have been processed with
     * |dtls1_reassemble_fragment|, above, or the record will have
     * been discarded. */
    assert(item != NULL);
  }

  return DTLS1_HM_FRAGMENT_RETRY;

err:
  if (frag != NULL && item == NULL) {
    dtls1_hm_fragment_free(frag);
  }
  *ok = 0;
  return i;
}


static long dtls1_get_message_fragment(SSL *s, int stn, long max, int *ok) {
  uint8_t wire[DTLS1_HM_HEADER_LENGTH];
  unsigned long len, frag_off, frag_len;
  int i, al;
  struct hm_header_st msg_hdr;

redo:
  /* see if we have the required fragment already */
  if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) {
    if (*ok) {
      s->init_num = frag_len;
    }
    return frag_len;
  }

  /* read handshake message header */
  i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire,
                                DTLS1_HM_HEADER_LENGTH, 0);
  if (i <= 0) {
    /* nbio, or an error */
    s->rwstate = SSL_READING;
    *ok = 0;
    return i;
  }

  /* Handshake fails if message header is incomplete */
  if (i != DTLS1_HM_HEADER_LENGTH) {
    al = SSL_AD_UNEXPECTED_MESSAGE;
    OPENSSL_PUT_ERROR(SSL, dtls1_get_message_fragment,
                      SSL_R_UNEXPECTED_MESSAGE);
    goto f_err;
  }

  /* parse the message fragment header */
  dtls1_get_message_header(wire, &msg_hdr);

  /* if this is a future (or stale) message it gets buffered
   * (or dropped)--no further processing at this time. */
  if (msg_hdr.seq != s->d1->handshake_read_seq) {
    return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
  }

  len = msg_hdr.msg_len;
  frag_off = msg_hdr.frag_off;
  frag_len = msg_hdr.frag_len;

  if (frag_len && frag_len < len) {
    return dtls1_reassemble_fragment(s, &msg_hdr, ok);
  }

  if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
      wire[0] == SSL3_MT_HELLO_REQUEST) {
    /* The server may always send 'Hello Request' messages --
     * we are doing a handshake anyway now, so ignore them
     * if their format is correct. Does not count for
     * 'Finished' MAC. */
    if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) {
      if (s->msg_callback) {
        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, wire,
                        DTLS1_HM_HEADER_LENGTH, s, s->msg_callback_arg);
      }

      s->init_num = 0;
      goto redo;
    } else {
      /* Incorrectly formated Hello request */
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_get_message_fragment,
                        SSL_R_UNEXPECTED_MESSAGE);
      goto f_err;
    }
  }

  if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) {
    goto f_err;
  }

  /* XDTLS:  ressurect this when restart is in place */
  s->state = stn;

  if (frag_len > 0) {
    uint8_t *p = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;

    i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[frag_off], frag_len,
                                  0);
    /* XDTLS:  fix this--message fragments cannot span multiple packets */
    if (i <= 0) {
      s->rwstate = SSL_READING;
      *ok = 0;
      return i;
    }
  } else {
    i = 0;
  }

  /* XDTLS:  an incorrectly formatted fragment should cause the
   * handshake to fail */
  if (i != (int)frag_len) {
    al = SSL3_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, dtls1_get_message_fragment,
                      SSL3_AD_ILLEGAL_PARAMETER);
    goto f_err;
  }

  *ok = 1;

  /* Note that s->init_num is *not* used as current offset in
   * s->init_buf->data, but as a counter summing up fragments'
   * lengths: as soon as they sum up to handshake packet
   * length, we assume we have got all the fragments. */
  s->init_num = frag_len;
  return frag_len;

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
  s->init_num = 0;

  *ok = 0;
  return -1;
}

/* for these 2 messages, we need to
 * ssl->enc_read_ctx			re-init
 * ssl->s3->read_sequence		zero
 * ssl->s3->read_mac_secret		re-init
 * ssl->session->read_sym_enc		assign
 * ssl->session->read_compression	assign
 * ssl->session->read_hash		assign */
int dtls1_send_change_cipher_spec(SSL *s, int a, int b) {
  uint8_t *p;

  if (s->state == a) {
    p = (uint8_t *)s->init_buf->data;
    *p++ = SSL3_MT_CCS;
    s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
    s->init_num = DTLS1_CCS_HEADER_LENGTH;

    s->init_off = 0;

    dtls1_set_message_header(s, SSL3_MT_CCS, 0, s->d1->handshake_write_seq, 0,
                             0);

    /* buffer the message to handle re-xmits */
    dtls1_buffer_message(s, 1);

    s->state = b;
  }

  /* SSL3_ST_CW_CHANGE_B */
  return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
}

int dtls1_read_failed(SSL *s, int code) {
  if (code > 0) {
    assert(0);
    return 1;
  }

  if (!dtls1_is_timer_expired(s)) {
    /* not a timeout, none of our business, let higher layers handle this. In
     * fact, it's probably an error */
    return code;
  }

  if (!SSL_in_init(s)) {
    /* done, no need to send a retransmit */
    BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
    return code;
  }

  return dtls1_handle_timeout(s);
}

int dtls1_get_queue_priority(unsigned short seq, int is_ccs) {
  /* The index of the retransmission queue actually is the message sequence
   * number, since the queue only contains messages of a single handshake.
   * However, the ChangeCipherSpec has no message sequence number and so using
   * only the sequence will result in the CCS and Finished having the same
   * index. To prevent this, the sequence number is multiplied by 2. In case of
   * a CCS 1 is subtracted. This does not only differ CSS and Finished, it also
   * maintains the order of the index (important for priority queues) and fits
   * in the unsigned short variable. */
  return seq * 2 - is_ccs;
}

static int dtls1_retransmit_message(SSL *s, hm_fragment *frag) {
  int ret;
  /* XDTLS: for now assuming that read/writes are blocking */
  unsigned long header_length;
  uint8_t save_write_sequence[8];

  /* assert(s->init_num == 0);
     assert(s->init_off == 0); */

  if (frag->msg_header.is_ccs) {
    header_length = DTLS1_CCS_HEADER_LENGTH;
  } else {
    header_length = DTLS1_HM_HEADER_LENGTH;
  }

  memcpy(s->init_buf->data, frag->fragment,
         frag->msg_header.msg_len + header_length);
  s->init_num = frag->msg_header.msg_len + header_length;

  dtls1_set_message_header(s, frag->msg_header.type,
                           frag->msg_header.msg_len, frag->msg_header.seq,
                           0, frag->msg_header.frag_len);

  /* Save current state. */
  SSL_AEAD_CTX *aead_write_ctx = s->aead_write_ctx;
  uint16_t epoch = s->d1->w_epoch;

  /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
   * (negotiated cipher) exist. */
  assert(epoch == 0 || epoch == 1);
  assert(frag->msg_header.epoch <= epoch);
  const int fragment_from_previous_epoch = (epoch == 1 &&
                                            frag->msg_header.epoch == 0);
  if (fragment_from_previous_epoch) {
    /* Rewind to the previous epoch.
     *
     * TODO(davidben): Instead of swapping out connection-global state, this
     * logic should pass a "use previous epoch" parameter down to lower-level
     * functions. */
    s->d1->w_epoch = frag->msg_header.epoch;
    s->aead_write_ctx = NULL;
    memcpy(save_write_sequence, s->s3->write_sequence,
           sizeof(s->s3->write_sequence));
    memcpy(s->s3->write_sequence, s->d1->last_write_sequence,
           sizeof(s->s3->write_sequence));
  } else {
    /* Otherwise the messages must be from the same epoch. */
    assert(frag->msg_header.epoch == epoch);
  }

  ret = dtls1_do_write(s, frag->msg_header.is_ccs ? SSL3_RT_CHANGE_CIPHER_SPEC
                                                  : SSL3_RT_HANDSHAKE);

  if (fragment_from_previous_epoch) {
    /* Restore the current epoch. */
    s->aead_write_ctx = aead_write_ctx;
    s->d1->w_epoch = epoch;
    memcpy(s->d1->last_write_sequence, s->s3->write_sequence,
           sizeof(s->s3->write_sequence));
    memcpy(s->s3->write_sequence, save_write_sequence,
           sizeof(s->s3->write_sequence));
  }

  (void)BIO_flush(SSL_get_wbio(s));
  return ret;
}


int dtls1_retransmit_buffered_messages(SSL *s) {
  pqueue sent = s->d1->sent_messages;
  piterator iter = pqueue_iterator(sent);
  pitem *item;

  for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
    hm_fragment *frag = (hm_fragment *)item->data;
    if (dtls1_retransmit_message(s, frag) <= 0) {
      return -1;
    }
  }

  return 1;
}

int dtls1_buffer_message(SSL *s, int is_ccs) {
  pitem *item;
  hm_fragment *frag;
  uint8_t seq64be[8];

  /* this function is called immediately after a message has
   * been serialized */
  assert(s->init_off == 0);

  frag = dtls1_hm_fragment_new(s->init_num, 0);
  if (!frag) {
    return 0;
  }

  memcpy(frag->fragment, s->init_buf->data, s->init_num);

  if (is_ccs) {
    assert(s->d1->w_msg_hdr.msg_len + DTLS1_CCS_HEADER_LENGTH ==
           (unsigned int)s->init_num);
  } else {
    assert(s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH ==
           (unsigned int)s->init_num);
  }

  frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
  frag->msg_header.seq = s->d1->w_msg_hdr.seq;
  frag->msg_header.type = s->d1->w_msg_hdr.type;
  frag->msg_header.frag_off = 0;
  frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
  frag->msg_header.is_ccs = is_ccs;
  frag->msg_header.epoch = s->d1->w_epoch;

  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(
      dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs) >>
      8);
  seq64be[7] = (uint8_t)(
      dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs));

  item = pitem_new(seq64be, frag);
  if (item == NULL) {
    dtls1_hm_fragment_free(frag);
    return 0;
  }

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

/* call this function when the buffered messages are no longer needed */
void dtls1_clear_record_buffer(SSL *s) {
  pitem *item;

  for (item = pqueue_pop(s->d1->sent_messages); item != NULL;
       item = pqueue_pop(s->d1->sent_messages)) {
    dtls1_hm_fragment_free((hm_fragment *)item->data);
    pitem_free(item);
  }
}

/* don't actually do the writing, wait till the MTU has been retrieved */
void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len,
                              unsigned short seq_num, unsigned long frag_off,
                              unsigned long frag_len) {
  struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

  msg_hdr->type = mt;
  msg_hdr->msg_len = len;
  msg_hdr->seq = seq_num;
  msg_hdr->frag_off = frag_off;
  msg_hdr->frag_len = frag_len;
}

static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                                     unsigned long frag_len) {
  struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

  msg_hdr->frag_off = frag_off;
  msg_hdr->frag_len = frag_len;
}

static uint8_t *dtls1_write_message_header(SSL *s, uint8_t *p) {
  struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

  *p++ = msg_hdr->type;
  l2n3(msg_hdr->msg_len, p);

  s2n(msg_hdr->seq, p);
  l2n3(msg_hdr->frag_off, p);
  l2n3(msg_hdr->frag_len, p);

  return p;
}

unsigned int dtls1_min_mtu(void) {
  return kMinMTU;
}

void dtls1_get_message_header(uint8_t *data,
                              struct hm_header_st *msg_hdr) {
  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
  msg_hdr->type = *(data++);
  n2l3(data, msg_hdr->msg_len);

  n2s(data, msg_hdr->seq);
  n2l3(data, msg_hdr->frag_off);
  n2l3(data, msg_hdr->frag_len);
}

void dtls1_get_ccs_header(uint8_t *data, struct ccs_header_st *ccs_hdr) {
  memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));

  ccs_hdr->type = *(data++);
}

int dtls1_shutdown(SSL *s) {
  int ret;
  ret = ssl3_shutdown(s);
  return ret;
}
