/* 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 <stdio.h>
#include <errno.h>
#include <assert.h>

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

#include "ssl_locl.h"


/* mod 128 saturating subtract of two 64-bit values in big-endian order */
static int satsub64be(const uint8_t *v1, const uint8_t *v2) {
  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;
    }
  } 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, uint8_t *buf, int len,
                                   int peek);
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);
static int dtls1_buffer_record(SSL *s, record_pqueue *q,
                               uint8_t *priority);
static int dtls1_process_record(SSL *s);
static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
                          unsigned int len);

/* copy buffered record into SSL structure */
static int dtls1_copy_record(SSL *s, pitem *item) {
  DTLS1_RECORD_DATA *rdata;

  rdata = (DTLS1_RECORD_DATA *)item->data;

  if (s->s3->rbuf.buf != NULL) {
    OPENSSL_free(s->s3->rbuf.buf);
  }

  s->packet = rdata->packet;
  s->packet_length = rdata->packet_length;
  memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
  memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));

  /* Set proper sequence number for mac calculation */
  memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);

  return 1;
}

static int dtls1_buffer_record(SSL *s, record_pqueue *queue,
                               uint8_t *priority) {
  DTLS1_RECORD_DATA *rdata;
  pitem *item;

  /* Limit the size of the queue to prevent DOS attacks */
  if (pqueue_size(queue->q) >= 100) {
    return 0;
  }

  rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
  item = pitem_new(priority, rdata);
  if (rdata == NULL || item == NULL) {
    if (rdata != NULL) {
      OPENSSL_free(rdata);
    }
    if (item != NULL) {
      pitem_free(item);
    }

    OPENSSL_PUT_ERROR(SSL, dtls1_buffer_record, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  rdata->packet = s->packet;
  rdata->packet_length = s->packet_length;
  memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
  memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));

  item->data = rdata;

  s->packet = NULL;
  s->packet_length = 0;
  memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
  memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));

  if (!ssl3_setup_buffers(s)) {
    OPENSSL_PUT_ERROR(SSL, dtls1_buffer_record, ERR_R_INTERNAL_ERROR);
    OPENSSL_free(rdata);
    pitem_free(item);
    return 0;
  }

  /* insert should not fail, since duplicates are dropped */
  if (pqueue_insert(queue->q, item) == NULL) {
    OPENSSL_PUT_ERROR(SSL, dtls1_buffer_record, ERR_R_INTERNAL_ERROR);
    OPENSSL_free(rdata);
    pitem_free(item);
    return 0;
  }

  return 1;
}

static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) {
  pitem *item;

  item = pqueue_pop(queue->q);
  if (item) {
    dtls1_copy_record(s, item);

    OPENSSL_free(item->data);
    pitem_free(item);

    return 1;
  }

  return 0;
}

/* retrieve a buffered record that belongs to the new epoch, i.e., not
 * processed yet */
#define dtls1_get_unprocessed_record(s) \
  dtls1_retrieve_buffered_record((s), &((s)->d1->unprocessed_rcds))

/* retrieve a buffered record that belongs to the current epoch, i.e.,
 * processed */
#define dtls1_get_processed_record(s) \
  dtls1_retrieve_buffered_record((s), &((s)->d1->processed_rcds))

static int dtls1_process_buffered_records(SSL *s) {
  pitem *item;

  item = pqueue_peek(s->d1->unprocessed_rcds.q);
  if (item) {
    /* Check if epoch is current. */
    if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) {
      return 1; /* Nothing to do. */
    }

    /* Process all the records. */
    while (pqueue_peek(s->d1->unprocessed_rcds.q)) {
      dtls1_get_unprocessed_record(s);
      if (!dtls1_process_record(s)) {
        return 0;
      }
      dtls1_buffer_record(s, &(s->d1->processed_rcds), s->s3->rrec.seq_num);
    }
  }

  /* sync epoch numbers once all the unprocessed records have been processed */
  s->d1->processed_rcds.epoch = s->d1->r_epoch;
  s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;

  return 1;
}

