]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Restructure the write code
authorMatt Caswell <matt@openssl.org>
Mon, 12 Sep 2022 14:50:26 +0000 (15:50 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 23 Sep 2022 13:54:49 +0000 (14:54 +0100)
Move the multiblock code into a separate file and introduce the usage of
record_functions_st for some write functions.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19198)

ssl/record/methods/build.info
ssl/record/methods/ktls_meth.c
ssl/record/methods/recmethod_local.h
ssl/record/methods/ssl3_meth.c
ssl/record/methods/tls13_meth.c
ssl/record/methods/tls1_meth.c
ssl/record/methods/tls_common.c
ssl/record/methods/tls_multib.c [new file with mode: 0644]
ssl/record/methods/tlsany_meth.c

index 064bcaf177a003be9134d159bac108dfa815408e..f31acd10b923a2e5b366819a8cc6a963a35d1100 100644 (file)
@@ -5,7 +5,7 @@ ENDIF
 
 SOURCE[../../../libssl]=\
         tls_common.c ssl3_meth.c tls1_meth.c tls13_meth.c tlsany_meth.c \
-        dtls_meth.c $KTLSSRC
+        dtls_meth.c tls_multib.c $KTLSSRC
 
 # For shared builds we need to include the sources needed in providers
 # (ssl3_cbc.c) in libssl as well.
index 7f6c9602f0c28ff5982a25be057165fc32425ca2..95f34d176f98580de593e26e96b21ab02f4e81de 100644 (file)
@@ -481,13 +481,15 @@ static int ktls_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
 
 static struct record_functions_st ossl_ktls_funcs = {
     ktls_set_crypto_state,
-    ktls_read_n,
-    tls_get_more_records,
     ktls_cipher,
     NULL,
     tls_default_set_protocol_version,
+    ktls_read_n,
+    tls_get_more_records,
     ktls_validate_record_header,
-    ktls_post_process_record
+    ktls_post_process_record,
+    tls_get_max_records_default,
+    tls_write_records_default
 };
 
 static int
index 334a093362a5b59d406b3b70d782cd159f7708a3..ee5d03a77d5042ac093732e2aa81f90c37af8fc0 100644 (file)
@@ -38,11 +38,6 @@ struct record_functions_st
                             const EVP_MD *md,
                             const SSL_COMP *comp);
 
-    int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
-                  int clearold, size_t *readbytes);
-
-    int (*get_more_records)(OSSL_RECORD_LAYER *rl);
-
     /*
      * Returns:
      *    0: if the record is publicly invalid, or an internal error, or AEAD
@@ -58,11 +53,27 @@ struct record_functions_st
     /* Return 1 for success or 0 for error */
     int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version);
 
+    /* Read related functions */
+
+    int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
+                  int clearold, size_t *readbytes);
+
+    int (*get_more_records)(OSSL_RECORD_LAYER *rl);
+
     /* Return 1 for success or 0 for error */
     int (*validate_record_header)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
 
     /* Return 1 for success or 0 for error */
     int (*post_process_record)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
+
+    /* Write related functions */
+
+    size_t (*get_max_records)(OSSL_RECORD_LAYER *rl, int type, size_t len,
+                              size_t maxfrag, size_t *preffrag);
+
+    /* Return 1 for success or 0 for error */
+    int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
+                         size_t numtempl);
 };
 
 struct ossl_record_layer_st
@@ -314,3 +325,18 @@ void tls_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr,
                    const char **longstr);
 int tls_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options);
 int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl);
+int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
+                           size_t firstlen, size_t nextlen);
+
+int tls_write_records_multiblock(OSSL_RECORD_LAYER *rl,
+                                 OSSL_RECORD_TEMPLATE *templates,
+                                 size_t numtempl);
+
+size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, int type, size_t len,
+                                   size_t maxfrag, size_t *preffrag);
+size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, int type,
+                                      size_t len, size_t maxfrag,
+                                      size_t *preffrag);
+int tls_write_records_default(OSSL_RECORD_LAYER *rl,
+                              OSSL_RECORD_TEMPLATE *templates,
+                              size_t numtempl);
index f1fd1f42031e66bbe1ac999329ff3a79075c6407..80551356cbdab03eb42ff014ca08e645c460dc90 100644 (file)
@@ -295,11 +295,13 @@ static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
 
 struct record_functions_st ssl_3_0_funcs = {
     ssl3_set_crypto_state,
-    tls_default_read_n,
-    tls_get_more_records,
     ssl3_cipher,
     ssl3_mac,
     tls_default_set_protocol_version,
+    tls_default_read_n,
+    tls_get_more_records,
     tls_default_validate_record_header,
-    tls_default_post_process_record
+    tls_default_post_process_record,
+    tls_get_max_records_default,
+    tls_write_records_default
 };
