Fix DTLS buffered message DoS attack
[openssl.git] / ssl / statem / statem_dtls.c
index 34fd8b20085abd8f1985a809613dc844c92f5490..de2de097967233b659b988b9788aae22b8703141 100644 (file)
-/* ssl/statem/statem_dtls.c */
 /*
- * 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 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
  *
- */
-/* 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.]
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
  */
 
 #include <limits.h>
 #include "../ssl_locl.h"
 #include "statem_locl.h"
 #include <openssl/buffer.h>
-#include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
@@ -204,8 +97,7 @@ void dtls1_hm_fragment_free(hm_fragment *frag)
     if (frag->msg_header.is_ccs) {
         EVP_CIPHER_CTX_free(frag->msg_header.
                             saved_retransmit_state.enc_write_ctx);
-        EVP_MD_CTX_destroy(frag->msg_header.
-                           saved_retransmit_state.write_hash);
+        EVP_MD_CTX_free(frag->msg_header.saved_retransmit_state.write_hash);
     }
     OPENSSL_free(frag->fragment);
     OPENSSL_free(frag->reassembly);
@@ -226,18 +118,18 @@ int dtls1_do_write(SSL *s, int type)
     if (!dtls1_query_mtu(s))
         return -1;
 
-    OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something
-                                                     * reasonable now */
+    if (s->d1->mtu < dtls1_min_mtu(s))
+        /* should have something reasonable now */
+        return -1;
 
     if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
         OPENSSL_assert(s->init_num ==
-                       (int)s->d1->w_msg_hdr.msg_len +
-                       DTLS1_HM_HEADER_LENGTH);
+                       (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
 
     if (s->write_hash) {
         if (s->enc_write_ctx
-            && ((EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_GCM_MODE) ||
-                (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CCM_MODE)))
+            && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
+                EVP_CIPH_FLAG_AEAD_CIPHER) != 0)
             mac_size = 0;
         else
             mac_size = EVP_MD_CTX_size(s->write_hash);
@@ -246,14 +138,50 @@ int dtls1_do_write(SSL *s, int type)
 
     if (s->enc_write_ctx &&
         (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE))
-        blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
+        blocksize = 2 * EVP_CIPHER_CTX_block_size(s->enc_write_ctx);
     else
         blocksize = 0;
 
     frag_off = 0;
+    s->rwstate = SSL_NOTHING;
+
     /* s->init_num shouldn't ever be < 0...but just in case */
     while (s->init_num > 0) {
-        used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH
+        if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) {
+            /* We must be writing a fragment other than the first one */
+
+            if (frag_off > 0) {
+                /* This is the first attempt at writing out this fragment */
+
+                if (s->init_off <= DTLS1_HM_HEADER_LENGTH) {
+                    /*
+                     * Each fragment that was already sent must at least have
+                     * contained the message header plus one other byte.
+                     * Therefore |init_off| must have progressed by at least
+                     * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went
+                     * wrong.
+                     */
+                    return -1;
+                }
+
+                /*
+                 * Adjust |init_off| and |init_num| to allow room for a new
+                 * message header for this fragment.
+                 */
+                s->init_off -= DTLS1_HM_HEADER_LENGTH;
+                s->init_num += DTLS1_HM_HEADER_LENGTH;
+            } else {
+                /*
+                 * We must have been called again after a retry so use the
+                 * fragment offset from our last attempt. We do not need
+                 * to adjust |init_off| and |init_num| as above, because
+                 * that should already have been done before the retry.
+                 */
+                frag_off = s->d1->w_msg_hdr.frag_off;
+            }
+        }
+
+        used_len = BIO_wpending(s->wbio) + DTLS1_RT_HEADER_LENGTH
             + mac_size + blocksize;
         if (s->d1->mtu > used_len)
             curr_mtu = s->d1->mtu - used_len;
@@ -264,9 +192,11 @@ int dtls1_do_write(SSL *s, int type)
             /*
              * grr.. we could get an error if MTU picked was wrong
              */
-            ret = BIO_flush(SSL_get_wbio(s));
-            if (ret <= 0)
+            ret = BIO_flush(s->wbio);
+            if (ret <= 0) {
+                s->rwstate = SSL_WRITING;
                 return ret;
+            }
             used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
             if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) {
                 curr_mtu = s->d1->mtu - used_len;
@@ -292,25 +222,6 @@ int dtls1_do_write(SSL *s, int type)
          * XDTLS: this function is too long.  split out the CCS part
          */
         if (type == SSL3_RT_HANDSHAKE) {
-            if (s->init_off != 0) {
-                OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
-                s->init_off -= DTLS1_HM_HEADER_LENGTH;
-                s->init_num += DTLS1_HM_HEADER_LENGTH;
-
-                /*
-                 * We just checked that s->init_num > 0 so this cast should
-                 * be safe
-                 */
-                if (((unsigned int)s->init_num) > curr_mtu)
-                    len = curr_mtu;
-                else
-                    len = s->init_num;
-            }
-
-            /* Shouldn't ever happen */
-            if (len > INT_MAX)
-                len = INT_MAX;
-
             if (len < DTLS1_HM_HEADER_LENGTH) {
                 /*
                  * len is so small that we really can't do anything sensible
@@ -318,16 +229,14 @@ int dtls1_do_write(SSL *s, int type)
                  */
                 return -1;
             }
-            dtls1_fix_message_header(s, frag_off,
-                                     len - DTLS1_HM_HEADER_LENGTH);
+            dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);
 
             dtls1_write_message_header(s,
                                        (unsigned char *)&s->init_buf->
                                        data[s->init_off]);
         }
 