static int dtls1_process_record(SSL *s) {
  int i, al;
  int enc_err;
  SSL_SESSION *sess;
  SSL3_RECORD *rr;
  unsigned int mac_size, orig_len;
  unsigned char md[EVP_MAX_MD_SIZE];

  rr = &(s->s3->rrec);
  sess = s->session;

  /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, and
   * we have that many bytes in s->packet. */
  rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]);

  /* ok, we can now read from 's->packet' data into 'rr' rr->input points at
   * rr->length bytes, which need to be copied into rr->data by either the
   * decryption or by the decompression When the data is 'copied' into the
   * rr->data buffer, rr->input will be pointed at the new buffer */

  /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length bytes
   * of encrypted compressed stuff. */

  /* check is not needed I believe */
  if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
    al = SSL_AD_RECORD_OVERFLOW;
    OPENSSL_PUT_ERROR(SSL, dtls1_process_record,
                      SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
    goto f_err;
  }

  /* decrypt in place in 'rr->input' */
  rr->data = rr->input;

  enc_err = s->enc_method->enc(s, 0);
  /* enc_err is:
   *    0: (in non-constant time) if the record is publically invalid.
   *    1: if the padding is valid
   *    -1: if the padding is invalid */
  if (enc_err == 0) {
    /* For DTLS we simply ignore bad packets. */
    rr->length = 0;
    s->packet_length = 0;
    goto err;
  }

  /* r->length is now the compressed data plus mac */
  if ((sess != NULL) && (s->enc_read_ctx != NULL) &&
      (EVP_MD_CTX_md(s->read_hash) != NULL)) {
    /* s->read_hash != NULL => mac_size != -1 */
    uint8_t *mac = NULL;
    uint8_t mac_tmp[EVP_MAX_MD_SIZE];
    mac_size = EVP_MD_CTX_size(s->read_hash);
    assert(mac_size <= EVP_MAX_MD_SIZE);

    /* kludge: *_cbc_remove_padding passes padding length in rr->type */
    orig_len = rr->length + ((unsigned int)rr->type >> 8);

    /* orig_len is the length of the record before any padding was removed.
     * This is public information, as is the MAC in use, therefore we can
     * safely process the record in a different amount of time if it's too
     * short to possibly contain a MAC. */
    if (orig_len < mac_size ||
        /* CBC records must have a padding length byte too. */
        (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
         orig_len < mac_size + 1)) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_LENGTH_TOO_SHORT);
      goto f_err;
    }

    if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
      /* We update the length so that the TLS header bytes can be constructed
       * correctly but we need to extract the MAC in constant time from within
       * the record, without leaking the contents of the padding bytes. */
      mac = mac_tmp;
      ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
      rr->length -= mac_size;
    } else {
      /* In this case there's no padding, so |orig_len| equals |rec->length|
       * and we checked that there's enough bytes for |mac_size| above. */
      rr->length -= mac_size;
      mac = &rr->data[rr->length];
    }

    i = s->enc_method->mac(s, md, 0 /* not send */);
    if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) {
      enc_err = -1;
    }
    if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) {
      enc_err = -1;
    }
  }

  if (enc_err < 0) {
    /* decryption failed, silently discard message */
    rr->length = 0;
    s->packet_length = 0;
    goto err;
  }

  if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
    al = SSL_AD_RECORD_OVERFLOW;
    OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_DATA_LENGTH_TOO_LONG);
    goto f_err;
  }

  rr->off = 0;
  /* So at this point the following is true
   * ssl->s3->rrec.type 	is the type of record
   * ssl->s3->rrec.length	== number of bytes in record
   * ssl->s3->rrec.off	== offset to first valid byte
   * ssl->s3->rrec.data	== where to take bytes from, increment
   *			   after use :-). */

  /* we have pulled in a full packet so zero things */
  s->packet_length = 0;
  dtls1_record_bitmap_update(s, &(s->d1->bitmap)); /* Mark receipt of record. */
  return 1;

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);

err:
  return 0;
}

/* Call this to get a new input record.
 * It will return <= 0 if more data is needed, normally due to an error
 * or non-blocking IO.
 * When it finishes, one packet has been decoded and can be found in
 * ssl->s3->rrec.type    - is the type of record
 * ssl->s3->rrec.data,   - data
 * ssl->s3->rrec.length, - number of bytes
 *
 * used only by dtls1_read_bytes */