index 2a24067d145f4fdfa5443ec905cbe1bd0a7f31ea..5195fbd96345970a766c0d26d92e2b58de33f787 100644 (file)
@@ -240,11 +240,13 @@ static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
 
 struct record_functions_st tls_1_3_funcs = {
     tls13_set_crypto_state,
-    tls_default_read_n,
-    tls_get_more_records,
     tls13_cipher,
     NULL,
     tls_default_set_protocol_version,
+    tls_default_read_n,
+    tls_get_more_records,
     tls13_validate_record_header,
-    tls13_post_process_record
+    tls13_post_process_record,
+    tls_get_max_records_default,
+    tls_write_records_default
 };
index db3cad4ee355dc8ea21a8609e5c3fd4b4d675f67..a12a0cf843e968941e228716bc84055b88ece2ed 100644 (file)
@@ -522,22 +522,26 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
 /* TLSv1.0, TLSv1.1 and TLSv1.2 all use the same funcs */
 struct record_functions_st tls_1_funcs = {
     tls1_set_crypto_state,
-    tls_default_read_n,
-    tls_get_more_records,
     tls1_cipher,
     tls1_mac,
     tls_default_set_protocol_version,
+    tls_default_read_n,
+    tls_get_more_records,
     tls_default_validate_record_header,
-    tls_default_post_process_record
+    tls_default_post_process_record,
+    tls_get_max_records_multiblock,
+    tls_write_records_multiblock /* Defined in tls_multib.c */
 };
 
 struct record_functions_st dtls_1_funcs = {
     tls1_set_crypto_state,
-    tls_default_read_n,
-    dtls_get_more_records,
     tls1_cipher,
     tls1_mac,
     tls_default_set_protocol_version,
+    tls_default_read_n,
+    dtls_get_more_records,
+    NULL,
+    NULL,
     NULL,
     NULL
 };
index 95083532f4a90aef1a8da6130dc0b7adb3005008..a55a5a815261ae510ba65049b480dd7085c36ade 100644 (file)
 #include "../record_local.h"
 #include "recmethod_local.h"
 
-#if     defined(OPENSSL_SMALL_FOOTPRINT) || \
-        !(      defined(AES_ASM) &&     ( \
-                defined(__x86_64)       || defined(__x86_64__)  || \
-                defined(_M_AMD64)       || defined(_M_X64)      ) \
-        )
-# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
-# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
-#endif
-
 static void tls_int_free(OSSL_RECORD_LAYER *rl);
 
 void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
@@ -145,8 +136,8 @@ static void tls_release_write_buffer_int(OSSL_RECORD_LAYER *rl, size_t start)
 # endif /* OPENSSL_NO_COMP */
 #endif
 
-static int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
-                                  size_t firstlen, size_t nextlen)
+int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
+                           size_t firstlen, size_t nextlen)
 {
     unsigned char *p;
     size_t align = 0, headerlen;
@@ -1453,44 +1444,12 @@ size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl)
     return 0;
 }
 
