Index: head/security/openssl/Makefile =================================================================== --- head/security/openssl/Makefile +++ head/security/openssl/Makefile @@ -3,6 +3,7 @@ PORTNAME= openssl PORTVERSION= 1.1.1h +PORTREVISION= 1 PORTEPOCH= 1 CATEGORIES= security devel MASTER_SITES= https://www.openssl.org/source/ \ Index: head/security/openssl/files/extra-patch-ktls =================================================================== --- head/security/openssl/files/extra-patch-ktls +++ head/security/openssl/files/extra-patch-ktls @@ -1,8 +1,8 @@ diff --git CHANGES CHANGES -index f4230aaac0..3cc665f654 100644 +index 7ea3d2b823..514cf091a3 100644 --- CHANGES +++ CHANGES -@@ -306,6 +306,11 @@ +@@ -354,6 +354,11 @@ necessary to configure just to create a source distribution. [Richard Levitte] @@ -15,10 +15,10 @@ *) Timing vulnerability in DSA signature generation diff --git Configure Configure -index 2e9efaa5f3..524b58cbb9 100755 +index 1d73d06e1b..29e655da96 100755 --- Configure +++ Configure -@@ -331,6 +331,7 @@ my @dtls = qw(dtls1 dtls1_2); +@@ -341,6 +341,7 @@ my @dtls = qw(dtls1 dtls1_2); # For developers: keep it sorted alphabetically my @disablables = ( @@ -26,7 +26,7 @@ "afalgeng", "aria", "asan", -@@ -464,6 +465,7 @@ our %disabled = ( # "what" => "comment" +@@ -474,6 +475,7 @@ our %disabled = ( # "what" => "comment" "weak-ssl-ciphers" => "default", "zlib" => "default", "zlib-dynamic" => "default", @@ -34,7 +34,7 @@ ); # Note: => pair form used for aesthetics, not to truly make a hash table -@@ -1567,6 +1569,33 @@ unless ($disabled{devcryptoeng}) { +@@ -1580,6 +1582,33 @@ unless ($disabled{devcryptoeng}) { } } @@ -69,7 +69,7 @@ # do this late because some of them depend on %disabled. diff --git INSTALL INSTALL -index 328ad2baf4..46735b8236 100644 +index f5118428b3..be84f2aa8e 100644 --- INSTALL +++ INSTALL @@ -262,6 +262,15 @@ @@ -89,10 +89,10 @@ Build with the Address sanitiser. This is a developer option only. It may not work on all platforms and should never be diff --git apps/s_client.c apps/s_client.c -index 26a6789d81..457e539b85 100644 +index 83b3fc9c7f..68bd9ced01 100644 --- apps/s_client.c +++ apps/s_client.c -@@ -3262,6 +3262,12 @@ static void print_stuff(BIO *bio, SSL *s, int full) +@@ -3282,6 +3282,12 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_printf(bio, "Expansion: %s\n", expansion ? SSL_COMP_get_name(expansion) : "NONE"); #endif @@ -153,7 +153,7 @@ return sock; } diff --git crypto/bio/bss_conn.c crypto/bio/bss_conn.c -index dd43a40601..3def4550cb 100644 +index 807a82b23b..f75bf37adb 100644 --- crypto/bio/bss_conn.c +++ crypto/bio/bss_conn.c @@ -11,6 +11,7 @@ @@ -174,7 +174,7 @@ BIO_ADDRINFO *addr_first; const BIO_ADDRINFO *addr_iter; -@@ -311,7 +315,12 @@ static int conn_read(BIO *b, char *out, int outl) +@@ -320,7 +324,12 @@ static int conn_read(BIO *b, char *out, int outl) if (out != NULL) { clear_socket_error(); @@ -188,7 +188,7 @@ BIO_clear_retry_flags(b); if (ret <= 0) { if (BIO_sock_should_retry(ret)) -@@ -336,7 +345,16 @@ static int conn_write(BIO *b, const char *in, int inl) +@@ -345,7 +354,16 @@ static int conn_write(BIO *b, const char *in, int inl) } clear_socket_error(); @@ -206,7 +206,7 @@ BIO_clear_retry_flags(b); if (ret <= 0) { if (BIO_sock_should_retry(ret)) -@@ -352,6 +370,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) +@@ -361,6 +379,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) const char **pptr = NULL; long ret = 1; BIO_CONNECT *data; @@ -220,7 +220,7 @@ data = (BIO_CONNECT *)b->ptr; -@@ -500,6 +525,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) +@@ -520,6 +545,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_EOF: ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; break; @@ -253,7 +253,7 @@ ret = 0; break; diff --git crypto/bio/bss_sock.c crypto/bio/bss_sock.c -index 6251f3d46a..c879533fef 100644 +index 6251f3d46a..7d582b5549 100644 --- crypto/bio/bss_sock.c +++ crypto/bio/bss_sock.c @@ -11,6 +11,7 @@ @@ -319,21 +319,22 @@ BIO_clear_retry_flags(b); if (ret <= 0) { if (BIO_sock_should_retry(ret)) -@@ -126,6 +153,13 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) +@@ -126,6 +153,14 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; int *ip; +# ifndef OPENSSL_NO_KTLS ++ size_t crypto_info_len; +# ifdef __FreeBSD__ + struct tls_enable *crypto_info; +# else -+ struct tls12_crypto_info_aes_gcm_128 *crypto_info; ++ struct tls_crypto_info_all *crypto_info; +# endif +# endif switch (cmd) { case BIO_C_SET_FD: -@@ -153,6 +187,31 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) +@@ -153,6 +188,33 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_FLUSH: ret = 1; break; @@ -341,10 +342,12 @@ + case BIO_CTRL_SET_KTLS: +# ifdef __FreeBSD__ + crypto_info = (struct tls_enable *)ptr; ++ crypto_info_len = sizeof(*crypto_info); +# else -+ crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr; ++ crypto_info = (struct tls_crypto_info_all *)ptr; ++ crypto_info_len = crypto_info->tls_crypto_info_len; +# endif -+ ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num); ++ ret = ktls_start(b->num, crypto_info, crypto_info_len, num); + if (ret) + BIO_set_ktls_flag(b, num); + break; @@ -366,10 +369,10 @@ ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; break; diff --git crypto/err/openssl.txt crypto/err/openssl.txt -index 35512f9caf..426297da8b 100644 +index 0b5873ebbc..a4dcacab59 100644 --- crypto/err/openssl.txt +++ crypto/err/openssl.txt -@@ -1315,6 +1315,7 @@ SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate +@@ -1317,6 +1317,7 @@ SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate SSL_F_SSL_RENEGOTIATE_ABBREVIATED:546:SSL_renegotiate_abbreviated SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:* SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:* @@ -397,7 +400,7 @@ /* Special case: -1 length restores whole IV */ if (arg == -1) { diff --git doc/man3/BIO_ctrl.pod doc/man3/BIO_ctrl.pod -index 60cd10883b..589338dd51 100644 +index 2e438c3ce9..31b18b2879 100644 --- doc/man3/BIO_ctrl.pod +++ doc/man3/BIO_ctrl.pod @@ -5,7 +5,8 @@ @@ -455,9 +458,9 @@ + =head1 COPYRIGHT - Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. diff --git doc/man3/SSL_CTX_set_mode.pod doc/man3/SSL_CTX_set_mode.pod -index 387d1ec1ef..373b2aa0f2 100644 +index 85e3353e0e..27eaebad1e 100644 --- doc/man3/SSL_CTX_set_mode.pod +++ doc/man3/SSL_CTX_set_mode.pod @@ -114,6 +114,22 @@ enables this behaviour to allow interoperability with such broken @@ -491,8 +494,50 @@ =head1 COPYRIGHT +diff --git doc/man3/SSL_CTX_set_record_padding_callback.pod doc/man3/SSL_CTX_set_record_padding_callback.pod +index 13e56f0c57..247a39fc03 100644 +--- doc/man3/SSL_CTX_set_record_padding_callback.pod ++++ doc/man3/SSL_CTX_set_record_padding_callback.pod +@@ -16,7 +16,7 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding + #include + + void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); +- void SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); ++ int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); + + void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); + void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); +@@ -32,6 +32,8 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding + SSL_CTX_set_record_padding_callback() or SSL_set_record_padding_callback() + can be used to assign a callback function I to specify the padding + for TLS 1.3 records. The value set in B is copied to a new SSL by SSL_new(). ++Kernel TLS is not possible if the record padding callback is set, and the callback ++function cannot be set if Kernel TLS is already configured for the current SSL object. + + SSL_CTX_set_record_padding_callback_arg() and SSL_set_record_padding_callback_arg() + assign a value B that is passed to the callback when it is invoked. The value +@@ -64,6 +66,9 @@ indicates no padding will be added. A return value that causes the record to + exceed the maximum record size (SSL3_RT_MAX_PLAIN_LENGTH) will pad out to the + maximum record size. + ++The SSL_CTX_get_record_padding_callback_arg() function returns 1 on success or 0 if ++the callback function is not set because Kernel TLS is configured for the SSL object. ++ + =head1 NOTES + + The default behavior is to add no padding to the record. +@@ -84,6 +89,9 @@ L, L + + The record padding API was added for TLS 1.3 support in OpenSSL 1.1.1. + ++The return type of SSL_CTX_set_record_padding_callback() function was ++changed to int in OpenSSL 3.0. ++ + =head1 COPYRIGHT + + Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. diff --git doc/man3/SSL_write.pod doc/man3/SSL_write.pod -index a76ffbb8fd..d7900fd87b 100644 +index 5e3ce1e7e4..20c7953deb 100644 --- doc/man3/SSL_write.pod +++ doc/man3/SSL_write.pod @@ -2,12 +2,13 @@ @@ -639,10 +684,10 @@ +#endif diff --git include/internal/ktls.h include/internal/ktls.h new file mode 100644 -index 0000000000..209dff1689 +index 0000000000..3baa63f781 --- /dev/null +++ include/internal/ktls.h -@@ -0,0 +1,345 @@ +@@ -0,0 +1,432 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * @@ -652,23 +697,46 @@ + * https://www.openssl.org/source/license.html + */ + -+#ifndef OPENSSL_NO_KTLS -+# ifndef HEADER_INTERNAL_KTLS -+# define HEADER_INTERNAL_KTLS ++#if defined(OPENSSL_SYS_LINUX) ++# ifndef OPENSSL_NO_KTLS ++# include ++# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) ++# define OPENSSL_NO_KTLS ++# ifndef PEDANTIC ++# warning "KTLS requires Kernel Headers >= 4.13.0" ++# warning "Skipping Compilation of KTLS" ++# endif ++# endif ++# endif ++#endif + ++#ifndef HEADER_INTERNAL_KTLS ++# define HEADER_INTERNAL_KTLS ++# ifndef OPENSSL_NO_KTLS ++ +# if defined(__FreeBSD__) +# include +# include +# include +# include +# include -+# include ++# include "openssl/ssl3.h" + ++# ifndef TCP_RXTLS_ENABLE ++# define OPENSSL_NO_KTLS_RX ++# endif ++# define OPENSSL_KTLS_AES_GCM_128 ++# define OPENSSL_KTLS_AES_GCM_256 ++# define OPENSSL_KTLS_TLS13 ++ +/* + * Only used by the tests in sslapitest.c. + */ +# define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 ++# define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8 + ++typedef struct tls_enable ktls_crypto_info_t; ++ +/* + * FreeBSD does not require any additional steps to enable KTLS before + * setting keys. @@ -681,18 +749,25 @@ +/* + * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer + * as using TLS. If successful, then data sent using this socket will -+ * be encrypted and encapsulated in TLS records using the tls_en. ++ * be encrypted and encapsulated in TLS records using the tls_en + * provided here. ++ * ++ * The TCP_RXTLS_ENABLE socket option marks the incoming socket buffer ++ * as using TLS. If successful, then data received for this socket will ++ * be authenticated and decrypted using the tls_en provided here. + */ +static ossl_inline int ktls_start(int fd, -+ struct tls_enable *tls_en, ++ void *tls_en, + size_t len, int is_tx) +{ + if (is_tx) + return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, -+ tls_en, sizeof(*tls_en)) ? 0 : 1; -+ else -+ return 0; ++ tls_en, len) ? 0 : 1; ++# ifndef OPENSSL_NO_KTLS_RX ++ return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, len) ? 0 : 1; ++# else ++ return 0; ++# endif +} + +/* @@ -728,12 +803,80 @@ + return sendmsg(fd, &msg, 0); +} + ++# ifdef OPENSSL_NO_KTLS_RX ++ +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + return -1; +} + ++# else /* !defined(OPENSSL_NO_KTLS_RX) */ ++ +/* ++ * Receive a TLS record using the tls_en provided in ktls_start. The ++ * kernel strips any explicit IV and authentication tag, but provides ++ * the TLS record header via a control message. If there is an error ++ * with the TLS record such as an invalid header, invalid padding, or ++ * authentication failure recvmsg() will fail with an error. ++ */ ++static ossl_inline int ktls_read_record(int fd, void *data, size_t length) ++{ ++ struct msghdr msg = { 0 }; ++ int cmsg_len = sizeof(struct tls_get_record); ++ struct tls_get_record *tgr; ++ struct cmsghdr *cmsg; ++ char buf[CMSG_SPACE(cmsg_len)]; ++ struct iovec msg_iov; /* Vector of data to send/receive into */ ++ int ret; ++ unsigned char *p = data; ++ const size_t prepend_length = SSL3_RT_HEADER_LENGTH; ++ ++ if (length <= prepend_length) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ msg.msg_control = buf; ++ msg.msg_controllen = sizeof(buf); ++ ++ msg_iov.iov_base = p + prepend_length; ++ msg_iov.iov_len = length - prepend_length; ++ msg.msg_iov = &msg_iov; ++ msg.msg_iovlen = 1; ++ ++ ret = recvmsg(fd, &msg, 0); ++ if (ret <= 0) ++ return ret; ++ ++ if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) { ++ errno = EMSGSIZE; ++ return -1; ++ } ++ ++ if (msg.msg_controllen == 0) { ++ errno = EBADMSG; ++ return -1; ++ } ++ ++ cmsg = CMSG_FIRSTHDR(&msg); ++ if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD ++ || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) { ++ errno = EBADMSG; ++ return -1; ++ } ++ ++ tgr = (struct tls_get_record *)CMSG_DATA(cmsg); ++ p[0] = tgr->tls_type; ++ p[1] = tgr->tls_vmajor; ++ p[2] = tgr->tls_vminor; ++ *(uint16_t *)(p + 3) = htons(ret); ++ ++ return ret + prepend_length; ++} ++ ++# endif /* OPENSSL_NO_KTLS_RX */ ++ ++/* + * KTLS enables the sendfile system call to send data from a file over + * TLS. + */ @@ -751,97 +894,64 @@ + } + return sbytes; +} ++ +# endif /* __FreeBSD__ */ + +# if defined(OPENSSL_SYS_LINUX) -+# include + -+# define K_MAJ 4 -+# define K_MIN1 13 -+# define K_MIN2 0 -+# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2) -+ ++# include ++# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) ++# define OPENSSL_NO_KTLS_RX +# ifndef PEDANTIC -+# warning "KTLS requires Kernel Headers >= 4.13.0" -+# warning "Skipping Compilation of KTLS" ++# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" ++# warning "Skipping Compilation of KTLS receive data path" +# endif ++# endif ++# define OPENSSL_KTLS_AES_GCM_128 ++# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) ++# define OPENSSL_KTLS_AES_GCM_256 ++# define OPENSSL_KTLS_TLS13 ++# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) ++# define OPENSSL_KTLS_AES_CCM_128 ++# endif ++# endif + -+# define TLS_TX 1 -+# define TLS_RX 2 ++# include ++# include ++# include ++# include "openssl/ssl3.h" ++# include "openssl/tls1.h" ++# include "openssl/evp.h" + -+# define TLS_CIPHER_AES_GCM_128 51 -+# define TLS_CIPHER_AES_GCM_128_IV_SIZE 8 -+# define TLS_CIPHER_AES_GCM_128_KEY_SIZE 16 -+# define TLS_CIPHER_AES_GCM_128_SALT_SIZE 4 -+# define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16 -+# define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 ++# ifndef SOL_TLS ++# define SOL_TLS 282 ++# endif + -+# define TLS_SET_RECORD_TYPE 1 ++# ifndef TCP_ULP ++# define TCP_ULP 31 ++# endif + -+struct tls_crypto_info { -+ unsigned short version; -+ unsigned short cipher_type; -+}; ++# ifndef TLS_RX ++# define TLS_RX 2 ++# endif + -+struct tls12_crypto_info_aes_gcm_128 { -+ struct tls_crypto_info info; -+ unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE]; -+ unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE]; -+ unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE]; -+ unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; ++struct tls_crypto_info_all { ++ union { ++# ifdef OPENSSL_KTLS_AES_GCM_128 ++ struct tls12_crypto_info_aes_gcm_128 gcm128; ++# endif ++# ifdef OPENSSL_KTLS_AES_GCM_256 ++ struct tls12_crypto_info_aes_gcm_256 gcm256; ++# endif ++# ifdef OPENSSL_KTLS_AES_CCM_128 ++ struct tls12_crypto_info_aes_ccm_128 ccm128; ++# endif ++ }; ++ size_t tls_crypto_info_len; +}; + -+/* Dummy functions here */ -+static ossl_inline int ktls_enable(int fd) -+{ -+ return 0; -+} ++typedef struct tls_crypto_info_all ktls_crypto_info_t; + -+static ossl_inline int ktls_start(int fd, -+ struct tls12_crypto_info_aes_gcm_128 -+ *crypto_info, size_t len, int is_tx) -+{ -+ return 0; -+} -+ -+static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, -+ const void *data, size_t length) -+{ -+ return -1; -+} -+ -+static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -+{ -+ return -1; -+} -+ -+static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) -+{ -+ return -1; -+} -+ -+# else /* KERNEL_VERSION */ -+ -+# include -+# include -+# include -+# include -+# include "openssl/ssl3.h" -+# include "openssl/tls1.h" -+# include "openssl/evp.h" -+ -+# ifndef SOL_TLS -+# define SOL_TLS 282 -+# endif -+ -+# ifndef TCP_ULP -+# define TCP_ULP 31 -+# endif -+ -+# ifndef TLS_RX -+# define TLS_RX 2 -+# endif -+ +/* + * When successful, this socket option doesn't change the behaviour of the + * TCP socket, except changing the TCP setsockopt handler to enable the @@ -861,12 +971,11 @@ + * If successful, then data received using this socket will be decrypted, + * authenticated and decapsulated using the crypto_info provided here. + */ -+static ossl_inline int ktls_start(int fd, -+ struct tls12_crypto_info_aes_gcm_128 -+ *crypto_info, size_t len, int is_tx) ++static ossl_inline int ktls_start(int fd, void *crypto_info, ++ size_t len, int is_tx) +{ + return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, -+ crypto_info, sizeof(*crypto_info)) ? 0 : 1; ++ crypto_info, len) ? 0 : 1; +} + +/* @@ -915,20 +1024,15 @@ + return sendfile(s, fd, &off, size); +} + -+# define K_MIN1_RX 17 -+# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1_RX, K_MIN2) ++# ifdef OPENSSL_NO_KTLS_RX + -+# ifndef PEDANTIC -+# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" -+# warning "Skipping Compilation of KTLS receive data path" -+# endif + +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + return -1; +} + -+# else ++# else /* !defined(OPENSSL_NO_KTLS_RX) */ + +/* + * Receive a TLS record using the crypto_info provided in ktls_start. @@ -983,11 +1087,39 @@ + return ret; +} + -+# endif -+# endif -+# endif -+# endif -+#endif ++# endif /* OPENSSL_NO_KTLS_RX */ ++ ++# endif /* OPENSSL_SYS_LINUX */ ++# else /* OPENSSL_NO_KTLS */ ++/* Dummy functions here */ ++static ossl_inline int ktls_enable(int fd) ++{ ++ return 0; ++} ++ ++static ossl_inline int ktls_start(int fd, void *crypto_info, ++ size_t len, int is_tx) ++{ ++ return 0; ++} ++ ++static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, ++ const void *data, size_t length) ++{ ++ return -1; ++} ++ ++static ossl_inline int ktls_read_record(int fd, void *data, size_t length) ++{ ++ return -1; ++} ++ ++static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) ++{ ++ return -1; ++} ++# endif /* OPENSSL_NO_KTLS */ ++#endif /* HEADER_INTERNAL_KTLS */ diff --git include/openssl/bio.h include/openssl/bio.h index ae559a5105..fa50337aab 100644 --- include/openssl/bio.h @@ -1045,7 +1177,7 @@ /* Padding modes */ #define EVP_PADDING_PKCS7 1 diff --git include/openssl/ssl.h include/openssl/ssl.h -index 6724ccf2d2..48710cde1f 100644 +index fd0c5a9996..09620489bc 100644 --- include/openssl/ssl.h +++ include/openssl/ssl.h @@ -493,6 +493,10 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); @@ -1079,6 +1211,15 @@ __owur int SSL_write(SSL *ssl, const void *buf, int num); __owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); __owur int SSL_write_early_data(SSL *s, const void *buf, size_t num, +@@ -2123,7 +2133,7 @@ void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); + void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); + int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); + +-void SSL_set_record_padding_callback(SSL *ssl, ++int SSL_set_record_padding_callback(SSL *ssl, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); + void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); diff --git include/openssl/sslerr.h include/openssl/sslerr.h index 82983d3c1e..0bdc8f3b2c 100644 --- include/openssl/sslerr.h @@ -1091,8 +1232,253 @@ # define SSL_F_SSL_SESSION_DUP 348 # define SSL_F_SSL_SESSION_NEW 189 # define SSL_F_SSL_SESSION_PRINT_FP 190 +diff --git ssl/build.info ssl/build.info +index bb2f1deb53..1c49ac9aee 100644 +--- ssl/build.info ++++ ssl/build.info +@@ -1,4 +1,5 @@ + LIBS=../libssl ++ + SOURCE[../libssl]=\ + pqueue.c packet.c \ + statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c record/rec_layer_s3.c \ +@@ -13,3 +14,7 @@ SOURCE[../libssl]=\ + bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \ + record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ + statem/statem.c record/ssl3_record_tls13.c ++ ++IF[{- !$disabled{ktls} -}] ++ SOURCE[../libssl]=ktls.c ++ENDIF +diff --git ssl/ktls.c ssl/ktls.c +new file mode 100644 +index 0000000000..7123ecac00 +--- /dev/null ++++ ssl/ktls.c +@@ -0,0 +1,221 @@ ++/* ++ * Copyright 2018-2020 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 "internal/ktls.h" ++ ++#if defined(__FreeBSD__) ++# include ++ ++/*- ++ * Check if a given cipher is supported by the KTLS interface. ++ * The kernel might still fail the setsockopt() if no suitable ++ * provider is found, but this checks if the socket option ++ * supports the cipher suite used at all. ++ */ ++int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, ++ const EVP_CIPHER_CTX *dd) ++{ ++ ++ switch (s->version) { ++ case TLS1_VERSION: ++ case TLS1_1_VERSION: ++ case TLS1_2_VERSION: ++ case TLS1_3_VERSION: ++ break; ++ default: ++ return 0; ++ } ++ ++ switch (s->s3->tmp.new_cipher->algorithm_enc) { ++ case SSL_AES128GCM: ++ case SSL_AES256GCM: ++ return 1; ++ case SSL_AES128: ++ case SSL_AES256: ++ if (s->ext.use_etm) ++ return 0; ++ switch (s->s3->tmp.new_cipher->algorithm_mac) { ++ case SSL_SHA1: ++ case SSL_SHA256: ++ case SSL_SHA384: ++ return 1; ++ default: ++ return 0; ++ } ++ default: ++ return 0; ++ } ++} ++ ++/* Function to configure kernel TLS structure */ ++int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, ++ void *rl_sequence, ktls_crypto_info_t *crypto_info, ++ unsigned char **rec_seq, unsigned char *iv, ++ unsigned char *key, unsigned char *mac_key, ++ size_t mac_secret_size) ++{ ++ memset(crypto_info, 0, sizeof(*crypto_info)); ++ switch (s->s3->tmp.new_cipher->algorithm_enc) { ++ case SSL_AES128GCM: ++ case SSL_AES256GCM: ++ crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; ++ if (s->version == TLS1_3_VERSION) ++ crypto_info->iv_len = EVP_CIPHER_CTX_iv_length(dd); ++ else ++ crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN; ++ break; ++ case SSL_AES128: ++ case SSL_AES256: ++ switch (s->s3->tmp.new_cipher->algorithm_mac) { ++ case SSL_SHA1: ++ crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC; ++ break; ++ case SSL_SHA256: ++ crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC; ++ break; ++ case SSL_SHA384: ++ crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC; ++ break; ++ default: ++ return 0; ++ } ++ crypto_info->cipher_algorithm = CRYPTO_AES_CBC; ++ crypto_info->iv_len = EVP_CIPHER_iv_length(c); ++ crypto_info->auth_key = mac_key; ++ crypto_info->auth_key_len = mac_secret_size; ++ break; ++ default: ++ return 0; ++ } ++ crypto_info->cipher_key = key; ++ crypto_info->cipher_key_len = EVP_CIPHER_key_length(c); ++ crypto_info->iv = iv; ++ crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; ++ crypto_info->tls_vminor = (s->version & 0x000000ff); ++# ifdef TCP_RXTLS_ENABLE ++ memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); ++ if (rec_seq != NULL) ++ *rec_seq = crypto_info->rec_seq; ++# else ++ if (rec_seq != NULL) ++ *rec_seq = NULL; ++# endif ++ return 1; ++}; ++ ++#endif /* __FreeBSD__ */ ++ ++#if defined(OPENSSL_SYS_LINUX) ++ ++/* Function to check supported ciphers in Linux */ ++int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, ++ const EVP_CIPHER_CTX *dd) ++{ ++ switch (s->version) { ++ case TLS1_2_VERSION: ++ case TLS1_3_VERSION: ++ break; ++ default: ++ return 0; ++ } ++ ++ /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */ ++ switch (EVP_CIPHER_nid(c)) ++ { ++# ifdef OPENSSL_KTLS_AES_CCM_128 ++ case NID_aes_128_ccm: ++ if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) ++ return 0; ++# endif ++# ifdef OPENSSL_KTLS_AES_GCM_128 ++ case NID_aes_128_gcm: ++# endif ++# ifdef OPENSSL_KTLS_AES_GCM_256 ++ case NID_aes_256_gcm: ++# endif ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++/* Function to configure kernel TLS structure */ ++int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, ++ void *rl_sequence, ktls_crypto_info_t *crypto_info, ++ unsigned char **rec_seq, unsigned char *iv, ++ unsigned char *key, unsigned char *mac_key, ++ size_t mac_secret_size) ++{ ++ unsigned char geniv[12]; ++ unsigned char *iiv = iv; ++ ++ if (s->version == TLS1_2_VERSION && ++ EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { ++ EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, ++ EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, ++ geniv); ++ iiv = geniv; ++ } ++ ++ memset(crypto_info, 0, sizeof(*crypto_info)); ++ switch (EVP_CIPHER_nid(c)) ++ { ++# ifdef OPENSSL_KTLS_AES_GCM_128 ++ case NID_aes_128_gcm: ++ crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; ++ crypto_info->gcm128.info.version = s->version; ++ crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); ++ memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, ++ TLS_CIPHER_AES_GCM_128_IV_SIZE); ++ memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); ++ memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c)); ++ memcpy(crypto_info->gcm128.rec_seq, rl_sequence, ++ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); ++ if (rec_seq != NULL) ++ *rec_seq = crypto_info->gcm128.rec_seq; ++ return 1; ++# endif ++# ifdef OPENSSL_KTLS_AES_GCM_256 ++ case NID_aes_256_gcm: ++ crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; ++ crypto_info->gcm256.info.version = s->version; ++ crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); ++ memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, ++ TLS_CIPHER_AES_GCM_256_IV_SIZE); ++ memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); ++ memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c)); ++ memcpy(crypto_info->gcm256.rec_seq, rl_sequence, ++ TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); ++ if (rec_seq != NULL) ++ *rec_seq = crypto_info->gcm256.rec_seq; ++ return 1; ++# endif ++# ifdef OPENSSL_KTLS_AES_CCM_128 ++ case NID_aes_128_ccm: ++ crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; ++ crypto_info->ccm128.info.version = s->version; ++ crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); ++ memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, ++ TLS_CIPHER_AES_CCM_128_IV_SIZE); ++ memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); ++ memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c)); ++ memcpy(crypto_info->ccm128.rec_seq, rl_sequence, ++ TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); ++ if (rec_seq != NULL) ++ *rec_seq = crypto_info->ccm128.rec_seq; ++ return 1; ++# endif ++ default: ++ return 0; ++ } ++ ++} ++ ++#endif /* OPENSSL_SYS_LINUX */ diff --git ssl/record/rec_layer_s3.c ssl/record/rec_layer_s3.c -index b2a7a47eb0..36f37c4ae2 100644 +index b2a7a47eb0..0c4af1981b 100644 --- ssl/record/rec_layer_s3.c +++ ssl/record/rec_layer_s3.c @@ -268,11 +268,15 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, @@ -1174,7 +1560,7 @@ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); goto err; -@@ -895,12 +919,16 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, +@@ -895,15 +919,20 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, goto err; } } else { @@ -1196,7 +1582,11 @@ } if (SSL_TREAT_AS_TLS13(s) -@@ -959,7 +987,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, ++ && !BIO_get_ktls_send(s->wbio) + && s->enc_write_ctx != NULL + && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS + || type != SSL3_RT_ALERT)) { +@@ -959,7 +988,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * in the wb->buf */ @@ -1205,7 +1595,7 @@ unsigned char *mac; if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) -@@ -975,24 +1003,26 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, +@@ -975,24 +1004,26 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * This will be at most one cipher block or the tag length if using * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case. */ @@ -1245,7 +1635,7 @@ } if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) { -@@ -1008,12 +1038,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, +@@ -1008,12 +1039,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, goto err; } } else { @@ -1265,7 +1655,7 @@ } } -@@ -1023,13 +1055,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, +@@ -1023,13 +1056,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, thispkt = &pkt[j]; thiswr = &wr[j]; @@ -1284,7 +1674,7 @@ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); goto err; -@@ -1074,13 +1110,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, +@@ -1074,13 +1111,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, goto err; } @@ -1300,7 +1690,7 @@ if (create_empty_fragment) { /* -@@ -1097,6 +1128,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, +@@ -1097,6 +1129,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, return 1; } @@ -1315,7 +1705,7 @@ /* now let's set up wb */ SSL3_BUFFER_set_left(&s->rlayer.wbuf[j], prefix_len + SSL3_RECORD_get_length(thiswr)); -@@ -1150,6 +1189,21 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, +@@ -1150,6 +1190,21 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, clear_sys_error(); if (s->wbio != NULL) { s->rwstate = SSL_WRITING; @@ -1372,7 +1762,7 @@ #define SSL3_RECORD_get_off(r) ((r)->off) #define SSL3_RECORD_set_off(r, o) ((r)->off = (o)) diff --git ssl/record/ssl3_buffer.c ssl/record/ssl3_buffer.c -index 605f8f9b75..32ee4f1786 100644 +index 9b2a6964c6..fef54e01f3 100644 --- ssl/record/ssl3_buffer.c +++ ssl/record/ssl3_buffer.c @@ -111,23 +111,27 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) @@ -1428,7 +1818,7 @@ pipes--; } diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c -index ab5d22aa10..5f450fd940 100644 +index ab5d22aa10..3d747db64b 100644 --- ssl/record/ssl3_record.c +++ ssl/record/ssl3_record.c @@ -186,9 +186,11 @@ int ssl3_get_record(SSL *s) @@ -1451,7 +1841,7 @@ - return rret; /* error or non-blocking */ + if (rret <= 0) { +#ifndef OPENSSL_NO_KTLS -+ if (!BIO_get_ktls_recv(s->rbio)) ++ if (!BIO_get_ktls_recv(s->rbio) || rret == 0) + return rret; /* error or non-blocking */ + switch (errno) { + case EBADMSG: @@ -1550,7 +1940,7 @@ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0), diff --git ssl/ssl_lib.c ssl/ssl_lib.c -index 7c7e59789c..9d242fc25d 100644 +index b1df374817..bd31aaf27b 100644 --- ssl/ssl_lib.c +++ ssl/ssl_lib.c @@ -11,6 +11,7 @@ @@ -1585,7 +1975,7 @@ BUF_MEM_free(s->init_buf); -@@ -1212,8 +1218,6 @@ void SSL_free(SSL *s) +@@ -1214,8 +1220,6 @@ void SSL_free(SSL *s) if (s->method != NULL) s->method->ssl_free(s); @@ -1594,7 +1984,7 @@ SSL_CTX_free(s->ctx); ASYNC_WAIT_CTX_free(s->waitctx); -@@ -1353,6 +1357,15 @@ int SSL_set_fd(SSL *s, int fd) +@@ -1355,6 +1359,15 @@ int SSL_set_fd(SSL *s, int fd) } BIO_set_fd(bio, fd, BIO_NOCLOSE); SSL_set_bio(s, bio, bio); @@ -1610,7 +2000,7 @@ ret = 1; err: return ret; -@@ -1372,6 +1385,15 @@ int SSL_set_wfd(SSL *s, int fd) +@@ -1374,6 +1387,15 @@ int SSL_set_wfd(SSL *s, int fd) } BIO_set_fd(bio, fd, BIO_NOCLOSE); SSL_set0_wbio(s, bio); @@ -1626,7 +2016,7 @@ } else { BIO_up_ref(rbio); SSL_set0_wbio(s, rbio); -@@ -1953,6 +1975,69 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) +@@ -1955,6 +1977,69 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) } } @@ -1696,7 +2086,7 @@ int SSL_write(SSL *s, const void *buf, int num) { int ret; -@@ -2197,6 +2282,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +@@ -2199,6 +2284,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_SET_MAX_SEND_FRAGMENT: if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) return 0; @@ -1707,20 +2097,60 @@ s->max_send_fragment = larg; if (s->max_send_fragment < s->split_send_fragment) s->split_send_fragment = s->max_send_fragment; +@@ -4417,11 +4506,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) + return 1; + } + +-void SSL_set_record_padding_callback(SSL *ssl, ++int SSL_set_record_padding_callback(SSL *ssl, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)) + { +- ssl->record_padding_cb = cb; ++ BIO *b; ++ ++ b = SSL_get_wbio(ssl); ++ if (b == NULL || !BIO_get_ktls_send(b)) { ++ ssl->record_padding_cb = cb; ++ return 1; ++ } ++ return 0; + } + + void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) diff --git ssl/ssl_local.h ssl/ssl_local.h -index 8ddbde7729..aea5c76809 100644 +index 8ddbde7729..dc430fe40b 100644 --- ssl/ssl_local.h +++ ssl/ssl_local.h -@@ -34,6 +34,7 @@ +@@ -34,6 +34,8 @@ # include "internal/dane.h" # include "internal/refcount.h" # include "internal/tsan_assist.h" +# include "internal/bio.h" ++# include "internal/ktls.h" # ifdef OPENSSL_BUILD_SHLIBSSL # undef OPENSSL_EXTERN +@@ -2618,6 +2620,17 @@ __owur int ssl_log_secret(SSL *ssl, const char *label, + #define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET" + #define EXPORTER_SECRET_LABEL "EXPORTER_SECRET" + ++# ifndef OPENSSL_NO_KTLS ++/* ktls.c */ ++int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, ++ const EVP_CIPHER_CTX *dd); ++int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, ++ void *rl_sequence, ktls_crypto_info_t *crypto_info, ++ unsigned char **rec_seq, unsigned char *iv, ++ unsigned char *key, unsigned char *mac_key, ++ size_t mac_secret_size); ++# endif ++ + /* s3_cbc.c */ + __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); + __owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, diff --git ssl/t1_enc.c ssl/t1_enc.c -index c85c0b0310..9e988ab321 100644 +index c85c0b0310..d461421068 100644 --- ssl/t1_enc.c +++ ssl/t1_enc.c @@ -10,10 +10,14 @@ @@ -1738,7 +2168,7 @@ /* seed1 through seed5 are concatenated */ static int tls1_PRF(SSL *s, -@@ -78,6 +82,39 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) +@@ -78,6 +82,41 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) return ret; } @@ -1750,6 +2180,7 @@ + * record layer. If read_ahead is enabled, then this might be false and this + * function will fail. + */ ++# ifndef OPENSSL_NO_KTLS_RX +static int count_unprocessed_records(SSL *s) +{ + SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); @@ -1773,21 +2204,21 @@ + + return count; +} ++# endif +#endif + int tls1_change_cipher_state(SSL *s, int which) { unsigned char *p, *mac_secret; -@@ -94,6 +131,17 @@ int tls1_change_cipher_state(SSL *s, int which) +@@ -94,6 +133,16 @@ int tls1_change_cipher_state(SSL *s, int which) EVP_PKEY *mac_key; size_t n, i, j, k, cl; int reuse_dd = 0; +#ifndef OPENSSL_NO_KTLS -+# ifdef __FreeBSD__ -+ struct tls_enable crypto_info; -+# else -+ struct tls12_crypto_info_aes_gcm_128 crypto_info; -+ unsigned char geniv[12]; ++ ktls_crypto_info_t crypto_info; ++ unsigned char *rec_seq; ++ void *rl_sequence; ++# ifndef OPENSSL_NO_KTLS_RX + int count_unprocessed; + int bit; +# endif @@ -1796,7 +2227,7 @@ c = s->s3->tmp.new_sym_enc; m = s->s3->tmp.new_hash; -@@ -312,6 +360,138 @@ int tls1_change_cipher_state(SSL *s, int which) +@@ -312,6 +361,85 @@ int tls1_change_cipher_state(SSL *s, int which) ERR_R_INTERNAL_ERROR); goto err; } @@ -1812,56 +2243,10 @@ + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) + goto skip_ktls; + -+# ifdef __FreeBSD__ -+ memset(&crypto_info, 0, sizeof(crypto_info)); -+ switch (s->s3->tmp.new_cipher->algorithm_enc) { -+ case SSL_AES128GCM: -+ case SSL_AES256GCM: -+ crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16; -+ crypto_info.iv_len = EVP_GCM_TLS_FIXED_IV_LEN; -+ break; -+ case SSL_AES128: -+ case SSL_AES256: -+ if (s->ext.use_etm) -+ goto skip_ktls; -+ switch (s->s3->tmp.new_cipher->algorithm_mac) { -+ case SSL_SHA1: -+ crypto_info.auth_algorithm = CRYPTO_SHA1_HMAC; -+ break; -+ case SSL_SHA256: -+ crypto_info.auth_algorithm = CRYPTO_SHA2_256_HMAC; -+ break; -+ case SSL_SHA384: -+ crypto_info.auth_algorithm = CRYPTO_SHA2_384_HMAC; -+ break; -+ default: -+ goto skip_ktls; -+ } -+ crypto_info.cipher_algorithm = CRYPTO_AES_CBC; -+ crypto_info.iv_len = EVP_CIPHER_iv_length(c); -+ crypto_info.auth_key = ms; -+ crypto_info.auth_key_len = *mac_secret_size; -+ break; -+ default: ++ /* check that cipher is supported */ ++ if (!ktls_check_supported_cipher(s, c, dd)) + goto skip_ktls; -+ } -+ crypto_info.cipher_key = key; -+ crypto_info.cipher_key_len = EVP_CIPHER_key_length(c); -+ crypto_info.iv = iv; -+ crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff; -+ crypto_info.tls_vminor = (s->version & 0x000000ff); -+# else -+ /* check that cipher is AES_GCM_128 */ -+ if (EVP_CIPHER_nid(c) != NID_aes_128_gcm -+ || EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE -+ || EVP_CIPHER_key_length(c) != TLS_CIPHER_AES_GCM_128_KEY_SIZE) -+ goto skip_ktls; + -+ /* check version is 1.2 */ -+ if (s->version != TLS1_2_VERSION) -+ goto skip_ktls; -+# endif -+ + if (which & SSL3_CC_WRITE) + bio = s->wbio; + else @@ -1887,26 +2272,17 @@ + goto err; + } + -+# ifndef __FreeBSD__ -+ memset(&crypto_info, 0, sizeof(crypto_info)); -+ crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128; -+ crypto_info.info.version = s->version; -+ -+ EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, -+ EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, -+ geniv); -+ memcpy(crypto_info.iv, geniv + EVP_GCM_TLS_FIXED_IV_LEN, -+ TLS_CIPHER_AES_GCM_128_IV_SIZE); -+ memcpy(crypto_info.salt, geniv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); -+ memcpy(crypto_info.key, key, EVP_CIPHER_key_length(c)); + if (which & SSL3_CC_WRITE) -+ memcpy(crypto_info.rec_seq, &s->rlayer.write_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); ++ rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); + else -+ memcpy(crypto_info.rec_seq, &s->rlayer.read_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); ++ rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); + ++ if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq, ++ iv, key, ms, *mac_secret_size)) ++ goto skip_ktls; ++ + if (which & SSL3_CC_READ) { ++# ifndef OPENSSL_NO_KTLS_RX + count_unprocessed = count_unprocessed_records(s); + if (count_unprocessed < 0) + goto skip_ktls; @@ -1914,14 +2290,16 @@ + /* increment the crypto_info record sequence */ + while (count_unprocessed) { + for (bit = 7; bit >= 0; bit--) { /* increment */ -+ ++crypto_info.rec_seq[bit]; -+ if (crypto_info.rec_seq[bit] != 0) ++ ++rec_seq[bit]; ++ if (rec_seq[bit] != 0) + break; + } + count_unprocessed--; + } -+ } ++# else ++ goto skip_ktls; +# endif ++ } + + /* ktls works with user provided buffers directly */ + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { @@ -1935,8 +2313,223 @@ s->statem.enc_write_state = ENC_WRITE_STATE_VALID; #ifdef SSL_DEBUG +diff --git ssl/tls13_enc.c ssl/tls13_enc.c +index b8fb07f210..d9f050ee34 100644 +--- ssl/tls13_enc.c ++++ ssl/tls13_enc.c +@@ -9,6 +9,8 @@ + + #include + #include "ssl_local.h" ++#include "internal/ktls.h" ++#include "record/record_local.h" + #include "internal/cryptlib.h" + #include + #include +@@ -363,9 +365,9 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, + const unsigned char *hash, + const unsigned char *label, + size_t labellen, unsigned char *secret, +- unsigned char *iv, EVP_CIPHER_CTX *ciph_ctx) ++ unsigned char *key, unsigned char *iv, ++ EVP_CIPHER_CTX *ciph_ctx) + { +- unsigned char key[EVP_MAX_KEY_LENGTH]; + size_t ivlen, keylen, taglen; + int hashleni = EVP_MD_size(md); + size_t hashlen; +@@ -374,14 +376,14 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, + if (!ossl_assert(hashleni >= 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, + ERR_R_EVP_LIB); +- goto err; ++ return 0; + } + hashlen = (size_t)hashleni; + + if (!tls13_hkdf_expand(s, md, insecret, label, labellen, hash, hashlen, + secret, hashlen, 1)) { + /* SSLfatal() already called */ +- goto err; ++ return 0; + } + + /* TODO(size_t): convert me */ +@@ -401,7 +403,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, + ERR_R_EVP_LIB); +- goto err; ++ return 0; + } + if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) + taglen = EVP_CCM8_TLS_TAG_LEN; +@@ -415,7 +417,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, + if (!tls13_derive_key(s, md, secret, key, keylen) + || !tls13_derive_iv(s, md, secret, iv, ivlen)) { + /* SSLfatal() already called */ +- goto err; ++ return 0; + } + + if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0 +@@ -425,13 +427,10 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, + || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, + ERR_R_EVP_LIB); +- goto err; ++ return 0; + } + + return 1; +- err: +- OPENSSL_cleanse(key, sizeof(key)); +- return 0; + } + + int tls13_change_cipher_state(SSL *s, int which) +@@ -456,6 +455,7 @@ int tls13_change_cipher_state(SSL *s, int which) + static const unsigned char early_exporter_master_secret[] = "e exp master"; + #endif + unsigned char *iv; ++ unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char secret[EVP_MAX_MD_SIZE]; + unsigned char hashval[EVP_MAX_MD_SIZE]; + unsigned char *hash = hashval; +@@ -469,6 +469,10 @@ int tls13_change_cipher_state(SSL *s, int which) + int ret = 0; + const EVP_MD *md = NULL; + const EVP_CIPHER *cipher = NULL; ++#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) ++ ktls_crypto_info_t crypto_info; ++ BIO *bio; ++#endif + + if (which & SSL3_CC_READ) { + if (s->enc_read_ctx != NULL) { +@@ -671,9 +675,13 @@ int tls13_change_cipher_state(SSL *s, int which) + } + } + ++ /* check whether cipher is known */ ++ if(!ossl_assert(cipher != NULL)) ++ goto err; ++ + if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, +- insecret, hash, label, labellen, secret, iv, +- ciph_ctx)) { ++ insecret, hash, label, labellen, secret, key, ++ iv, ciph_ctx)) { + /* SSLfatal() already called */ + goto err; + } +@@ -714,8 +722,51 @@ int tls13_change_cipher_state(SSL *s, int which) + s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; + else + s->statem.enc_write_state = ENC_WRITE_STATE_VALID; ++#ifndef OPENSSL_NO_KTLS ++# if defined(OPENSSL_KTLS_TLS13) ++ if (!(which & SSL3_CC_WRITE) || !(which & SSL3_CC_APPLICATION) ++ || ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX))) ++ goto skip_ktls; ++ ++ /* ktls supports only the maximum fragment size */ ++ if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) ++ goto skip_ktls; ++ ++ /* ktls does not support record padding */ ++ if (s->record_padding_cb != NULL) ++ goto skip_ktls; ++ ++ /* check that cipher is supported */ ++ if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) ++ goto skip_ktls; ++ ++ bio = s->wbio; ++ ++ if (!ossl_assert(bio != NULL)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ ++ if (BIO_flush(bio) <= 0) ++ goto skip_ktls; ++ ++ /* configure kernel crypto structure */ ++ if (!ktls_configure_crypto(s, cipher, ciph_ctx, ++ RECORD_LAYER_get_write_sequence(&s->rlayer), ++ &crypto_info, NULL, iv, key, NULL, 0)) ++ goto skip_ktls; ++ ++ /* ktls works with user provided buffers directly */ ++ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) ++ ssl3_release_write_buffer(s); ++skip_ktls: ++# endif ++#endif + ret = 1; + err: ++ OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(secret, sizeof(secret)); + return ret; + } +@@ -729,6 +780,7 @@ int tls13_update_key(SSL *s, int sending) + #endif + const EVP_MD *md = ssl_handshake_md(s); + size_t hashlen = EVP_MD_size(md); ++ unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char *insecret, *iv; + unsigned char secret[EVP_MAX_MD_SIZE]; + EVP_CIPHER_CTX *ciph_ctx; +@@ -753,8 +805,8 @@ int tls13_update_key(SSL *s, int sending) + if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s), + s->s3->tmp.new_sym_enc, insecret, NULL, + application_traffic, +- sizeof(application_traffic) - 1, secret, iv, +- ciph_ctx)) { ++ sizeof(application_traffic) - 1, secret, key, ++ iv, ciph_ctx)) { + /* SSLfatal() already called */ + goto err; + } +@@ -764,6 +816,7 @@ int tls13_update_key(SSL *s, int sending) + s->statem.enc_write_state = ENC_WRITE_STATE_VALID; + ret = 1; + err: ++ OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(secret, sizeof(secret)); + return ret; + } +diff --git test/build.info test/build.info +index 56ac14eabd..e8454e2e03 100644 +--- test/build.info ++++ test/build.info +@@ -544,7 +544,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN + # We disable this test completely in a shared build because it deliberately + # redefines some internal libssl symbols. This doesn't work in a non-shared + # build +- IF[{- !$disabled{shared} -}] ++ IF[{- !$disabled{shared} && $disabled{ktls} -}] + PROGRAMS_NO_INST=tls13secretstest + SOURCE[tls13secretstest]=tls13secretstest.c + SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../ssl/packet.c +diff --git test/recipes/90-test_tls13secrets.t test/recipes/90-test_tls13secrets.t +index 5490885309..3478e540ed 100644 +--- test/recipes/90-test_tls13secrets.t ++++ test/recipes/90-test_tls13secrets.t +@@ -13,7 +13,7 @@ my $test_name = "tls13secrets"; + setup($test_name); + + plan skip_all => "$test_name is not supported in this build" +- if disabled("tls1_3") || disabled("shared"); ++ if disabled("tls1_3") || disabled("shared") || !disabled("ktls"); + + plan tests => 1; + diff --git test/sslapitest.c test/sslapitest.c -index 5c118108ef..98b8574aba 100644 +index ad1824c68d..f6a61cab4e 100644 --- test/sslapitest.c +++ test/sslapitest.c @@ -7,6 +7,7 @@ @@ -1961,13 +2554,13 @@ #include "../ssl/ssl_local.h" #ifndef OPENSSL_NO_TLS1_3 -@@ -779,6 +782,406 @@ static int execute_test_large_message(const SSL_METHOD *smeth, +@@ -779,6 +782,409 @@ static int execute_test_large_message(const SSL_METHOD *smeth, return testresult; } -+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ -+ && !defined(OPENSSL_NO_SOCK) -+ ++#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_KTLS) && \ ++ !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_TLS1_2)) ++#define TLS_CIPHER_MAX_REC_SEQ_SIZE 8 +/* sock must be connected */ +static int ktls_chk_platform(int sock) +{ @@ -1976,30 +2569,26 @@ + return 1; +} + -+static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) ++static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd, int rec_seq_size) +{ + static char count = 1; + unsigned char cbuf[16000] = {0}; + unsigned char sbuf[16000]; + size_t err = 0; -+ char crec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char crec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char crec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char crec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char srec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char srec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char srec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -+ char srec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; ++ char crec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char crec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char crec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char crec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char srec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char srec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char srec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; ++ char srec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + + cbuf[0] = count++; -+ memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); -+ memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); -+ memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); -+ memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); ++ memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, rec_seq_size); ++ memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, rec_seq_size); ++ memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, rec_seq_size); ++ memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, rec_seq_size); + + if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf))) + goto end; @@ -2019,14 +2608,10 @@ + } + } + -+ memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); -+ memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); -+ memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); -+ memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, -+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); ++ memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, rec_seq_size); ++ memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, rec_seq_size); ++ memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, rec_seq_size); ++ memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, rec_seq_size); + + /* verify the payload */ + if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf))) @@ -2034,42 +2619,42 @@ + + /* ktls is used then kernel sequences are used instead of OpenSSL sequences */ + if (clientssl->mode & SSL_MODE_NO_KTLS_TX) { -+ if (!TEST_mem_ne(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_ne(crec_wseq_before, rec_seq_size, ++ crec_wseq_after, rec_seq_size)) + goto end; + } else { -+ if (!TEST_mem_eq(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_eq(crec_wseq_before, rec_seq_size, ++ crec_wseq_after, rec_seq_size)) + goto end; + } + + if (serverssl->mode & SSL_MODE_NO_KTLS_TX) { -+ if (!TEST_mem_ne(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_ne(srec_wseq_before, rec_seq_size, ++ srec_wseq_after, rec_seq_size)) + goto end; + } else { -+ if (!TEST_mem_eq(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_eq(srec_wseq_before, rec_seq_size, ++ srec_wseq_after, rec_seq_size)) + goto end; + } + + if (clientssl->mode & SSL_MODE_NO_KTLS_RX) { -+ if (!TEST_mem_ne(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_ne(crec_rseq_before, rec_seq_size, ++ crec_rseq_after, rec_seq_size)) + goto end; + } else { -+ if (!TEST_mem_eq(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_eq(crec_rseq_before, rec_seq_size, ++ crec_rseq_after, rec_seq_size)) + goto end; + } + + if (serverssl->mode & SSL_MODE_NO_KTLS_RX) { -+ if (!TEST_mem_ne(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_ne(srec_rseq_before, rec_seq_size, ++ srec_rseq_after, rec_seq_size)) + goto end; + } else { -+ if (!TEST_mem_eq(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, -+ srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) ++ if (!TEST_mem_eq(srec_rseq_before, rec_seq_size, ++ srec_rseq_after, rec_seq_size)) + goto end; + } + @@ -2079,7 +2664,9 @@ +} + +static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, -+ int sis_ktls_tx, int sis_ktls_rx) ++ int sis_ktls_tx, int sis_ktls_rx, ++ int tls_version, const char *cipher, ++ int rec_seq_size) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; @@ -2096,10 +2683,10 @@ + /* Create a session based on SHA-256 */ + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), -+ TLS1_2_VERSION, TLS1_2_VERSION, ++ tls_version, tls_version, + &sctx, &cctx, cert, privkey)) -+ || !TEST_true(SSL_CTX_set_cipher_list(cctx, -+ "AES128-GCM-SHA256")) ++ || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) ++ || !TEST_true(SSL_CTX_set_cipher_list(sctx, cipher)) + || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, + &clientssl, sfd, cfd))) + goto end; @@ -2160,7 +2747,8 @@ + goto end; + } + -+ if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd))) ++ if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd, ++ rec_seq_size))) + goto end; + + testresult = 1; @@ -2183,7 +2771,7 @@ +#define SENDFILE_CHUNK (4 * 4096) +#define min(a,b) ((a) > (b) ? (b) : (a)) + -+static int test_ktls_sendfile(void) ++static int test_ktls_sendfile(int tls_version, const char *cipher) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; @@ -2210,10 +2798,10 @@ + /* Create a session based on SHA-256 */ + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), -+ TLS1_2_VERSION, TLS1_2_VERSION, ++ tls_version, tls_version, + &sctx, &cctx, cert, privkey)) -+ || !TEST_true(SSL_CTX_set_cipher_list(cctx, -+ "AES128-GCM-SHA256")) ++ || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) ++ || !TEST_true(SSL_CTX_set_cipher_list(sctx, cipher)) + || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, + &clientssl, sfd, cfd))) + goto end; @@ -2284,114 +2872,108 @@ + return testresult; +} + -+static int test_ktls_no_txrx_client_no_txrx_server(void) ++#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) ++static int test_ktls(int test) +{ -+ return execute_test_ktls(0, 0, 0, 0); -+} ++ int cis_ktls_tx, cis_ktls_rx, sis_ktls_tx, sis_ktls_rx; ++ int tlsver, testresult; + -+static int test_ktls_no_rx_client_no_txrx_server(void) -+{ -+ return execute_test_ktls(1, 0, 0, 0); -+} ++ if (test > 15) { ++#if defined(OPENSSL_NO_TLS1_3) ++ return 1; ++#else ++ test -= 16; ++ tlsver = TLS1_3_VERSION; ++#endif ++ } else { ++#if defined(OPENSSL_NO_TLS1_2) ++ return 1; ++#else ++ tlsver = TLS1_2_VERSION; ++#endif ++ } + -+static int test_ktls_no_tx_client_no_txrx_server(void) -+{ -+ return execute_test_ktls(0, 1, 0, 0); -+} ++ cis_ktls_tx = (test & 1) != 0; ++ cis_ktls_rx = (test & 2) != 0; ++ sis_ktls_tx = (test & 4) != 0; ++ sis_ktls_rx = (test & 8) != 0; + -+static int test_ktls_client_no_txrx_server(void) -+{ -+ return execute_test_ktls(1, 1, 0, 0); -+} ++#if defined(OPENSSL_NO_KTLS_RX) ++ if (cis_ktls_rx || sis_ktls_rx) ++ return 1; ++#endif ++#if !defined(OPENSSL_NO_TLS1_3) ++ if (tlsver == TLS1_3_VERSION && (cis_ktls_rx || sis_ktls_rx)) ++ return 1; ++#endif + -+static int test_ktls_no_txrx_client_no_rx_server(void) -+{ -+ return execute_test_ktls(0, 0, 1, 0); ++ testresult = 1; ++#ifdef OPENSSL_KTLS_AES_GCM_128 ++ testresult &= execute_test_ktls(cis_ktls_tx, cis_ktls_rx, sis_ktls_tx, ++ sis_ktls_rx, tlsver, "AES128-GCM-SHA256", ++ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); ++#endif ++#ifdef OPENSSL_KTLS_AES_CCM_128 ++ testresult &= execute_test_ktls(cis_ktls_tx, cis_ktls_rx, sis_ktls_tx, ++ sis_ktls_rx, tlsver, "AES128-CCM", ++ TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); ++#endif ++#ifdef OPENSSL_KTLS_AES_GCM_256 ++ testresult &= execute_test_ktls(cis_ktls_tx, cis_ktls_rx, sis_ktls_tx, ++ sis_ktls_rx, tlsver, "AES256-GCM-SHA384", ++ TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); ++#endif ++ return testresult; +} + -+static int test_ktls_no_rx_client_no_rx_server(void) ++static int test_ktls_sendfile_anytls(int tst) +{ -+ return execute_test_ktls(1, 0, 1, 0); -+} ++ char *cipher[] = {"AES128-GCM-SHA256","AES128-CCM","AES256-GCM-SHA384"}; ++ int tlsver; + -+static int test_ktls_no_tx_client_no_rx_server(void) -+{ -+ return execute_test_ktls(0, 1, 1, 0); -+} ++ if (tst > 2) { ++#if defined(OPENSSL_NO_TLS1_3) ++ return 1; ++#else ++ tst -= 3; ++ tlsver = TLS1_3_VERSION; ++#endif ++ } else { ++#if defined(OPENSSL_NO_TLS1_2) ++ return 1; ++#else ++ tlsver = TLS1_2_VERSION; ++#endif ++ } + -+static int test_ktls_client_no_rx_server(void) -+{ -+ return execute_test_ktls(1, 1, 1, 0); ++#ifndef OPENSSL_KTLS_AES_GCM_128 ++ if(tst == 0) return 1; ++#endif ++#ifndef OPENSSL_KTLS_AES_CCM_128 ++ if(tst == 1) return 1; ++#endif ++#ifndef OPENSSL_KTLS_AES_GCM_256 ++ if(tst == 2) return 1; ++#endif ++ return test_ktls_sendfile(tlsver, cipher[tst]); +} + -+static int test_ktls_no_txrx_client_no_tx_server(void) -+{ -+ return execute_test_ktls(0, 0, 0, 1); -+} -+ -+static int test_ktls_no_rx_client_no_tx_server(void) -+{ -+ return execute_test_ktls(1, 0, 0, 1); -+} -+ -+static int test_ktls_no_tx_client_no_tx_server(void) -+{ -+ return execute_test_ktls(0, 1, 0, 1); -+} -+ -+static int test_ktls_client_no_tx_server(void) -+{ -+ return execute_test_ktls(1, 1, 0, 1); -+} -+ -+static int test_ktls_no_txrx_client_server(void) -+{ -+ return execute_test_ktls(0, 0, 1, 1); -+} -+ -+static int test_ktls_no_rx_client_server(void) -+{ -+ return execute_test_ktls(1, 0, 1, 1); -+} -+ -+static int test_ktls_no_tx_client_server(void) -+{ -+ return execute_test_ktls(0, 1, 1, 1); -+} -+ -+static int test_ktls_client_server(void) -+{ -+ return execute_test_ktls(1, 1, 1, 1); -+} +#endif ++#endif + static int test_large_message_tls(void) { return execute_test_large_message(TLS_server_method(), TLS_client_method(), -@@ -6504,6 +6907,26 @@ int setup_tests(void) +@@ -6691,6 +7097,12 @@ int setup_tests(void) return 0; } -+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ -+ && !defined(OPENSSL_NO_SOCK) -+ ADD_TEST(test_ktls_no_txrx_client_no_txrx_server); -+ ADD_TEST(test_ktls_no_rx_client_no_txrx_server); -+ ADD_TEST(test_ktls_no_tx_client_no_txrx_server); -+ ADD_TEST(test_ktls_client_no_txrx_server); -+ ADD_TEST(test_ktls_no_txrx_client_no_rx_server); -+ ADD_TEST(test_ktls_no_rx_client_no_rx_server); -+ ADD_TEST(test_ktls_no_tx_client_no_rx_server); -+ ADD_TEST(test_ktls_client_no_rx_server); -+ ADD_TEST(test_ktls_no_txrx_client_no_tx_server); -+ ADD_TEST(test_ktls_no_rx_client_no_tx_server); -+ ADD_TEST(test_ktls_no_tx_client_no_tx_server); -+ ADD_TEST(test_ktls_client_no_tx_server); -+ ADD_TEST(test_ktls_no_txrx_client_server); -+ ADD_TEST(test_ktls_no_rx_client_server); -+ ADD_TEST(test_ktls_no_tx_client_server); -+ ADD_TEST(test_ktls_client_server); -+ ADD_TEST(test_ktls_sendfile); ++#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) ++#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) ++ ADD_ALL_TESTS(test_ktls, 32); ++ ADD_ALL_TESTS(test_ktls_sendfile_anytls, 6); +#endif ++#endif ADD_TEST(test_large_message_tls); ADD_TEST(test_large_message_tls_read_ahead); #ifndef OPENSSL_NO_DTLS @@ -2564,4 +3146,4 @@ +BIO_get_ktls_recv define BIO_get_conn_address define BIO_get_conn_hostname define - BIO_get_conn_port definE + BIO_get_conn_port define