int dtls1_get_record(SSL *s) {
  int ssl_major, ssl_minor;
  int i, n;
  SSL3_RECORD *rr;
  unsigned char *p = NULL;
  unsigned short version;
  DTLS1_BITMAP *bitmap;
  unsigned int is_next_epoch;

  rr = &(s->s3->rrec);

  /* The epoch may have changed. If so, process all the pending records. This
   * is a non-blocking operation. */
  dtls1_process_buffered_records(s);

  /* If we're renegotiating, then there may be buffered records. */
  if (dtls1_get_processed_record(s)) {
    return 1;
  }

  /* get something from the wire */
again:
  /* check if we have the header */
  if ((s->rstate != SSL_ST_READ_BODY) ||
      (s->packet_length < DTLS1_RT_HEADER_LENGTH)) {
    n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
    /* read timeout is handled by dtls1_read_bytes */
    if (n <= 0) {
      return n; /* error or non-blocking */
    }

    /* this packet contained a partial record, dump it */
    if (s->packet_length != DTLS1_RT_HEADER_LENGTH) {
      s->packet_length = 0;
      goto again;
    }

    s->rstate = SSL_ST_READ_BODY;

    p = s->packet;

    if (s->msg_callback) {
      s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, s,
                      s->msg_callback_arg);
    }

    /* Pull apart the header into the DTLS1_RECORD */
    rr->type = *(p++);
    ssl_major = *(p++);
    ssl_minor = *(p++);
    version = (ssl_major << 8) | ssl_minor;

    /* sequence number is 64 bits, with top 2 bytes = epoch */
    n2s(p, rr->epoch);

    memcpy(&(s->s3->read_sequence[2]), p, 6);
    p += 6;

    n2s(p, rr->length);

    /* Lets check version */
    if (s->s3->have_version) {
      if (version != s->version) {
        /* The record's version doesn't match, so silently drop it.
         *
         * TODO(davidben): This doesn't work. The DTLS record layer is not
         * packet-based, so the remainder of the packet isn't dropped and we
         * get a framing error. It's also unclear what it means to silently
         * drop a record in a packet containing two records. */
        rr->length = 0;
        s->packet_length = 0;
        goto again;
      }
    }

    if ((version & 0xff00) != (s->version & 0xff00)) {
      /* wrong version, silently discard record */
      rr->length = 0;
      s->packet_length = 0;
      goto again;
    }

    if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
      /* record too long, silently discard it */
      rr->length = 0;
      s->packet_length = 0;
      goto again;
    }

    /* now s->rstate == SSL_ST_READ_BODY */
  }

  /* s->rstate == SSL_ST_READ_BODY, get and decode the data */

  if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) {
    /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
    i = rr->length;
    n = ssl3_read_n(s, i, i, 1);
    if (n <= 0) {
      return n; /* error or non-blocking io */
    }

    /* this packet contained a partial record, dump it */
    if (n != i) {
      rr->length = 0;
      s->packet_length = 0;
      goto again;
    }

    /* now n == rr->length,
     * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
  }
  s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */

  /* match epochs.  NULL means the packet is dropped on the floor */
  bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
  if (bitmap == NULL) {
    rr->length = 0;
    s->packet_length = 0; /* dump this record */
    goto again;           /* get another record */
  }

  /* Check whether this is a repeat, or aged record. */
  if (!dtls1_record_replay_check(s, bitmap)) {
    rr->length = 0;
    s->packet_length = 0; /* dump this record */
    goto again;           /* get another record */
  }

  /* just read a 0 length packet */
  if (rr->length == 0) {
    goto again;
  }

  /* If this record is from the next epoch (either HM or ALERT),
   * and a handshake is currently in progress, buffer it since it
   * cannot be processed at this time.
   */
  if (is_next_epoch) {
    if (SSL_in_init(s) || s->in_handshake) {
      dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
    }
    rr->length = 0;
    s->packet_length = 0;
    goto again;
  }

  if (!dtls1_process_record(s)) {
    rr->length = 0;
    s->packet_length = 0; /* dump this record */
    goto again;           /* get another record */
  }

  return 1;
}

