From: Matt Caswell Date: Mon, 12 Sep 2022 14:50:26 +0000 (+0100) Subject: Restructure the write code X-Git-Tag: openssl-3.2.0-alpha1~2019 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bafe524b5ce425105ac321f9fffa23e2d5b06845;p=thirdparty%2Fopenssl.git Restructure the write code Move the multiblock code into a separate file and introduce the usage of record_functions_st for some write functions. Reviewed-by: Hugo Landau Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/19198) --- diff --git a/ssl/record/methods/build.info b/ssl/record/methods/build.info index 064bcaf177a..f31acd10b92 100644 --- a/ssl/record/methods/build.info +++ b/ssl/record/methods/build.info @@ -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. diff --git a/ssl/record/methods/ktls_meth.c b/ssl/record/methods/ktls_meth.c index 7f6c9602f0c..95f34d176f9 100644 --- a/ssl/record/methods/ktls_meth.c +++ b/ssl/record/methods/ktls_meth.c @@ -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 diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index 334a093362a..ee5d03a77d5 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -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); diff --git a/ssl/record/methods/ssl3_meth.c b/ssl/record/methods/ssl3_meth.c index f1fd1f42031..80551356cbd 100644 --- a/ssl/record/methods/ssl3_meth.c +++ b/ssl/record/methods/ssl3_meth.c @@ -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 }; diff --git a/ssl/record/methods/tls13_meth.c b/ssl/record/methods/tls13_meth.c index 2a24067d145..5195fbd9634 100644 --- a/ssl/record/methods/tls13_meth.c +++ b/ssl/record/methods/tls13_meth.c @@ -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 }; diff --git a/ssl/record/methods/tls1_meth.c b/ssl/record/methods/tls1_meth.c index db3cad4ee35..a12a0cf843e 100644 --- a/ssl/record/methods/tls1_meth.c +++ b/ssl/record/methods/tls1_meth.c @@ -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 }; diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index 95083532f4a..a55a5a81526 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -18,15 +18,6 @@ #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 index 00000000000..0402fc99dd5 --- /dev/null +++ b/ssl/record/methods/tls_multib.c @@ -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; +} diff --git a/ssl/record/methods/tlsany_meth.c b/ssl/record/methods/tlsany_meth.c index e34b8ca8ae9..e2ca41adf8b 100644 --- a/ssl/record/methods/tlsany_meth.c +++ b/ssl/record/methods/tlsany_meth.c @@ -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 };