-        ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off],
-                                len);
+        ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len);
         if (ret < 0) {
             /*
              * might need to update MTU here, but we don't know which
@@ -382,7 +291,8 @@ int dtls1_do_write(SSL *s, int type)
                     xlen = ret - DTLS1_HM_HEADER_LENGTH;
                 }
 
-                ssl3_finish_mac(s, p, xlen);
+                if (!ssl3_finish_mac(s, p, xlen))
+                    return -1;
             }
 
             if (ret == s->init_num) {
@@ -398,7 +308,16 @@ int dtls1_do_write(SSL *s, int type)
             }
             s->init_off += ret;
             s->init_num -= ret;
-            frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
+            ret -= DTLS1_HM_HEADER_LENGTH;
+            frag_off += ret;
+
+            /*
+             * We save the fragment offset for the next fragment so we have it
+             * available in case of an IO retry. We don't know the length of the
+             * next fragment yet so just set that to 0 for now. It will be
+             * updated again later.
+             */
+            dtls1_fix_message_header(s, frag_off, 0);
         }
     }
     return (0);
@@ -417,8 +336,7 @@ int dtls_get_message(SSL *s, int *mt, unsigned long *len)
 
  again:
     ok = dtls_get_reassembled_message(s, &tmplen);
-    if (tmplen == DTLS1_HM_BAD_FRAGMENT
-        || tmplen == DTLS1_HM_FRAGMENT_RETRY) {
+    if (tmplen == DTLS1_HM_BAD_FRAGMENT || tmplen == DTLS1_HM_FRAGMENT_RETRY) {
         /* bad fragment received */
         goto again;
     } else if (tmplen <= 0 && !ok) {
@@ -454,7 +372,8 @@ int dtls_get_message(SSL *s, int *mt, unsigned long *len)
         msg_len += DTLS1_HM_HEADER_LENGTH;
     }
 
-    ssl3_finish_mac(s, p, msg_len);
+    if (!ssl3_finish_mac(s, p, msg_len))
+        return 0;
     if (s->msg_callback)
         s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                         p, msg_len, s, s->msg_callback_arg);
@@ -463,7 +382,6 @@ int dtls_get_message(SSL *s, int *mt, unsigned long *len)
 
     s->d1->handshake_read_seq++;
 
-
     s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
     *len = s->init_num;
 
@@ -489,8 +407,7 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr)
          * 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)) {
+        if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
             SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB);
             return SSL_AD_INTERNAL_ERROR;
         }
@@ -525,11 +442,23 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok)
     int al;
 
     *ok = 0;
-    item = pqueue_peek(s->d1->buffered_messages);
-    if (item == NULL)
-        return 0;
 
-    frag = (hm_fragment *)item->data;
+    do {
+        item = pqueue_peek(s->d1->buffered_messages);
+        if (item == NULL)
+            return 0;
+
+        frag = (hm_fragment *)item->data;
+
+        if (frag->msg_header.seq < s->d1->handshake_read_seq) {
+            /* This is a stale message that has been buffered so clear it */
+            pqueue_pop(s->d1->buffered_messages);
+            dtls1_hm_fragment_free(frag);
+            pitem_free(item);
+            item = NULL;
+            frag = NULL;
+        }
+    } while (item == NULL);
 
     /* Don't return if reassembly still in progress */
     if (frag->reassembly != NULL)