/* Return up to 'len' payload bytes received in 'type' records.
 * 'type' is one of the following:
 *
 *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
 *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
 *   -  0 (during a shutdown, no data has to be returned)
 *
 * If we don't have stored data to work from, read a SSL/TLS record first
 * (possibly multiple records if we still don't have anything to return).
 *
 * This function must handle any surprises the peer may have for us, such as
 * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
 * a surprise, but handled as if it were), or renegotiation requests.
 * Also if record payloads contain fragments too small to process, we store
 * them until there is enough for the respective protocol (the record protocol
 * may use arbitrary fragmentation and even interleaving):
 *     Change cipher spec protocol
 *             just 1 byte needed, no need for keeping anything stored
 *     Alert protocol
 *             2 bytes needed (AlertLevel, AlertDescription)
 *     Handshake protocol
 *             4 bytes needed (HandshakeType, uint24 length) -- we just have
 *             to detect unexpected Client Hello and Hello Request messages
 *             here, anything else is handled by higher layers
 *     Application data protocol
 *             none of our business
 */
int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) {
  int al, i, j, ret;
  unsigned int n;
  SSL3_RECORD *rr;
  void (*cb)(const SSL *ssl, int type2, int val) = NULL;

  if (s->s3->rbuf.buf == NULL && !ssl3_setup_buffers(s)) {
      return -1;
  }

  /* XXX: check what the second '&& type' is about */
  if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
       (type != SSL3_RT_HANDSHAKE) && type) ||
      (peek && (type != SSL3_RT_APPLICATION_DATA))) {
    OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  /* check whether there's a handshake message (client hello?) waiting */
  ret = have_handshake_fragment(s, type, buf, len, peek);
  if (ret) {
    return ret;
  }

  /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */

  if (!s->in_handshake && SSL_in_init(s)) {
    /* type == SSL3_RT_APPLICATION_DATA */
    i = s->handshake_func(s);
    if (i < 0) {
      return i;
    }
    if (i == 0) {
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
      return -1;
    }
  }

start:
  s->rwstate = SSL_NOTHING;

  /* s->s3->rrec.type     - is the type of record
   * s->s3->rrec.data     - data
   * s->s3->rrec.off      - offset into 'data' for next read
   * s->s3->rrec.length   - number of bytes. */
  rr = &s->s3->rrec;

  /* We are not handshaking and have no data yet,
   * so process data buffered during the last handshake
   * in advance, if any.
   */
  if (s->state == SSL_ST_OK && rr->length == 0) {
    pitem *item;
    item = pqueue_pop(s->d1->buffered_app_data.q);
    if (item) {
      dtls1_copy_record(s, item);

      OPENSSL_free(item->data);
      pitem_free(item);
    }
  }

  /* Check for timeout */
  if (dtls1_handle_timeout(s) > 0) {
    goto start;
  }

  /* get new packet if necessary */
  if (rr->length == 0 || s->rstate == SSL_ST_READ_BODY) {
    ret = dtls1_get_record(s);
    if (ret <= 0) {
      ret = dtls1_read_failed(s, ret);
      /* anything other than a timeout is an error */
      if (ret <= 0) {
        return ret;
      } else {
        goto start;
      }
    }
  }

  /* we now have a packet which can be read and processed */

  /* |change_cipher_spec is set when we receive a ChangeCipherSpec and reset by
   * ssl3_get_finished. */
  if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE) {
    /* We now have application data between CCS and Finished. Most likely the
     * packets were reordered on their way, so buffer the application data for
     * later processing rather than dropping the connection. */
    dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
    rr->length = 0;
    goto start;
  }

  /* If the other end has shut down, throw anything we read away (even in
   * 'peek' mode) */
  if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
    rr->length = 0;
    s->rwstate = SSL_NOTHING;
    return 0;
  }


  if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
    /* make sure that we are not getting application data when we
     * are doing a handshake for the first time */
    if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
        (s->enc_read_ctx == NULL)) {
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
      goto f_err;
    }

    if (len <= 0) {
      return len;
    }

    if ((unsigned int)len > rr->length) {
      n = rr->length;
    } else {
      n = (unsigned int)len;
    }

    memcpy(buf, &(rr->data[rr->off]), n);
    if (!peek) {
      rr->length -= n;
      rr->off += n;
      if (rr->length == 0) {
        s->rstate = SSL_ST_READ_HEADER;
        rr->off = 0;
      }
    }

    return n;
  }

  /* If we get here, then type != rr->type; if we have a handshake message,
   * then it was unexpected (Hello Request or Client Hello). */

  /* In case of record types for which we have 'fragment' storage, fill that so
   * that we can process the data at a fixed place. */
  {
    unsigned int k, dest_maxlen = 0;
    uint8_t *dest = NULL;
    unsigned int *dest_len = NULL;

    if (rr->type == SSL3_RT_HANDSHAKE) {
      dest_maxlen = sizeof s->d1->handshake_fragment;
      dest = s->d1->handshake_fragment;
      dest_len = &s->d1->handshake_fragment_len;
    } else if (rr->type == SSL3_RT_ALERT) {
      dest_maxlen = sizeof(s->d1->alert_fragment);
      dest = s->d1->alert_fragment;
      dest_len = &s->d1->alert_fragment_len;
    }
    /* else it's a CCS message, or application data or wrong */
    else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) {
      /* Application data while renegotiating is allowed. Try again reading. */
      if (rr->type == SSL3_RT_APPLICATION_DATA) {
        BIO *bio;
        s->s3->in_read_app_data = 2;
        bio = SSL_get_rbio(s);
        s->rwstate = SSL_READING;
        BIO_clear_retry_flags(bio);
        BIO_set_retry_read(bio);
        return -1;
      }

      /* Not certain if this is the right error handling */
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNEXPECTED_RECORD);
      goto f_err;
    }

    if (dest_maxlen > 0) {
      /* XDTLS:  In a pathalogical case, the Client Hello
       *  may be fragmented--don't always expect dest_maxlen bytes */
      if (rr->length < dest_maxlen) {
        s->rstate = SSL_ST_READ_HEADER;
        rr->length = 0;
        goto start;
      }

      /* now move 'n' bytes: */
      for (k = 0; k < dest_maxlen; k++) {
        dest[k] = rr->data[rr->off++];
        rr->length--;
      }
      *dest_len = dest_maxlen;
    }
  }

  /* s->d1->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;
   * s->d1->alert_fragment_len == 7      iff  rr->type == SSL3_RT_ALERT.
   * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */

  /* If we are a client, check for an incoming 'Hello Request': */
  if (!s->server && s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH &&
      s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST &&
      s->session != NULL && s->session->cipher != NULL) {
    s->d1->handshake_fragment_len = 0;

    if ((s->d1->handshake_fragment[1] != 0) ||
        (s->d1->handshake_fragment[2] != 0) ||
        (s->d1->handshake_fragment[3] != 0)) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_BAD_HELLO_REQUEST);
      goto f_err;
    }

    /* no need to check sequence number on HELLO REQUEST messages */

    if (s->msg_callback) {
      s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                      s->d1->handshake_fragment, 4, s, s->msg_callback_arg);
    }

    if (SSL_is_init_finished(s) && !s->s3->renegotiate) {
      s->d1->handshake_read_seq++;
      s->new_session = 1;
      ssl3_renegotiate(s);
      if (ssl3_renegotiate_check(s)) {
        i = s->handshake_func(s);
        if (i < 0) {
          return i;
        }
        if (i == 0) {
          OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
          return -1;
        }
      }
    }

    /* we either finished a handshake or ignored the request, now try again to
     * obtain the (application) data we were asked for */
    goto start;
  }

  if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) {
    int alert_level = s->d1->alert_fragment[0];
    int alert_descr = s->d1->alert_fragment[1];

    s->d1->alert_fragment_len = 0;

    if (s->msg_callback) {
      s->msg_callback(0, s->version, SSL3_RT_ALERT, s->d1->alert_fragment, 2, s,
                      s->msg_callback_arg);
    }

    if (s->info_callback != NULL) {
      cb = s->info_callback;
    } else if (s->ctx->info_callback != NULL) {
      cb = s->ctx->info_callback;
    }

    if (cb != NULL) {
      j = (alert_level << 8) | alert_descr;
      cb(s, SSL_CB_READ_ALERT, j);
    }

    if (alert_level == 1) { /* warning */
      s->s3->warn_alert = alert_descr;
      if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
        s->shutdown |= SSL_RECEIVED_SHUTDOWN;
        return 0;
      }
    } else if (alert_level == 2) { /* fatal */
      char tmp[16];

      s->rwstate = SSL_NOTHING;
      s->s3->fatal_alert = alert_descr;
      OPENSSL_PUT_ERROR(SSL, 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;
      SSL_CTX_remove_session(s->ctx, s->session);
      return 0;
    } else {
      al = SSL_AD_ILLEGAL_PARAMETER;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNKNOWN_ALERT_TYPE);
      goto f_err;
    }

    goto start;
  }

  if (s->shutdown & SSL_SENT_SHUTDOWN) {
    /* but we have not received a shutdown */
    s->rwstate = SSL_NOTHING;
    rr->length = 0;
    return 0;
  }

  if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
    struct ccs_header_st ccs_hdr;
    unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;

    dtls1_get_ccs_header(rr->data, &ccs_hdr);

    /* '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 != ccs_hdr_len) || (rr->off != 0) ||
        (rr->data[0] != SSL3_MT_CCS)) {
      al = SSL_AD_ILLEGAL_PARAMETER;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_BAD_CHANGE_CIPHER_SPEC);
      goto f_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);
    }

    /* We can't process a CCS now, because previous handshake
     * messages are still missing, so just drop it.
     */
    if (!s->d1->change_cipher_spec_ok) {
      goto start;
    }

    s->d1->change_cipher_spec_ok = 0;

    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);

    goto start;
  }

  /* Unexpected handshake message (Client Hello, or protocol violation) */
  if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
      !s->in_handshake) {
    struct hm_header_st msg_hdr;

    /* this may just be a stale retransmit */
    dtls1_get_message_header(rr->data, &msg_hdr);
    if (rr->epoch != s->d1->r_epoch) {
      rr->length = 0;
      goto start;
    }

    /* If we are server, we may have a repeated FINISHED of the client here,
     * then retransmit our CCS and FINISHED. */
    if (msg_hdr.type == SSL3_MT_FINISHED) {
      if (dtls1_check_timeout_num(s) < 0) {
        return -1;
      }

      dtls1_retransmit_buffered_messages(s);
      rr->length = 0;
      goto start;
    }

    if ((s->state & SSL_ST_MASK) == SSL_ST_OK) {
      s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
      s->renegotiate = 1;
      s->new_session = 1;
    }
    i = s->handshake_func(s);
    if (i < 0) {
      return i;
    }
    if (i == 0) {
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
      return -1;
    }

    goto start;
  }

  switch (rr->type) {
    default:
      /* TLS just ignores unknown message types */
      if (s->version == TLS1_VERSION) {
        rr->length = 0;
        goto start;
      }
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNEXPECTED_RECORD);
      goto f_err;

    case SSL3_RT_CHANGE_CIPHER_SPEC:
    case SSL3_RT_ALERT:
    case SSL3_RT_HANDSHAKE:
      /* we already handled all of these, with the possible exception of
       * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not
       * happen when type != rr->type */
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, ERR_R_INTERNAL_ERROR);
      goto f_err;

    case SSL3_RT_APPLICATION_DATA:
      /* At this point, we were expecting handshake data, but have application
       * data. If the library was running inside ssl3_read() (i.e.
       * in_read_app_data is set) and it makes sense to read application data
       * at this point (session renegotiation not yet started), we will indulge
       * it. */
      if (s->s3->in_read_app_data && (s->s3->total_renegotiations != 0) &&
          (((s->state & SSL_ST_CONNECT) &&
            (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
            (s->state <= SSL3_ST_CR_SRVR_HELLO_A)) ||
           ((s->state & SSL_ST_ACCEPT) &&
            (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
            (s->state >= SSL3_ST_SR_CLNT_HELLO_A)))) {
        s->s3->in_read_app_data = 2;
        return -1;
      } else {
        al = SSL_AD_UNEXPECTED_MESSAGE;
        OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNEXPECTED_RECORD);
        goto f_err;
      }
  }

  /* not reached */

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
  return -1;
}