-static int tls_is_multiblock_capable(OSSL_RECORD_LAYER *rl, int type,
-                                     size_t len, size_t fraglen)
-{
-#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
-    /* TODO(RECLAYER): REMOVE ME */
-    SSL_CONNECTION *s = rl->cbarg;
-
-    if (type == SSL3_RT_APPLICATION_DATA
-            && len >= 4 * fraglen
-            && s->compress == NULL
-            && rl->msg_callback == NULL
-            && !rl->use_etm
-            && RLAYER_USE_EXPLICIT_IV(rl)
-            && !BIO_get_ktls_send(s->wbio)
-            && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx))
-                & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) != 0)
-        return 1;
-#endif
-    return 0;
-}
-
-size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t len,
-                           size_t maxfrag, size_t *preffrag)
+size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, int type, size_t len,
+                                   size_t maxfrag, size_t *preffrag)
 {
     /* TODO(RECLAYER): Remove me */
     SSL_CONNECTION *s = rl->cbarg;
 
-    if (tls_is_multiblock_capable(rl, type, len, *preffrag)) {
-        /* minimize address aliasing conflicts */
-        if ((*preffrag & 0xfff) == 0)
-            *preffrag -= 512;
-
-        if (len >= 8 * (*preffrag))
-            return 8;
-
-        return 4;
-    }
-
     /*
      * TODO(RECLYAER): There is no test for the pipelining code. We should add
      *                 one.
@@ -1516,114 +1475,15 @@ size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t len,
     return 1;
 }
 
-static int tls_write_records_multiblock(OSSL_RECORD_LAYER *rl,
-                                        OSSL_RECORD_TEMPLATE *templates,
-                                        size_t numtempl)
+size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t len,
+                           size_t maxfrag, size_t *preffrag)
 {
-#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
-    size_t i;
-    size_t totlen;
-    SSL3_BUFFER *wb;
-    /* TODO(RECLAYER): Remove me */
-    SSL_CONNECTION *s = rl->cbarg;
-
-    if (numtempl != 4 && numtempl != 8)
-        return 0;
-
-    /*
-     * Check templates have contiguous buffers and are all the same type and
-     * length
-     */
-    for (i = 1; i < numtempl; i++) {
-        if (templates[i - 1].type != templates[i].type
-                || templates[i - 1].buflen != templates[i].buflen
-                || templates[i - 1].buf + templates[i - 1].buflen
-                   != templates[i].buf)
-            return 0;
-    }
-
-    totlen = templates[0].buflen * numtempl;
-    if (!tls_is_multiblock_capable(rl, templates[0].type, totlen,
-                                   templates[0].buflen))
-        return 0;
-
-    /*
-     * If we get this far, then multiblock is suitable
-     * Depending on platform multi-block can deliver several *times*
-     * better performance. Downside is that it has to allocate
-     * jumbo buffer to accommodate up to 8 records, but the
-     * compromise is considered worthy.
-     */
-
-    unsigned char aad[13];
-    EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
-    size_t packlen;
-    int packleni;
-
-    /*
-     * Allocate jumbo buffer. This will get freed next time we do a non
-     * multiblock write in the call to tls_setup_write_buffer() - the different
-     * buffer sizes will be spotted and the buffer reallocated.
-     */
-    packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
-                                    EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE,
-                                    (int)templates[0].buflen, NULL);
-    packlen *= numtempl;
-    if (!tls_setup_write_buffer(rl, 1, packlen, packlen)) {
-        /* RLAYERfatal() already called */
-        return -1;
-    }
-    wb = &rl->wbuf[0];
-
-    mb_param.interleave = numtempl;
-    memcpy(aad, s->rlayer.write_sequence, 8);
-    aad[8] = templates[0].type;
-    aad[9] = (unsigned char)(templates[0].version >> 8);
-    aad[10] = (unsigned char)(templates[0].version);
-    aad[11] = 0;
-    aad[12] = 0;
-    mb_param.out = NULL;
-    mb_param.inp = aad;
-    mb_param.len = totlen;
-
-    packleni = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
-                                    EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
-                                    sizeof(mb_param), &mb_param);
-    packlen = (size_t)packleni;
-    if (packleni <= 0 || packlen > wb->len) { /* never happens */
-        RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-        return -1;
-    }
-
-    mb_param.out = wb->buf;
-    mb_param.inp = templates[0].buf;
-    mb_param.len = totlen;
-
-    if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
-                            EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
-                            sizeof(mb_param), &mb_param) <= 0) {
-        RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-        return -1;
-    }
-
-    s->rlayer.write_sequence[7] += mb_param.interleave;
-    if (s->rlayer.write_sequence[7] < mb_param.interleave) {
-        int j = 6;
-        while (j >= 0 && (++s->rlayer.write_sequence[j--]) == 0) ;
-    }
-
-    wb->offset = 0;
-    wb->left = packlen;
-
-    return 1;
-#else  /* !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK */
-    return 0;
-#endif
+    return rl->funcs->get_max_records(rl, type, len, maxfrag, preffrag);
 }
 