@@ -716,8 +645,7 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr,
      */
     if (msg_hdr->seq <= s->d1->handshake_read_seq ||
         msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
-        (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED))
-    {
+        (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) {
         unsigned char devnull[256];
 
         while (frag_len) {
@@ -805,7 +733,7 @@ static int dtls_get_reassembled_message(SSL *s, long *len)
         *len = i;
         return 0;
     }
-    if(recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
+    if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
         if (wire[0] != SSL3_MT_CCS) {
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE,
@@ -877,7 +805,7 @@ static int dtls_get_reassembled_message(SSL *s, long *len)
 
             s->init_num = 0;
             goto redo;
-        } else {                /* Incorrectly formated Hello request */
+        } else {                /* Incorrectly formatted Hello request */
 
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE,
@@ -973,7 +901,7 @@ int dtls_construct_change_cipher_spec(SSL *s)
 }
 
 #ifndef OPENSSL_NO_SCTP
-enum WORK_STATE dtls_wait_for_dry(SSL *s)
+WORK_STATE dtls_wait_for_dry(SSL *s)
 {
     int ret;
 
@@ -996,7 +924,7 @@ enum WORK_STATE dtls_wait_for_dry(SSL *s)
 int dtls1_read_failed(SSL *s, int code)
 {
     if (code > 0) {
-        fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
+        SSLerr(SSL_F_DTLS1_READ_FAILED, ERR_R_INTERNAL_ERROR);
         return 1;
     }
 
@@ -1039,7 +967,7 @@ int dtls1_get_queue_priority(unsigned short seq, int is_ccs)
 
 int dtls1_retransmit_buffered_messages(SSL *s)
 {
-    pqueue sent = s->d1->sent_messages;
+    pqueue *sent = s->d1->sent_messages;
     piterator iter;
     pitem *item;
     hm_fragment *frag;
@@ -1052,11 +980,8 @@ int dtls1_retransmit_buffered_messages(SSL *s)
         if (dtls1_retransmit_message(s, (unsigned short)
                                      dtls1_get_queue_priority
                                      (frag->msg_header.seq,
-                                      frag->msg_header.is_ccs), 0,
-                                     &found) <= 0 && found) {
-            fprintf(stderr, "dtls1_retransmit_message() failed\n");
+                                      frag->msg_header.is_ccs), &found) <= 0)
             return -1;
-        }
     }
 
     return 1;
@@ -1075,7 +1000,7 @@ int dtls1_buffer_message(SSL *s, int is_ccs)
     OPENSSL_assert(s->init_off == 0);
 
     frag = dtls1_hm_fragment_new(s->init_num, 0);
-    if (!frag)
+    if (frag == NULL)
         return 0;
 
     memcpy(frag->fragment, s->init_buf->data, s->init_num);
@@ -1083,7 +1008,8 @@ int dtls1_buffer_message(SSL *s, int is_ccs)
     if (is_ccs) {
         /* For DTLS1_BAD_VER the header length is non-standard */
         OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
-                       ((s->version==DTLS1_BAD_VER)?3:DTLS1_CCS_HEADER_LENGTH)
+                       ((s->version ==
+                         DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH)
                        == (unsigned int)s->init_num);
     } else {
         OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
@@ -1125,9 +1051,7 @@ int dtls1_buffer_message(SSL *s, int is_ccs)
     return 1;
 }
 
-int
-dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
-                         int *found)
+int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found)
 {
     int ret;
     /* XDTLS: for now assuming that read/writes are blocking */
@@ -1149,7 +1073,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
 
     item = pqueue_find(s->d1->sent_messages, seq64be);
     if (item == NULL) {
-        fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
+        SSLerr(SSL_F_DTLS1_RETRANSMIT_MESSAGE, ERR_R_INTERNAL_ERROR);
         *found = 0;
         return 0;
     }
@@ -1186,7 +1110,8 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
     s->compress = frag->msg_header.saved_retransmit_state.compress;
     s->session = frag->msg_header.saved_retransmit_state.session;
     DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer,
-        frag->msg_header.saved_retransmit_state.epoch);
+                                        frag->msg_header.
+                                        saved_retransmit_state.epoch);
 
     ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
                          SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
@@ -1200,26 +1125,13 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
 
     s->d1->retransmitting = 0;
 
-    (void)BIO_flush(SSL_get_wbio(s));
+    (void)BIO_flush(s->wbio);
     return ret;
 }
 
-/* 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);
-    }
-}
-
-void dtls1_set_message_header(SSL *s, unsigned char *p,
-                                        unsigned char mt, unsigned long len,
-                                        unsigned long frag_off,
-                                        unsigned long frag_len)
+void dtls1_set_message_header(SSL *s,
+                              unsigned char mt, unsigned long len,
+                              unsigned long frag_off, unsigned long frag_len)
 {
     if (frag_off == 0) {
         s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
@@ -1246,8 +1158,7 @@ dtls1_set_message_header_int(SSL *s, unsigned char mt,
 }
 
 static void
-dtls1_fix_message_header(SSL *s, unsigned long frag_off,
-                         unsigned long frag_len)
+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;
 
@@ -1269,8 +1180,7 @@ static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p)
     return p;
 }
 
-void
-dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
+void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
 {
     memset(msg_hdr, 0, sizeof(*msg_hdr));
     msg_hdr->type = *(data++);
@@ -1280,5 +1190,3 @@ dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
     n2l3(data, msg_hdr->frag_off);
     n2l3(data, msg_hdr->frag_len);
 }
-
-