int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) {
  int i;

  if (SSL_in_init(s) && !s->in_handshake) {
    i = s->handshake_func(s);
    if (i < 0) {
      return i;
    }
    if (i == 0) {
      OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data_bytes,
                        SSL_R_SSL_HANDSHAKE_FAILURE);
      return -1;
    }
  }

  if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data_bytes,
                      SSL_R_DTLS_MESSAGE_TOO_BIG);
    return -1;
  }

  i = dtls1_write_bytes(s, type, buf_, len);
  return i;
}


/* this only happens when a client hello is received and a handshake is
 * started. */
static int have_handshake_fragment(SSL *s, int type, uint8_t *buf,
                                   int len, int peek) {
  if (type == SSL3_RT_HANDSHAKE && s->d1->handshake_fragment_len > 0) {
    /* (partially) satisfy request from storage */
    uint8_t *src = s->d1->handshake_fragment;
    uint8_t *dst = buf;
    unsigned int k, n;

    /* peek == 0 */
    n = 0;
    while (len > 0 && s->d1->handshake_fragment_len > 0) {
      *dst++ = *src++;
      len--;
      s->d1->handshake_fragment_len--;
      n++;
    }
    /* move any remaining fragment bytes: */
    for (k = 0; k < s->d1->handshake_fragment_len; k++) {
      s->d1->handshake_fragment[k] = *src++;
    }
    return n;
  }

  return 0;
}