-static int tls_write_records_standard(OSSL_RECORD_LAYER *rl,
-                                      OSSL_RECORD_TEMPLATE *templates,
-                                      size_t numtempl)
+int tls_write_records_default(OSSL_RECORD_LAYER *rl,
+                              OSSL_RECORD_TEMPLATE *templates,
+                              size_t numtempl)
 {
     WPACKET pkt[SSL_MAX_PIPELINES + 1];
     SSL3_RECORD wr[SSL_MAX_PIPELINES + 1];
@@ -2049,8 +1909,6 @@ static int tls_write_records_standard(OSSL_RECORD_LAYER *rl,
 int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
                       size_t numtempl)
 {
-    int ret;
-
     /* Check we don't have pending data waiting to write */
     if (!ossl_assert(rl->nextwbuf >= rl->numwpipes
                      || SSL3_BUFFER_get_left(&rl->wbuf[rl->nextwbuf]) == 0)) {
@@ -2058,18 +1916,10 @@ int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
         return OSSL_RECORD_RETURN_FATAL;
     }
 
-    ret = tls_write_records_multiblock(rl, templates, numtempl);
-    if (ret < 0) {
+    if (!rl->funcs->write_records(rl, templates, numtempl)) {
         /* RLAYERfatal already called */
         return OSSL_RECORD_RETURN_FATAL;
     }
-    if (ret == 0) {
-        /* Multiblock wasn't suitable so just do a standard write */
-        if (!tls_write_records_standard(rl, templates, numtempl)) {
-            /* RLAYERfatal already called */
-            return OSSL_RECORD_RETURN_FATAL;
-        }
-    }
 
     rl->nextwbuf = 0;
     /* we now just need to write the buffers */
diff --git a/ssl/record/methods/tls_multib.c b/ssl/record/methods/tls_multib.c
new file mode 100644 (file)
index 0000000..0402fc9
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (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 "../../ssl_local.h"
+#include "../record_local.h"
+#include "recmethod_local.h"
+
+#if defined(OPENSSL_SMALL_FOOTPRINT) \
+    || !(defined(AES_ASM) && (defined(__x86_64) \
+                              || defined(__x86_64__) \
+                              || defined(_M_AMD64) \
+                              || defined(_M_X64)))
+# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+#endif
+
+static int tls_is_multiblock_capable(OSSL_RECORD_LAYER *rl, int type,
+                                     size_t len, size_t fraglen)
+{
+#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+    /* TODO(RECLAYER): REMOVE ME */
+    SSL_CONNECTION *s = rl->cbarg;
+
+    if (type == SSL3_RT_APPLICATION_DATA
+            && len >= 4 * fraglen
+            && s->compress == NULL
+            && rl->msg_callback == NULL
+            && !rl->use_etm
+            && RLAYER_USE_EXPLICIT_IV(rl)
+            && !BIO_get_ktls_send(s->wbio)
+            && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx))
+                & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) != 0)
+        return 1;
+#endif
+    return 0;
+}
+
+size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, int type,
+                                      size_t len, size_t maxfrag,
+                                      size_t *preffrag)
+{
+    if (tls_is_multiblock_capable(rl, type, len, *preffrag)) {
+        /* minimize address aliasing conflicts */
+        if ((*preffrag & 0xfff) == 0)
+            *preffrag -= 512;
+
+        if (len >= 8 * (*preffrag))
+            return 8;
+
+        return 4;
+    }
+
+    return tls_get_max_records_default(rl, type, len, maxfrag, preffrag);
+}
+
+/*
+ * Write records using the multiblock method.
+ *
+ * Returns 1 on success, 0 if multiblock isn't suitable (non-fatal error), or
+ * -1 on fatal error.
+ */
+static int tls_write_records_multiblock_int(OSSL_RECORD_LAYER *rl,
+                                            OSSL_RECORD_TEMPLATE *templates,
+                                            size_t numtempl)
+{
+#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+    size_t i;
+    size_t totlen;
+    SSL3_BUFFER *wb;
+    /* TODO(RECLAYER): Remove me */
+    SSL_CONNECTION *s = rl->cbarg;
+    unsigned char aad[13];
+    EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
+    size_t packlen;
+    int packleni;
+
+    if (numtempl != 4 && numtempl != 8)
+        return 0;
+
+    /*
+     * Check templates have contiguous buffers and are all the same type and
+     * length
+     */
+    for (i = 1; i < numtempl; i++) {
+        if (templates[i - 1].type != templates[i].type
+                || templates[i - 1].buflen != templates[i].buflen
+                || templates[i - 1].buf + templates[i - 1].buflen
+                   != templates[i].buf)
+            return 0;
+    }
+
+    totlen = templates[0].buflen * numtempl;
+    if (!tls_is_multiblock_capable(rl, templates[0].type, totlen,
+                                   templates[0].buflen))
+        return 0;
+
+    /*
+     * If we get this far, then multiblock is suitable
+     * Depending on platform multi-block can deliver several *times*
+     * better performance. Downside is that it has to allocate
+     * jumbo buffer to accommodate up to 8 records, but the
+     * compromise is considered worthy.
+     */
+
+    /*
+     * Allocate jumbo buffer. This will get freed next time we do a non
+     * multiblock write in the call to tls_setup_write_buffer() - the different
+     * buffer sizes will be spotted and the buffer reallocated.
+     */
+    packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+                                    EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE,
+                                    (int)templates[0].buflen, NULL);
+    packlen *= numtempl;
+    if (!tls_setup_write_buffer(rl, 1, packlen, packlen)) {
+        /* RLAYERfatal() already called */
+        return -1;
+    }
+    wb = &rl->wbuf[0];
+
+    mb_param.interleave = numtempl;
+    memcpy(aad, s->rlayer.write_sequence, 8);
+    aad[8] = templates[0].type;
+    aad[9] = (unsigned char)(templates[0].version >> 8);
+    aad[10] = (unsigned char)(templates[0].version);
+    aad[11] = 0;
+    aad[12] = 0;
+    mb_param.out = NULL;
+    mb_param.inp = aad;
+    mb_param.len = totlen;
+
+    packleni = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+                                    EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
+                                    sizeof(mb_param), &mb_param);
+    packlen = (size_t)packleni;
+    if (packleni <= 0 || packlen > wb->len) { /* never happens */
+        RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    mb_param.out = wb->buf;
+    mb_param.inp = templates[0].buf;
+    mb_param.len = totlen;
+
+    if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+                            EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
+                            sizeof(mb_param), &mb_param) <= 0) {
+        RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    s->rlayer.write_sequence[7] += mb_param.interleave;
+    if (s->rlayer.write_sequence[7] < mb_param.interleave) {
+        int j = 6;
+        while (j >= 0 && (++s->rlayer.write_sequence[j--]) == 0) ;
+    }
+
+    wb->offset = 0;
+    wb->left = packlen;
+
+    return 1;
+#else  /* !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK */
+    return 0;
+#endif
+}
+
+int tls_write_records_multiblock(OSSL_RECORD_LAYER *rl,
+                                 OSSL_RECORD_TEMPLATE *templates,
+                                 size_t numtempl)
+{
+    int ret;
+
+    ret = tls_write_records_multiblock_int(rl, templates, numtempl);
+    if (ret < 0) {
+        /* RLAYERfatal already called */
+        return 0;
+    }
+    if (ret == 0) {
+        /* Multiblock wasn't suitable so just do a standard write */
+        if (!tls_write_records_default(rl, templates, numtempl)) {
+            /* RLAYERfatal already called */
+            return 0;
+        }
+    }
+
+    return 1;
+}
index e34b8ca8ae9a5263ce1685e806ba31246b00273e..e2ca41adf8bd9fc3cdc42e3bfd2a92c98394c041 100644 (file)
@@ -136,13 +136,15 @@ static int tls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
 
 struct record_functions_st tls_any_funcs = {
     tls_any_set_crypto_state,
-    tls_default_read_n,
-    tls_get_more_records,
     tls_any_cipher,
     NULL,
     tls_any_set_protocol_version,
+    tls_default_read_n,
+    tls_get_more_records,
     tls_validate_record_header,
-    tls_default_post_process_record
+    tls_default_post_process_record,
+    tls_get_max_records_default,
+    tls_write_records_default
 };
 
 static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
@@ -156,11 +158,13 @@ static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
 
 struct record_functions_st dtls_any_funcs = {
     tls_any_set_crypto_state,
-    tls_default_read_n,
-    dtls_get_more_records,
     tls_any_cipher,
     NULL,
     dtls_any_set_protocol_version,
+    tls_default_read_n,
+    dtls_get_more_records,
+    NULL,
+    NULL,
     NULL,
     NULL
 };