Home | History | Annotate | Download | only in ssl
      1 /*
      2  * DTLS implementation written by Nagendra Modadugu
      3  * (nagendra (at) cs.stanford.edu) for the OpenSSL project 2005.
      4  */
      5 /* ====================================================================
      6  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in
     17  *    the documentation and/or other materials provided with the
     18  *    distribution.
     19  *
     20  * 3. All advertising materials mentioning features or use of this
     21  *    software must display the following acknowledgment:
     22  *    "This product includes software developed by the OpenSSL Project
     23  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
     24  *
     25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26  *    endorse or promote products derived from this software without
     27  *    prior written permission. For written permission, please contact
     28  *    openssl-core (at) openssl.org.
     29  *
     30  * 5. Products derived from this software may not be called "OpenSSL"
     31  *    nor may "OpenSSL" appear in their names without prior written
     32  *    permission of the OpenSSL Project.
     33  *
     34  * 6. Redistributions of any form whatsoever must retain the following
     35  *    acknowledgment:
     36  *    "This product includes software developed by the OpenSSL Project
     37  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
     38  *
     39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50  * OF THE POSSIBILITY OF SUCH DAMAGE.
     51  * ====================================================================
     52  *
     53  * This product includes cryptographic software written by Eric Young
     54  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
     59  * All rights reserved.
     60  *
     61  * This package is an SSL implementation written
     62  * by Eric Young (eay (at) cryptsoft.com).
     63  * The implementation was written so as to conform with Netscapes SSL.
     64  *
     65  * This library is free for commercial and non-commercial use as long as
     66  * the following conditions are aheared to.  The following conditions
     67  * apply to all code found in this distribution, be it the RC4, RSA,
     68  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     69  * included with this distribution is covered by the same copyright terms
     70  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     71  *
     72  * Copyright remains Eric Young's, and as such any Copyright notices in
     73  * the code are not to be removed.
     74  * If this package is used in a product, Eric Young should be given attribution
     75  * as the author of the parts of the library used.
     76  * This can be in the form of a textual message at program startup or
     77  * in documentation (online or textual) provided with the package.
     78  *
     79  * Redistribution and use in source and binary forms, with or without
     80  * modification, are permitted provided that the following conditions
     81  * are met:
     82  * 1. Redistributions of source code must retain the copyright
     83  *    notice, this list of conditions and the following disclaimer.
     84  * 2. Redistributions in binary form must reproduce the above copyright
     85  *    notice, this list of conditions and the following disclaimer in the
     86  *    documentation and/or other materials provided with the distribution.
     87  * 3. All advertising materials mentioning features or use of this software
     88  *    must display the following acknowledgement:
     89  *    "This product includes cryptographic software written by
     90  *     Eric Young (eay (at) cryptsoft.com)"
     91  *    The word 'cryptographic' can be left out if the rouines from the library
     92  *    being used are not cryptographic related :-).
     93  * 4. If you include any Windows specific code (or a derivative thereof) from
     94  *    the apps directory (application code) you must include an acknowledgement:
     95  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     96  *
     97  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     98  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     99  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    100  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    101  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    102  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    103  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    104  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    105  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    106  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    107  * SUCH DAMAGE.
    108  *
    109  * The licence and distribution terms for any publically available version or
    110  * derivative of this code cannot be changed.  i.e. this code cannot simply be
    111  * copied and put under another distribution licence
    112  * [including the GNU Public Licence.] */
    113 
    114 #include <openssl/ssl.h>
    115 
    116 #include <assert.h>
    117 #include <limits.h>
    118 #include <string.h>
    119 
    120 #include <openssl/buf.h>
    121 #include <openssl/err.h>
    122 #include <openssl/evp.h>
    123 #include <openssl/mem.h>
    124 #include <openssl/rand.h>
    125 #include <openssl/type_check.h>
    126 
    127 #include "../crypto/internal.h"
    128 #include "internal.h"
    129 
    130 
    131 /* TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable
    132  * for these values? Notably, why is kMinMTU a function of the transport
    133  * protocol's overhead rather than, say, what's needed to hold a minimally-sized
    134  * handshake fragment plus protocol overhead. */
    135 
    136 /* kMinMTU is the minimum acceptable MTU value. */
    137 static const unsigned int kMinMTU = 256 - 28;
    138 
    139 /* kDefaultMTU is the default MTU value to use if neither the user nor
    140  * the underlying BIO supplies one. */
    141 static const unsigned int kDefaultMTU = 1500 - 28;
    142 
    143 
    144 /* Receiving handshake messages. */
    145 
    146 static void dtls1_hm_fragment_free(hm_fragment *frag) {
    147   if (frag == NULL) {
    148     return;
    149   }
    150   OPENSSL_free(frag->data);
    151   OPENSSL_free(frag->reassembly);
    152   OPENSSL_free(frag);
    153 }
    154 
    155 static hm_fragment *dtls1_hm_fragment_new(const struct hm_header_st *msg_hdr) {
    156   hm_fragment *frag = OPENSSL_malloc(sizeof(hm_fragment));
    157   if (frag == NULL) {
    158     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    159     return NULL;
    160   }
    161   OPENSSL_memset(frag, 0, sizeof(hm_fragment));
    162   frag->type = msg_hdr->type;
    163   frag->seq = msg_hdr->seq;
    164   frag->msg_len = msg_hdr->msg_len;
    165 
    166   /* Allocate space for the reassembled message and fill in the header. */
    167   frag->data = OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len);
    168   if (frag->data == NULL) {
    169     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    170     goto err;
    171   }
    172 
    173   CBB cbb;
    174   if (!CBB_init_fixed(&cbb, frag->data, DTLS1_HM_HEADER_LENGTH) ||
    175       !CBB_add_u8(&cbb, msg_hdr->type) ||
    176       !CBB_add_u24(&cbb, msg_hdr->msg_len) ||
    177       !CBB_add_u16(&cbb, msg_hdr->seq) ||
    178       !CBB_add_u24(&cbb, 0 /* frag_off */) ||
    179       !CBB_add_u24(&cbb, msg_hdr->msg_len) ||
    180       !CBB_finish(&cbb, NULL, NULL)) {
    181     CBB_cleanup(&cbb);
    182     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    183     goto err;
    184   }
    185 
    186   /* If the handshake message is empty, |frag->reassembly| is NULL. */
    187   if (msg_hdr->msg_len > 0) {
    188     /* Initialize reassembly bitmask. */
    189     if (msg_hdr->msg_len + 7 < msg_hdr->msg_len) {
    190       OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    191       goto err;
    192     }
    193     size_t bitmask_len = (msg_hdr->msg_len + 7) / 8;
    194     frag->reassembly = OPENSSL_malloc(bitmask_len);
    195     if (frag->reassembly == NULL) {
    196       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    197       goto err;
    198     }
    199     OPENSSL_memset(frag->reassembly, 0, bitmask_len);
    200   }
    201 
    202   return frag;
    203 
    204 err:
    205   dtls1_hm_fragment_free(frag);
    206   return NULL;
    207 }
    208 
    209 /* bit_range returns a |uint8_t| with bits |start|, inclusive, to |end|,
    210  * exclusive, set. */
    211 static uint8_t bit_range(size_t start, size_t end) {
    212   return (uint8_t)(~((1u << start) - 1) & ((1u << end) - 1));
    213 }
    214 
    215 /* dtls1_hm_fragment_mark marks bytes |start|, inclusive, to |end|, exclusive,
    216  * as received in |frag|. If |frag| becomes complete, it clears
    217  * |frag->reassembly|. The range must be within the bounds of |frag|'s message
    218  * and |frag->reassembly| must not be NULL. */
    219 static void dtls1_hm_fragment_mark(hm_fragment *frag, size_t start,
    220                                    size_t end) {
    221   size_t msg_len = frag->msg_len;
    222 
    223   if (frag->reassembly == NULL || start > end || end > msg_len) {
    224     assert(0);
    225     return;
    226   }
    227   /* A zero-length message will never have a pending reassembly. */
    228   assert(msg_len > 0);
    229 
    230   if ((start >> 3) == (end >> 3)) {
    231     frag->reassembly[start >> 3] |= bit_range(start & 7, end & 7);
    232   } else {
    233     frag->reassembly[start >> 3] |= bit_range(start & 7, 8);
    234     for (size_t i = (start >> 3) + 1; i < (end >> 3); i++) {
    235       frag->reassembly[i] = 0xff;
    236     }
    237     if ((end & 7) != 0) {
    238       frag->reassembly[end >> 3] |= bit_range(0, end & 7);
    239     }
    240   }
    241 
    242   /* Check if the fragment is complete. */
    243   for (size_t i = 0; i < (msg_len >> 3); i++) {
    244     if (frag->reassembly[i] != 0xff) {
    245       return;
    246     }
    247   }
    248   if ((msg_len & 7) != 0 &&
    249       frag->reassembly[msg_len >> 3] != bit_range(0, msg_len & 7)) {
    250     return;
    251   }
    252 
    253   OPENSSL_free(frag->reassembly);
    254   frag->reassembly = NULL;
    255 }
    256 
    257 /* dtls1_is_current_message_complete returns one if the current handshake
    258  * message is complete and zero otherwise. */
    259 static int dtls1_is_current_message_complete(const SSL *ssl) {
    260   hm_fragment *frag = ssl->d1->incoming_messages[ssl->d1->handshake_read_seq %
    261                                                  SSL_MAX_HANDSHAKE_FLIGHT];
    262   return frag != NULL && frag->reassembly == NULL;
    263 }
    264 
    265 /* dtls1_get_incoming_message returns the incoming message corresponding to
    266  * |msg_hdr|. If none exists, it creates a new one and inserts it in the
    267  * queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It
    268  * returns NULL on failure. The caller does not take ownership of the result. */
    269 static hm_fragment *dtls1_get_incoming_message(
    270     SSL *ssl, const struct hm_header_st *msg_hdr) {
    271   if (msg_hdr->seq < ssl->d1->handshake_read_seq ||
    272       msg_hdr->seq - ssl->d1->handshake_read_seq >= SSL_MAX_HANDSHAKE_FLIGHT) {
    273     return NULL;
    274   }
    275 
    276   size_t idx = msg_hdr->seq % SSL_MAX_HANDSHAKE_FLIGHT;
    277   hm_fragment *frag = ssl->d1->incoming_messages[idx];
    278   if (frag != NULL) {
    279     assert(frag->seq == msg_hdr->seq);
    280     /* The new fragment must be compatible with the previous fragments from this
    281      * message. */
    282     if (frag->type != msg_hdr->type ||
    283         frag->msg_len != msg_hdr->msg_len) {
    284       OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
    285       ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    286       return NULL;
    287     }
    288     return frag;
    289   }
    290 
    291   /* This is the first fragment from this message. */
    292   frag = dtls1_hm_fragment_new(msg_hdr);
    293   if (frag == NULL) {
    294     return NULL;
    295   }
    296   ssl->d1->incoming_messages[idx] = frag;
    297   return frag;
    298 }
    299 
    300 /* dtls1_process_handshake_record reads a handshake record and processes it. It
    301  * returns one if the record was successfully processed and 0 or -1 on error. */
    302 static int dtls1_process_handshake_record(SSL *ssl) {
    303   SSL3_RECORD *rr = &ssl->s3->rrec;
    304 
    305 start:
    306   if (rr->length == 0) {
    307     int ret = dtls1_get_record(ssl);
    308     if (ret <= 0) {
    309       return ret;
    310     }
    311   }
    312 
    313   /* Cross-epoch records are discarded, but we may receive out-of-order
    314    * application data between ChangeCipherSpec and Finished or a
    315    * ChangeCipherSpec before the appropriate point in the handshake. Those must
    316    * be silently discarded.
    317    *
    318    * However, only allow the out-of-order records in the correct epoch.
    319    * Application data must come in the encrypted epoch, and ChangeCipherSpec in
    320    * the unencrypted epoch (we never renegotiate). Other cases fall through and
    321    * fail with a fatal error. */
    322   if ((rr->type == SSL3_RT_APPLICATION_DATA &&
    323        ssl->s3->aead_read_ctx != NULL) ||
    324       (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC &&
    325        ssl->s3->aead_read_ctx == NULL)) {
    326     rr->length = 0;
    327     goto start;
    328   }
    329 
    330   if (rr->type != SSL3_RT_HANDSHAKE) {
    331     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    332     OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
    333     return -1;
    334   }
    335 
    336   CBS cbs;
    337   CBS_init(&cbs, rr->data, rr->length);
    338 
    339   while (CBS_len(&cbs) > 0) {
    340     /* Read a handshake fragment. */
    341     struct hm_header_st msg_hdr;
    342     CBS body;
    343     if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) {
    344       OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
    345       ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    346       return -1;
    347     }
    348 
    349     const size_t frag_off = msg_hdr.frag_off;
    350     const size_t frag_len = msg_hdr.frag_len;
    351     const size_t msg_len = msg_hdr.msg_len;
    352     if (frag_off > msg_len || frag_off + frag_len < frag_off ||
    353         frag_off + frag_len > msg_len ||
    354         msg_len > ssl_max_handshake_message_len(ssl)) {
    355       OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
    356       ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    357       return -1;
    358     }
    359 
    360     /* The encrypted epoch in DTLS has only one handshake message. */
    361     if (ssl->d1->r_epoch == 1 && msg_hdr.seq != ssl->d1->handshake_read_seq) {
    362       OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
    363       ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    364       return -1;
    365     }
    366 
    367     if (msg_hdr.seq < ssl->d1->handshake_read_seq ||
    368         msg_hdr.seq >
    369             (unsigned)ssl->d1->handshake_read_seq + SSL_MAX_HANDSHAKE_FLIGHT) {
    370       /* Ignore fragments from the past, or ones too far in the future. */
    371       continue;
    372     }
    373 
    374     hm_fragment *frag = dtls1_get_incoming_message(ssl, &msg_hdr);
    375     if (frag == NULL) {
    376       return -1;
    377     }
    378     assert(frag->msg_len == msg_len);
    379 
    380     if (frag->reassembly == NULL) {
    381       /* The message is already assembled. */
    382       continue;
    383     }
    384     assert(msg_len > 0);
    385 
    386     /* Copy the body into the fragment. */
    387     OPENSSL_memcpy(frag->data + DTLS1_HM_HEADER_LENGTH + frag_off,
    388                    CBS_data(&body), CBS_len(&body));
    389     dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len);
    390   }
    391 
    392   rr->length = 0;
    393   ssl_read_buffer_discard(ssl);
    394   return 1;
    395 }
    396 
    397 int dtls1_get_message(SSL *ssl) {
    398   if (ssl->s3->tmp.reuse_message) {
    399     /* There must be a current message. */
    400     assert(ssl->init_msg != NULL);
    401     ssl->s3->tmp.reuse_message = 0;
    402   } else {
    403     dtls1_release_current_message(ssl, 0 /* don't free buffer */);
    404   }
    405 
    406   /* Process handshake records until the current message is ready. */
    407   while (!dtls1_is_current_message_complete(ssl)) {
    408     int ret = dtls1_process_handshake_record(ssl);
    409     if (ret <= 0) {
    410       return ret;
    411     }
    412   }
    413 
    414   hm_fragment *frag = ssl->d1->incoming_messages[ssl->d1->handshake_read_seq %
    415                                                  SSL_MAX_HANDSHAKE_FLIGHT];
    416   assert(frag != NULL);
    417   assert(frag->reassembly == NULL);
    418   assert(ssl->d1->handshake_read_seq == frag->seq);
    419 
    420   /* TODO(davidben): This function has a lot of implicit outputs. Simplify the
    421    * |ssl_get_message| API. */
    422   ssl->s3->tmp.message_type = frag->type;
    423   ssl->init_msg = frag->data + DTLS1_HM_HEADER_LENGTH;
    424   ssl->init_num = frag->msg_len;
    425 
    426   ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, frag->data,
    427                       ssl->init_num + DTLS1_HM_HEADER_LENGTH);
    428   return 1;
    429 }
    430 
    431 void dtls1_get_current_message(const SSL *ssl, CBS *out) {
    432   assert(dtls1_is_current_message_complete(ssl));
    433 
    434   hm_fragment *frag = ssl->d1->incoming_messages[ssl->d1->handshake_read_seq %
    435                                                  SSL_MAX_HANDSHAKE_FLIGHT];
    436   CBS_init(out, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len);
    437 }
    438 
    439 void dtls1_release_current_message(SSL *ssl, int free_buffer) {
    440   if (ssl->init_msg == NULL) {
    441     return;
    442   }
    443 
    444   assert(dtls1_is_current_message_complete(ssl));
    445   size_t index = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
    446   dtls1_hm_fragment_free(ssl->d1->incoming_messages[index]);
    447   ssl->d1->incoming_messages[index] = NULL;
    448   ssl->d1->handshake_read_seq++;
    449 
    450   ssl->init_msg = NULL;
    451   ssl->init_num = 0;
    452 }
    453 
    454 void dtls_clear_incoming_messages(SSL *ssl) {
    455   for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) {
    456     dtls1_hm_fragment_free(ssl->d1->incoming_messages[i]);
    457     ssl->d1->incoming_messages[i] = NULL;
    458   }
    459 }
    460 
    461 int dtls_has_incoming_messages(const SSL *ssl) {
    462   size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
    463   for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) {
    464     /* Skip the current message. */
    465     if (ssl->init_msg != NULL && i == current) {
    466       assert(dtls1_is_current_message_complete(ssl));
    467       continue;
    468     }
    469     if (ssl->d1->incoming_messages[i] != NULL) {
    470       return 1;
    471     }
    472   }
    473   return 0;
    474 }
    475 
    476 int dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
    477                          CBS *out_body) {
    478   OPENSSL_memset(out_hdr, 0x00, sizeof(struct hm_header_st));
    479 
    480   if (!CBS_get_u8(cbs, &out_hdr->type) ||
    481       !CBS_get_u24(cbs, &out_hdr->msg_len) ||
    482       !CBS_get_u16(cbs, &out_hdr->seq) ||
    483       !CBS_get_u24(cbs, &out_hdr->frag_off) ||
    484       !CBS_get_u24(cbs, &out_hdr->frag_len) ||
    485       !CBS_get_bytes(cbs, out_body, out_hdr->frag_len)) {
    486     return 0;
    487   }
    488 
    489   return 1;
    490 }
    491 
    492 
    493 /* Sending handshake messages. */
    494 
    495 void dtls_clear_outgoing_messages(SSL *ssl) {
    496   for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) {
    497     OPENSSL_free(ssl->d1->outgoing_messages[i].data);
    498     ssl->d1->outgoing_messages[i].data = NULL;
    499   }
    500   ssl->d1->outgoing_messages_len = 0;
    501   ssl->d1->outgoing_written = 0;
    502   ssl->d1->outgoing_offset = 0;
    503 }
    504 
    505 int dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
    506   /* Pick a modest size hint to save most of the |realloc| calls. */
    507   if (!CBB_init(cbb, 64) ||
    508       !CBB_add_u8(cbb, type) ||
    509       !CBB_add_u24(cbb, 0 /* length (filled in later) */) ||
    510       !CBB_add_u16(cbb, ssl->d1->handshake_write_seq) ||
    511       !CBB_add_u24(cbb, 0 /* offset */) ||
    512       !CBB_add_u24_length_prefixed(cbb, body)) {
    513     return 0;
    514   }
    515 
    516   return 1;
    517 }
    518 
    519 int dtls1_finish_message(SSL *ssl, CBB *cbb, uint8_t **out_msg,
    520                          size_t *out_len) {
    521   *out_msg = NULL;
    522   if (!CBB_finish(cbb, out_msg, out_len) ||
    523       *out_len < DTLS1_HM_HEADER_LENGTH) {
    524     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    525     OPENSSL_free(*out_msg);
    526     return 0;
    527   }
    528 
    529   /* Fix up the header. Copy the fragment length into the total message
    530    * length. */
    531   OPENSSL_memcpy(*out_msg + 1, *out_msg + DTLS1_HM_HEADER_LENGTH - 3, 3);
    532   return 1;
    533 }
    534 
    535 /* add_outgoing adds a new handshake message or ChangeCipherSpec to the current
    536  * outgoing flight. It returns one on success and zero on error. In both cases,
    537  * it takes ownership of |data| and releases it with |OPENSSL_free| when
    538  * done. */
    539 static int add_outgoing(SSL *ssl, int is_ccs, uint8_t *data, size_t len) {
    540   OPENSSL_COMPILE_ASSERT(SSL_MAX_HANDSHAKE_FLIGHT <
    541                              (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)),
    542                          outgoing_messages_len_is_too_small);
    543   if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT) {
    544     assert(0);
    545     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    546     OPENSSL_free(data);
    547     return 0;
    548   }
    549 
    550   if (!is_ccs) {
    551     /* TODO(svaldez): Move this up a layer to fix abstraction for SSL_TRANSCRIPT
    552      * on hs. */
    553     if (ssl->s3->hs != NULL &&
    554         !SSL_TRANSCRIPT_update(&ssl->s3->hs->transcript, data, len)) {
    555       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    556       OPENSSL_free(data);
    557       return 0;
    558     }
    559     ssl->d1->handshake_write_seq++;
    560   }
    561 
    562   DTLS_OUTGOING_MESSAGE *msg =
    563       &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len];
    564   msg->data = data;
    565   msg->len = len;
    566   msg->epoch = ssl->d1->w_epoch;
    567   msg->is_ccs = is_ccs;
    568 
    569   ssl->d1->outgoing_messages_len++;
    570   return 1;
    571 }
    572 
    573 int dtls1_add_message(SSL *ssl, uint8_t *data, size_t len) {
    574   return add_outgoing(ssl, 0 /* handshake */, data, len);
    575 }
    576 
    577 int dtls1_add_change_cipher_spec(SSL *ssl) {
    578   return add_outgoing(ssl, 1 /* ChangeCipherSpec */, NULL, 0);
    579 }
    580 
    581 int dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc) {
    582   /* The |add_alert| path is only used for warning alerts for now, which DTLS
    583    * never sends. This will be implemented later once closure alerts are
    584    * converted. */
    585   assert(0);
    586   OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    587   return 0;
    588 }
    589 
    590 /* dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above
    591  * the minimum. */
    592 static void dtls1_update_mtu(SSL *ssl) {
    593   /* TODO(davidben): No consumer implements |BIO_CTRL_DGRAM_SET_MTU| and the
    594    * only |BIO_CTRL_DGRAM_QUERY_MTU| implementation could use
    595    * |SSL_set_mtu|. Does this need to be so complex?  */
    596   if (ssl->d1->mtu < dtls1_min_mtu() &&
    597       !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
    598     long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
    599     if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
    600       ssl->d1->mtu = (unsigned)mtu;
    601     } else {
    602       ssl->d1->mtu = kDefaultMTU;
    603       BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL);
    604     }
    605   }
    606 
    607   /* The MTU should be above the minimum now. */
    608   assert(ssl->d1->mtu >= dtls1_min_mtu());
    609 }
    610 
    611 enum seal_result_t {
    612   seal_error,
    613   seal_no_progress,
    614   seal_partial,
    615   seal_success,
    616 };
    617 
    618 /* seal_next_message seals |msg|, which must be the next message, to |out|. If
    619  * progress was made, it returns |seal_partial| or |seal_success| and sets
    620  * |*out_len| to the number of bytes written. */
    621 static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out,
    622                                             size_t *out_len, size_t max_out,
    623                                             const DTLS_OUTGOING_MESSAGE *msg) {
    624   assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len);
    625   assert(msg == &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]);
    626 
    627   /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
    628    * (negotiated cipher) exist. */
    629   assert(ssl->d1->w_epoch == 0 || ssl->d1->w_epoch == 1);
    630   assert(msg->epoch <= ssl->d1->w_epoch);
    631   enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch;
    632   if (ssl->d1->w_epoch == 1 && msg->epoch == 0) {
    633     use_epoch = dtls1_use_previous_epoch;
    634   }
    635   size_t overhead = dtls_max_seal_overhead(ssl, use_epoch);
    636   size_t prefix = dtls_seal_prefix_len(ssl, use_epoch);
    637 
    638   if (msg->is_ccs) {
    639     /* Check there is room for the ChangeCipherSpec. */
    640     static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
    641     if (max_out < sizeof(kChangeCipherSpec) + overhead) {
    642       return seal_no_progress;
    643     }
    644 
    645     if (!dtls_seal_record(ssl, out, out_len, max_out,
    646                           SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
    647                           sizeof(kChangeCipherSpec), use_epoch)) {
    648       return seal_error;
    649     }
    650 
    651     ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
    652                         kChangeCipherSpec, sizeof(kChangeCipherSpec));
    653     return seal_success;
    654   }
    655 
    656   /* DTLS messages are serialized as a single fragment in |msg|. */
    657   CBS cbs, body;
    658   struct hm_header_st hdr;
    659   CBS_init(&cbs, msg->data, msg->len);
    660   if (!dtls1_parse_fragment(&cbs, &hdr, &body) ||
    661       hdr.frag_off != 0 ||
    662       hdr.frag_len != CBS_len(&body) ||
    663       hdr.msg_len != CBS_len(&body) ||
    664       !CBS_skip(&body, ssl->d1->outgoing_offset) ||
    665       CBS_len(&cbs) != 0) {
    666     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    667     return seal_error;
    668   }
    669 
    670   /* Determine how much progress can be made. */
    671   if (max_out < DTLS1_HM_HEADER_LENGTH + 1 + overhead || max_out < prefix) {
    672     return seal_no_progress;
    673   }
    674   size_t todo = CBS_len(&body);
    675   if (todo > max_out - DTLS1_HM_HEADER_LENGTH - overhead) {
    676     todo = max_out - DTLS1_HM_HEADER_LENGTH - overhead;
    677   }
    678 
    679   /* Assemble a fragment, to be sealed in-place. */
    680   CBB cbb;
    681   uint8_t *frag = out + prefix;
    682   size_t max_frag = max_out - prefix, frag_len;
    683   if (!CBB_init_fixed(&cbb, frag, max_frag) ||
    684       !CBB_add_u8(&cbb, hdr.type) ||
    685       !CBB_add_u24(&cbb, hdr.msg_len) ||
    686       !CBB_add_u16(&cbb, hdr.seq) ||
    687       !CBB_add_u24(&cbb, ssl->d1->outgoing_offset) ||
    688       !CBB_add_u24(&cbb, todo) ||
    689       !CBB_add_bytes(&cbb, CBS_data(&body), todo) ||
    690       !CBB_finish(&cbb, NULL, &frag_len)) {
    691     CBB_cleanup(&cbb);
    692     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    693     return seal_error;
    694   }
    695 
    696   ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, frag, frag_len);
    697 
    698   if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE,
    699                         out + prefix, frag_len, use_epoch)) {
    700     return seal_error;
    701   }
    702 
    703   if (todo == CBS_len(&body)) {
    704     /* The next message is complete. */
    705     ssl->d1->outgoing_offset = 0;
    706     return seal_success;
    707   }
    708 
    709   ssl->d1->outgoing_offset += todo;
    710   return seal_partial;
    711 }
    712 
    713 /* seal_next_packet writes as much of the next flight as possible to |out| and
    714  * advances |ssl->d1->outgoing_written| and |ssl->d1->outgoing_offset| as
    715  * appropriate. */
    716 static int seal_next_packet(SSL *ssl, uint8_t *out, size_t *out_len,
    717                             size_t max_out) {
    718   int made_progress = 0;
    719   size_t total = 0;
    720   assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len);
    721   for (; ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len;
    722        ssl->d1->outgoing_written++) {
    723     const DTLS_OUTGOING_MESSAGE *msg =
    724         &ssl->d1->outgoing_messages[ssl->d1->outgoing_written];
    725     size_t len;
    726     enum seal_result_t ret = seal_next_message(ssl, out, &len, max_out, msg);
    727     switch (ret) {
    728       case seal_error:
    729         return 0;
    730 
    731       case seal_no_progress:
    732         goto packet_full;
    733 
    734       case seal_partial:
    735       case seal_success:
    736         out += len;
    737         max_out -= len;
    738         total += len;
    739         made_progress = 1;
    740 
    741         if (ret == seal_partial) {
    742           goto packet_full;
    743         }
    744         break;
    745     }
    746   }
    747 
    748 packet_full:
    749   /* The MTU was too small to make any progress. */
    750   if (!made_progress) {
    751     OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
    752     return 0;
    753   }
    754 
    755   *out_len = total;
    756   return 1;
    757 }
    758 
    759 int dtls1_flush_flight(SSL *ssl) {
    760   dtls1_update_mtu(ssl);
    761 
    762   int ret = -1;
    763   uint8_t *packet = OPENSSL_malloc(ssl->d1->mtu);
    764   if (packet == NULL) {
    765     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    766     goto err;
    767   }
    768 
    769   while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len) {
    770     uint8_t old_written = ssl->d1->outgoing_written;
    771     uint32_t old_offset = ssl->d1->outgoing_offset;
    772 
    773     size_t packet_len;
    774     if (!seal_next_packet(ssl, packet, &packet_len, ssl->d1->mtu)) {
    775       goto err;
    776     }
    777 
    778     int bio_ret = BIO_write(ssl->wbio, packet, packet_len);
    779     if (bio_ret <= 0) {
    780       /* Retry this packet the next time around. */
    781       ssl->d1->outgoing_written = old_written;
    782       ssl->d1->outgoing_offset = old_offset;
    783       ssl->rwstate = SSL_WRITING;
    784       ret = bio_ret;
    785       goto err;
    786     }
    787   }
    788 
    789   if (BIO_flush(ssl->wbio) <= 0) {
    790     ssl->rwstate = SSL_WRITING;
    791     goto err;
    792   }
    793 
    794   ret = 1;
    795 
    796 err:
    797   OPENSSL_free(packet);
    798   return ret;
    799 }
    800 
    801 int dtls1_retransmit_outgoing_messages(SSL *ssl) {
    802   /* Rewind to the start of the flight and write it again.
    803    *
    804    * TODO(davidben): This does not allow retransmits to be resumed on
    805    * non-blocking write. */
    806   ssl->d1->outgoing_written = 0;
    807   ssl->d1->outgoing_offset = 0;
    808 
    809   return dtls1_flush_flight(ssl);
    810 }
    811 
    812 unsigned int dtls1_min_mtu(void) {
    813   return kMinMTU;
    814 }
    815