/* Call this to write data in records of type 'type' It will return <= 0 if not
 * all data has been sent or non-blocking IO. */
int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) {
  int i;

  assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
  s->rwstate = SSL_NOTHING;
  i = do_dtls1_write(s, type, buf, len);
  return i;
}

static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
                          unsigned int len) {
  uint8_t *p, *pseq;
  int i, mac_size = 0;
  int prefix_len = 0;
  int eivlen = 0;
  SSL3_RECORD *wr;
  SSL3_BUFFER *wb;
  SSL_SESSION *sess;

  /* first check if there is a SSL3_BUFFER still being written
   * out.  This will happen with non blocking IO */
  if (s->s3->wbuf.left != 0) {
    assert(0); /* XDTLS:  want to see if we ever get here */
    return ssl3_write_pending(s, type, buf, len);
  }

  /* If we have an alert to send, lets send it */
  if (s->s3->alert_dispatch) {
    i = s->method->ssl_dispatch_alert(s);
    if (i <= 0) {
      return i;
    }
    /* if it went, fall through and send more stuff */
  }

  if (len == 0) {
    return 0;
  }

  wr = &(s->s3->wrec);
  wb = &(s->s3->wbuf);
  sess = s->session;

  if (sess != NULL && s->enc_write_ctx != NULL &&
      EVP_MD_CTX_md(s->write_hash) != NULL) {
    mac_size = EVP_MD_CTX_size(s->write_hash);
    if (mac_size < 0) {
      goto err;
    }
  }

  p = wb->buf + prefix_len;

  /* write the header */

  *(p++) = type & 0xff;
  wr->type = type;
  /* Special case: for hello verify request, client version 1.0 and
   * we haven't decided which version to use yet send back using
   * version 1.0 header: otherwise some clients will ignore it.
   */
  if (!s->s3->have_version) {
    *(p++) = DTLS1_VERSION >> 8;
    *(p++) = DTLS1_VERSION & 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;
  p += 10;

  /* Explicit IV length, block ciphers appropriate version flag */
  if (s->enc_write_ctx) {
    int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
    if (mode == EVP_CIPH_CBC_MODE) {
      eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
      if (eivlen <= 1) {
        eivlen = 0;
      }
    } else if (mode == EVP_CIPH_GCM_MODE) {
      /* Need explicit part of IV for GCM mode */
      eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
    }
  }

  /* lets setup the record stuff. */
  wr->data = p + eivlen; /* make room for IV in case of CBC */
  wr->length = (int)len;
  wr->input = (unsigned char *)buf;

  /* we now 'read' from wr->input, wr->length bytes into wr->data */
  memcpy(wr->data, wr->input, wr->length);
  wr->input = wr->data;

  /* we should still have the output to wr->data and the input from wr->input.
   * Length should be wr->length. wr->data still points in the wb->buf */
  if (mac_size != 0) {
    if (s->enc_method->mac(s, &(p[wr->length + eivlen]), 1) < 0) {
      goto err;
    }
    wr->length += mac_size;
  }

  /* this is true regardless of mac size */
  wr->input = p;
  wr->data = p;
  wr->length += eivlen;

  if (s->enc_method->enc(s, 1) < 1) {
    goto err;
  }

  /* there's only one epoch between handshake and app data */
  s2n(s->d1->w_epoch, pseq);

  memcpy(pseq, &(s->s3->write_sequence[2]), 6);
  pseq += 6;
  s2n(wr->length, pseq);

  if (s->msg_callback) {
    s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
                    DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
  }

  /* we should now have wr->data pointing to the encrypted data, which is
   * wr->length long */
  wr->type = type; /* not needed but helps for debugging */
  wr->length += DTLS1_RT_HEADER_LENGTH;

  ssl3_record_sequence_update(&(s->s3->write_sequence[0]));

  /* now let's set up wb */
  wb->left = prefix_len + wr->length;
  wb->offset = 0;

  /* memorize arguments so that ssl3_write_pending can detect bad write retries
   * later */
  s->s3->wpend_tot = len;
  s->s3->wpend_buf = buf;
  s->s3->wpend_type = type;
  s->s3->wpend_ret = len;

  /* we now just need to write the buffer */
  return ssl3_write_pending(s, type, buf, len);

err:
  return -1;
}

static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) {
  int cmp;
  unsigned int shift;
  const uint8_t *seq = s->s3->read_sequence;

  cmp = satsub64be(seq, bitmap->max_seq_num);
  if (cmp > 0) {
    memcpy(s->s3->rrec.seq_num, seq, 8);
    return 1; /* this record in new */
  }
  shift = -cmp;
  if (shift >= sizeof(bitmap->map) * 8) {
    return 0; /* stale, outside the window */
  } else if (bitmap->map & (((uint64_t)1) << shift)) {
    return 0; /* record previously received */
  }

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

static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) {
  int cmp;
  unsigned int shift;
  const uint8_t *seq = s->s3->read_sequence;

  cmp = satsub64be(seq, bitmap->max_seq_num);
  if (cmp > 0) {
    shift = cmp;
    if (shift < sizeof(bitmap->map) * 8) {
      bitmap->map <<= shift, bitmap->map |= 1UL;
    } else {
      bitmap->map = 1UL;
    }
    memcpy(bitmap->max_seq_num, seq, 8);
  } else {
    shift = -cmp;
    if (shift < sizeof(bitmap->map) * 8) {
      bitmap->map |= ((uint64_t)1) << shift;
    }
  }
}

int dtls1_dispatch_alert(SSL *s) {
  int i, j;
  void (*cb)(const SSL *ssl, int type, int val) = NULL;
  uint8_t buf[DTLS1_AL_HEADER_LENGTH];
  uint8_t *ptr = &buf[0];

  s->s3->alert_dispatch = 0;

  memset(buf, 0x00, sizeof(buf));
  *ptr++ = s->s3->send_alert[0];
  *ptr++ = s->s3->send_alert[1];

  i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf));
  if (i <= 0) {
    s->s3->alert_dispatch = 1;
  } else {
    if (s->s3->send_alert[0] == SSL3_AL_FATAL) {
      (void)BIO_flush(s->wbio);
    }

    if (s->msg_callback) {
      s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s,
                      s->msg_callback_arg);
    }

    if (s->info_callback != NULL) {
      cb = s->info_callback;
    } else if (s->ctx->info_callback != NULL) {
      cb = s->ctx->info_callback;
    }

    if (cb != NULL) {
      j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
      cb(s, SSL_CB_WRITE_ALERT, j);
    }
  }

  return i;
}

static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
                                      unsigned int *is_next_epoch) {
  *is_next_epoch = 0;

  /* In current epoch, accept HM, CCS, DATA, & ALERT */
  if (rr->epoch == s->d1->r_epoch) {
    return &s->d1->bitmap;
  } else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
             (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
    /* Only HM and ALERT messages can be from the next epoch */
    *is_next_epoch = 1;
    return &s->d1->next_bitmap;
  }

  return NULL;
}

void dtls1_reset_seq_numbers(SSL *s, int rw) {
  uint8_t *seq;
  unsigned int seq_bytes = sizeof(s->s3->read_sequence);

  if (rw & SSL3_CC_READ) {
    seq = s->s3->read_sequence;
    s->d1->r_epoch++;
    memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
    memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
  } else {
    seq = s->s3->write_sequence;
    memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
    s->d1->w_epoch++;
  }

  memset(seq, 0x00, seq_bytes);
}
