Changeset View
Changeset View
Standalone View
Standalone View
head/security/openssl/files/extra-patch-ktls
diff --git CHANGES CHANGES | diff --git CHANGES CHANGES | ||||
index f4230aaac0..3cc665f654 100644 | index 7ea3d2b823..514cf091a3 100644 | ||||
--- CHANGES | --- CHANGES | ||||
+++ CHANGES | +++ CHANGES | ||||
@@ -306,6 +306,11 @@ | @@ -354,6 +354,11 @@ | ||||
necessary to configure just to create a source distribution. | necessary to configure just to create a source distribution. | ||||
[Richard Levitte] | [Richard Levitte] | ||||
+ *) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path | + *) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path | ||||
+ improves application performance by removing data copies and providing | + improves application performance by removing data copies and providing | ||||
+ applications with zero-copy system calls such as sendfile and splice. | + applications with zero-copy system calls such as sendfile and splice. | ||||
+ [Boris Pismenny] | + [Boris Pismenny] | ||||
+ | + | ||||
Changes between 1.1.1 and 1.1.1a [20 Nov 2018] | Changes between 1.1.1 and 1.1.1a [20 Nov 2018] | ||||
*) Timing vulnerability in DSA signature generation | *) Timing vulnerability in DSA signature generation | ||||
diff --git Configure Configure | diff --git Configure Configure | ||||
index 2e9efaa5f3..524b58cbb9 100755 | index 1d73d06e1b..29e655da96 100755 | ||||
--- Configure | --- Configure | ||||
+++ 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 | # For developers: keep it sorted alphabetically | ||||
my @disablables = ( | my @disablables = ( | ||||
+ "ktls", | + "ktls", | ||||
"afalgeng", | "afalgeng", | ||||
"aria", | "aria", | ||||
"asan", | "asan", | ||||
@@ -464,6 +465,7 @@ our %disabled = ( # "what" => "comment" | @@ -474,6 +475,7 @@ our %disabled = ( # "what" => "comment" | ||||
"weak-ssl-ciphers" => "default", | "weak-ssl-ciphers" => "default", | ||||
"zlib" => "default", | "zlib" => "default", | ||||
"zlib-dynamic" => "default", | "zlib-dynamic" => "default", | ||||
+ "ktls" => "default", | + "ktls" => "default", | ||||
); | ); | ||||
# Note: => pair form used for aesthetics, not to truly make a hash table | # 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}) { | ||||
} | } | ||||
} | } | ||||
+unless ($disabled{ktls}) { | +unless ($disabled{ktls}) { | ||||
+ $config{ktls}=""; | + $config{ktls}=""; | ||||
+ if ($target =~ m/^linux/) { | + if ($target =~ m/^linux/) { | ||||
+ my $usr = "/usr/$config{cross_compile_prefix}"; | + my $usr = "/usr/$config{cross_compile_prefix}"; | ||||
+ chop($usr); | + chop($usr); | ||||
Show All 18 Lines | |||||
+} | +} | ||||
+ | + | ||||
+push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls}); | +push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls}); | ||||
+ | + | ||||
# Get the extra flags used when building shared libraries and modules. We | # Get the extra flags used when building shared libraries and modules. We | ||||
# do this late because some of them depend on %disabled. | # do this late because some of them depend on %disabled. | ||||
diff --git INSTALL INSTALL | diff --git INSTALL INSTALL | ||||
index 328ad2baf4..46735b8236 100644 | index f5118428b3..be84f2aa8e 100644 | ||||
--- INSTALL | --- INSTALL | ||||
+++ INSTALL | +++ INSTALL | ||||
@@ -262,6 +262,15 @@ | @@ -262,6 +262,15 @@ | ||||
Don't build the AFALG engine. This option will be forced if | Don't build the AFALG engine. This option will be forced if | ||||
on a platform that does not support AFALG. | on a platform that does not support AFALG. | ||||
+ enable-ktls | + enable-ktls | ||||
+ Build with Kernel TLS support. This option will enable the | + Build with Kernel TLS support. This option will enable the | ||||
+ use of the Kernel TLS data-path, which can improve | + use of the Kernel TLS data-path, which can improve | ||||
+ performance and allow for the use of sendfile and splice | + performance and allow for the use of sendfile and splice | ||||
+ system calls on TLS sockets. The Kernel may use TLS | + system calls on TLS sockets. The Kernel may use TLS | ||||
+ accelerators if any are available on the system. | + accelerators if any are available on the system. | ||||
+ This option will be forced off on systems that do not support | + This option will be forced off on systems that do not support | ||||
+ the Kernel TLS data-path. | + the Kernel TLS data-path. | ||||
+ | + | ||||
enable-asan | enable-asan | ||||
Build with the Address sanitiser. This is a developer option | Build with the Address sanitiser. This is a developer option | ||||
only. It may not work on all platforms and should never be | only. It may not work on all platforms and should never be | ||||
diff --git apps/s_client.c apps/s_client.c | 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 | ||||
+++ 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", | BIO_printf(bio, "Expansion: %s\n", | ||||
expansion ? SSL_COMP_get_name(expansion) : "NONE"); | expansion ? SSL_COMP_get_name(expansion) : "NONE"); | ||||
#endif | #endif | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (BIO_get_ktls_send(SSL_get_wbio(s))) | + if (BIO_get_ktls_send(SSL_get_wbio(s))) | ||||
+ BIO_printf(bio_err, "Using Kernel TLS for sending\n"); | + BIO_printf(bio_err, "Using Kernel TLS for sending\n"); | ||||
+ if (BIO_get_ktls_recv(SSL_get_rbio(s))) | + if (BIO_get_ktls_recv(SSL_get_rbio(s))) | ||||
+ BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); | + BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
+ */ | + */ | ||||
+ ktls_enable(sock); | + ktls_enable(sock); | ||||
+ } | + } | ||||
+# endif | +# endif | ||||
return sock; | return sock; | ||||
} | } | ||||
diff --git crypto/bio/bss_conn.c crypto/bio/bss_conn.c | 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 | ||||
+++ crypto/bio/bss_conn.c | +++ crypto/bio/bss_conn.c | ||||
@@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||||
#include <errno.h> | #include <errno.h> | ||||
#include "bio_local.h" | #include "bio_local.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
#ifndef OPENSSL_NO_SOCK | #ifndef OPENSSL_NO_SOCK | ||||
@@ -20,6 +21,9 @@ typedef struct bio_connect_st { | @@ -20,6 +21,9 @@ typedef struct bio_connect_st { | ||||
char *param_hostname; | char *param_hostname; | ||||
char *param_service; | char *param_service; | ||||
int connect_mode; | int connect_mode; | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+ unsigned char record_type; | + unsigned char record_type; | ||||
+# endif | +# endif | ||||
BIO_ADDRINFO *addr_first; | BIO_ADDRINFO *addr_first; | ||||
const BIO_ADDRINFO *addr_iter; | 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) { | if (out != NULL) { | ||||
clear_socket_error(); | clear_socket_error(); | ||||
- ret = readsocket(b->num, out, outl); | - ret = readsocket(b->num, out, outl); | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+ if (BIO_get_ktls_recv(b)) | + if (BIO_get_ktls_recv(b)) | ||||
+ ret = ktls_read_record(b->num, out, outl); | + ret = ktls_read_record(b->num, out, outl); | ||||
+ else | + else | ||||
+# endif | +# endif | ||||
+ ret = readsocket(b->num, out, outl); | + ret = readsocket(b->num, out, outl); | ||||
BIO_clear_retry_flags(b); | BIO_clear_retry_flags(b); | ||||
if (ret <= 0) { | if (ret <= 0) { | ||||
if (BIO_sock_should_retry(ret)) | 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(); | clear_socket_error(); | ||||
- ret = writesocket(b->num, in, inl); | - ret = writesocket(b->num, in, inl); | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+ if (BIO_should_ktls_ctrl_msg_flag(b)) { | + if (BIO_should_ktls_ctrl_msg_flag(b)) { | ||||
+ ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl); | + ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl); | ||||
+ if (ret >= 0) { | + if (ret >= 0) { | ||||
+ ret = inl; | + ret = inl; | ||||
+ BIO_clear_ktls_ctrl_msg_flag(b); | + BIO_clear_ktls_ctrl_msg_flag(b); | ||||
+ } | + } | ||||
+ } else | + } else | ||||
+# endif | +# endif | ||||
+ ret = writesocket(b->num, in, inl); | + ret = writesocket(b->num, in, inl); | ||||
BIO_clear_retry_flags(b); | BIO_clear_retry_flags(b); | ||||
if (ret <= 0) { | if (ret <= 0) { | ||||
if (BIO_sock_should_retry(ret)) | 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; | const char **pptr = NULL; | ||||
long ret = 1; | long ret = 1; | ||||
BIO_CONNECT *data; | BIO_CONNECT *data; | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+# ifdef __FreeBSD__ | +# ifdef __FreeBSD__ | ||||
+ struct tls_enable *crypto_info; | + struct tls_enable *crypto_info; | ||||
+# else | +# else | ||||
+ struct tls12_crypto_info_aes_gcm_128 *crypto_info; | + struct tls12_crypto_info_aes_gcm_128 *crypto_info; | ||||
+# endif | +# endif | ||||
+# endif | +# endif | ||||
data = (BIO_CONNECT *)b->ptr; | 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: | case BIO_CTRL_EOF: | ||||
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; | ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; | ||||
break; | break; | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+ case BIO_CTRL_SET_KTLS: | + case BIO_CTRL_SET_KTLS: | ||||
+# ifdef __FreeBSD__ | +# ifdef __FreeBSD__ | ||||
+ crypto_info = (struct tls_enable *)ptr; | + crypto_info = (struct tls_enable *)ptr; | ||||
+# else | +# else | ||||
Show All 16 Lines | |||||
+ BIO_clear_ktls_ctrl_msg_flag(b); | + BIO_clear_ktls_ctrl_msg_flag(b); | ||||
+ ret = 0; | + ret = 0; | ||||
+ break; | + break; | ||||
+# endif | +# endif | ||||
default: | default: | ||||
ret = 0; | ret = 0; | ||||
break; | break; | ||||
diff --git crypto/bio/bss_sock.c crypto/bio/bss_sock.c | 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 | ||||
+++ crypto/bio/bss_sock.c | +++ crypto/bio/bss_sock.c | ||||
@@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||||
#include <errno.h> | #include <errno.h> | ||||
#include "bio_local.h" | #include "bio_local.h" | ||||
#include "internal/cryptlib.h" | #include "internal/cryptlib.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
+ BIO_clear_ktls_ctrl_msg_flag(b); | + BIO_clear_ktls_ctrl_msg_flag(b); | ||||
+ } | + } | ||||
+ } else | + } else | ||||
+# endif | +# endif | ||||
+ ret = writesocket(b->num, in, inl); | + ret = writesocket(b->num, in, inl); | ||||
BIO_clear_retry_flags(b); | BIO_clear_retry_flags(b); | ||||
if (ret <= 0) { | if (ret <= 0) { | ||||
if (BIO_sock_should_retry(ret)) | 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; | long ret = 1; | ||||
int *ip; | int *ip; | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+ size_t crypto_info_len; | |||||
+# ifdef __FreeBSD__ | +# ifdef __FreeBSD__ | ||||
+ struct tls_enable *crypto_info; | + struct tls_enable *crypto_info; | ||||
+# else | +# else | ||||
+ struct tls12_crypto_info_aes_gcm_128 *crypto_info; | + struct tls_crypto_info_all *crypto_info; | ||||
+# endif | +# endif | ||||
+# endif | +# endif | ||||
switch (cmd) { | switch (cmd) { | ||||
case BIO_C_SET_FD: | 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: | case BIO_CTRL_FLUSH: | ||||
ret = 1; | ret = 1; | ||||
break; | break; | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+ case BIO_CTRL_SET_KTLS: | + case BIO_CTRL_SET_KTLS: | ||||
+# ifdef __FreeBSD__ | +# ifdef __FreeBSD__ | ||||
+ crypto_info = (struct tls_enable *)ptr; | + crypto_info = (struct tls_enable *)ptr; | ||||
+ crypto_info_len = sizeof(*crypto_info); | |||||
+# else | +# 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 | +# 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) | + if (ret) | ||||
+ BIO_set_ktls_flag(b, num); | + BIO_set_ktls_flag(b, num); | ||||
+ break; | + break; | ||||
+ case BIO_CTRL_GET_KTLS_SEND: | + case BIO_CTRL_GET_KTLS_SEND: | ||||
+ return BIO_should_ktls_flag(b, 1); | + return BIO_should_ktls_flag(b, 1); | ||||
+ case BIO_CTRL_GET_KTLS_RECV: | + case BIO_CTRL_GET_KTLS_RECV: | ||||
+ return BIO_should_ktls_flag(b, 0); | + return BIO_should_ktls_flag(b, 0); | ||||
+ case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG: | + case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG: | ||||
+ BIO_set_ktls_ctrl_msg_flag(b); | + BIO_set_ktls_ctrl_msg_flag(b); | ||||
+ b->ptr = (void *)num; | + b->ptr = (void *)num; | ||||
+ ret = 0; | + ret = 0; | ||||
+ break; | + break; | ||||
+ case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG: | + case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG: | ||||
+ BIO_clear_ktls_ctrl_msg_flag(b); | + BIO_clear_ktls_ctrl_msg_flag(b); | ||||
+ ret = 0; | + ret = 0; | ||||
+ break; | + break; | ||||
+# endif | +# endif | ||||
case BIO_CTRL_EOF: | case BIO_CTRL_EOF: | ||||
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; | ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; | ||||
break; | break; | ||||
diff --git crypto/err/openssl.txt crypto/err/openssl.txt | 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 | ||||
+++ 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_RENEGOTIATE_ABBREVIATED:546:SSL_renegotiate_abbreviated | ||||
SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:* | SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:* | ||||
SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:* | SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:* | ||||
+SSL_F_SSL_SENDFILE:639:SSL_sendfile | +SSL_F_SSL_SENDFILE:639:SSL_sendfile | ||||
SSL_F_SSL_SESSION_DUP:348:ssl_session_dup | SSL_F_SSL_SESSION_DUP:348:ssl_session_dup | ||||
SSL_F_SSL_SESSION_NEW:189:SSL_SESSION_new | SSL_F_SSL_SESSION_NEW:189:SSL_SESSION_new | ||||
SSL_F_SSL_SESSION_PRINT_FP:190:SSL_SESSION_print_fp | SSL_F_SSL_SESSION_PRINT_FP:190:SSL_SESSION_print_fp | ||||
diff --git crypto/evp/e_aes.c crypto/evp/e_aes.c | diff --git crypto/evp/e_aes.c crypto/evp/e_aes.c | ||||
Show All 11 Lines | |||||
+ return 0; | + return 0; | ||||
+ memcpy(ptr, gctx->iv, arg); | + memcpy(ptr, gctx->iv, arg); | ||||
+ return 1; | + return 1; | ||||
+ | + | ||||
case EVP_CTRL_GCM_SET_IV_FIXED: | case EVP_CTRL_GCM_SET_IV_FIXED: | ||||
/* Special case: -1 length restores whole IV */ | /* Special case: -1 length restores whole IV */ | ||||
if (arg == -1) { | if (arg == -1) { | ||||
diff --git doc/man3/BIO_ctrl.pod doc/man3/BIO_ctrl.pod | 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 | ||||
+++ doc/man3/BIO_ctrl.pod | +++ doc/man3/BIO_ctrl.pod | ||||
@@ -5,7 +5,8 @@ | @@ -5,7 +5,8 @@ | ||||
BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset, | BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset, | ||||
BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close, | BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close, | ||||
BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending, | BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending, | ||||
-BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb | -BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb | ||||
+BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, BIO_get_ktls_send, | +BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, BIO_get_ktls_send, | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
+=head1 HISTORY | +=head1 HISTORY | ||||
+ | + | ||||
+The BIO_get_ktls_send() and BIO_get_ktls_recv() functions were added in | +The BIO_get_ktls_send() and BIO_get_ktls_recv() functions were added in | ||||
+OpenSSL 3.0.0. | +OpenSSL 3.0.0. | ||||
+ | + | ||||
=head1 COPYRIGHT | =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 | 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 | ||||
+++ 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 | @@ -114,6 +114,22 @@ enables this behaviour to allow interoperability with such broken | ||||
implementations. Please note that setting this option breaks interoperability | implementations. Please note that setting this option breaks interoperability | ||||
with correct implementations. This option only applies to DTLS over SCTP. | with correct implementations. This option only applies to DTLS over SCTP. | ||||
+=item SSL_MODE_NO_KTLS_TX | +=item SSL_MODE_NO_KTLS_TX | ||||
+ | + | ||||
Show All 17 Lines | |||||
@@ -134,6 +150,7 @@ L<SSL_write(3)>, L<SSL_get_error(3)> | @@ -134,6 +150,7 @@ L<SSL_write(3)>, L<SSL_get_error(3)> | ||||
=head1 HISTORY | =head1 HISTORY | ||||
SSL_MODE_ASYNC was added in OpenSSL 1.1.0. | SSL_MODE_ASYNC was added in OpenSSL 1.1.0. | ||||
+SSL_MODE_NO_KTLS_TX was first added to OpenSSL 3.0.0. | +SSL_MODE_NO_KTLS_TX was first added to OpenSSL 3.0.0. | ||||
=head1 COPYRIGHT | =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 <openssl/ssl.h> | |||||
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<cb> to specify the padding | |||||
for TLS 1.3 records. The value set in B<ctx> 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<arg> 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<ssl(7)>, L<SSL_new(3)> | |||||
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 | 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 | ||||
+++ doc/man3/SSL_write.pod | +++ doc/man3/SSL_write.pod | ||||
@@ -2,12 +2,13 @@ | @@ -2,12 +2,13 @@ | ||||
=head1 NAME | =head1 NAME | ||||
-SSL_write_ex, SSL_write - write bytes to a TLS/SSL connection | -SSL_write_ex, SSL_write - write bytes to a TLS/SSL connection | ||||
+SSL_write_ex, SSL_write, SSL_sendfile - write bytes to a TLS/SSL connection | +SSL_write_ex, SSL_write, SSL_sendfile - write bytes to a TLS/SSL connection | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | |||||
+# define BIO_set_ktls_ctrl_msg(b, record_type) \ | +# define BIO_set_ktls_ctrl_msg(b, record_type) \ | ||||
+ BIO_ctrl(b, BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG, record_type, NULL) | + BIO_ctrl(b, BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG, record_type, NULL) | ||||
+# define BIO_clear_ktls_ctrl_msg(b) \ | +# define BIO_clear_ktls_ctrl_msg(b) \ | ||||
+ BIO_ctrl(b, BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG, 0, NULL) | + BIO_ctrl(b, BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG, 0, NULL) | ||||
+ | + | ||||
+#endif | +#endif | ||||
diff --git include/internal/ktls.h include/internal/ktls.h | diff --git include/internal/ktls.h include/internal/ktls.h | ||||
new file mode 100644 | new file mode 100644 | ||||
index 0000000000..209dff1689 | index 0000000000..3baa63f781 | ||||
--- /dev/null | --- /dev/null | ||||
+++ include/internal/ktls.h | +++ include/internal/ktls.h | ||||
@@ -0,0 +1,345 @@ | @@ -0,0 +1,432 @@ | ||||
+/* | +/* | ||||
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. | + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. | ||||
+ * | + * | ||||
+ * Licensed under the Apache License 2.0 (the "License"). You may not use | + * 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 | + * this file except in compliance with the License. You can obtain a copy | ||||
+ * in the file LICENSE in the source distribution or at | + * in the file LICENSE in the source distribution or at | ||||
+ * https://www.openssl.org/source/license.html | + * https://www.openssl.org/source/license.html | ||||
+ */ | + */ | ||||
+ | + | ||||
+#if defined(OPENSSL_SYS_LINUX) | |||||
+#ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+# include <linux/version.h> | |||||
+# 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 | +#ifndef HEADER_INTERNAL_KTLS | ||||
+# define HEADER_INTERNAL_KTLS | +# define HEADER_INTERNAL_KTLS | ||||
+# ifndef OPENSSL_NO_KTLS | |||||
+ | + | ||||
+# if defined(__FreeBSD__) | +# if defined(__FreeBSD__) | ||||
+# include <sys/types.h> | +# include <sys/types.h> | ||||
+# include <sys/socket.h> | +# include <sys/socket.h> | ||||
+# include <sys/ktls.h> | +# include <sys/ktls.h> | ||||
+# include <netinet/in.h> | +# include <netinet/in.h> | ||||
+# include <netinet/tcp.h> | +# include <netinet/tcp.h> | ||||
+# include <crypto/cryptodev.h> | +# 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. | + * Only used by the tests in sslapitest.c. | ||||
+ */ | + */ | ||||
+# define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 | +# 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 | + * FreeBSD does not require any additional steps to enable KTLS before | ||||
+ * setting keys. | + * setting keys. | ||||
+ */ | + */ | ||||
+static ossl_inline int ktls_enable(int fd) | +static ossl_inline int ktls_enable(int fd) | ||||
+{ | +{ | ||||
+ return 1; | + return 1; | ||||
+} | +} | ||||
+ | + | ||||
+/* | +/* | ||||
+ * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer | + * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer | ||||
+ * as using TLS. If successful, then data sent using this socket will | + * 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. | + * 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, | +static ossl_inline int ktls_start(int fd, | ||||
+ struct tls_enable *tls_en, | + void *tls_en, | ||||
+ size_t len, int is_tx) | + size_t len, int is_tx) | ||||
+{ | +{ | ||||
+ if (is_tx) | + if (is_tx) | ||||
+ return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, | + return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, | ||||
+ tls_en, sizeof(*tls_en)) ? 0 : 1; | + tls_en, len) ? 0 : 1; | ||||
+ else | +# ifndef OPENSSL_NO_KTLS_RX | ||||
+ return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, len) ? 0 : 1; | |||||
+# else | |||||
+ return 0; | + return 0; | ||||
+# endif | |||||
+} | +} | ||||
+ | + | ||||
+/* | +/* | ||||
+ * Send a TLS record using the tls_en provided in ktls_start and use | + * Send a TLS record using the tls_en provided in ktls_start and use | ||||
+ * record_type instead of the default SSL3_RT_APPLICATION_DATA. | + * record_type instead of the default SSL3_RT_APPLICATION_DATA. | ||||
+ * When the socket is non-blocking, then this call either returns EAGAIN or | + * When the socket is non-blocking, then this call either returns EAGAIN or | ||||
+ * the entire record is pushed to TCP. It is impossible to send a partial | + * the entire record is pushed to TCP. It is impossible to send a partial | ||||
+ * record using this control message. | + * record using this control message. | ||||
Show All 19 Lines | |||||
+ msg_iov.iov_base = (void *)data; | + msg_iov.iov_base = (void *)data; | ||||
+ msg_iov.iov_len = length; | + msg_iov.iov_len = length; | ||||
+ msg.msg_iov = &msg_iov; | + msg.msg_iov = &msg_iov; | ||||
+ msg.msg_iovlen = 1; | + msg.msg_iovlen = 1; | ||||
+ | + | ||||
+ return sendmsg(fd, &msg, 0); | + return sendmsg(fd, &msg, 0); | ||||
+} | +} | ||||
+ | + | ||||
+# ifdef OPENSSL_NO_KTLS_RX | |||||
+ | |||||
+static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | ||||
+{ | +{ | ||||
+ return -1; | + return -1; | ||||
+} | +} | ||||
+ | + | ||||
+# else /* !defined(OPENSSL_NO_KTLS_RX) */ | |||||
+ | |||||
+/* | +/* | ||||
+ * KTLS enables the sendfile system call to send data from a file over | + * Receive a TLS record using the tls_en provided in ktls_start. The | ||||
+ * TLS. | + * 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 ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, | +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | ||||
+ size_t size, int flags) | |||||
+{ | +{ | ||||
+ off_t sbytes; | + 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; | + int ret; | ||||
+ unsigned char *p = data; | |||||
+ const size_t prepend_length = SSL3_RT_HEADER_LENGTH; | |||||
+ | + | ||||
+ ret = sendfile(fd, s, off, size, NULL, &sbytes, flags); | + if (length <= prepend_length) { | ||||
+ if (ret == -1) { | + errno = EINVAL; | ||||
+ if (errno == EAGAIN && sbytes != 0) | |||||
+ return sbytes; | |||||
+ return -1; | + return -1; | ||||
+ } | + } | ||||
+ return sbytes; | |||||
+} | |||||
+# endif /* __FreeBSD__ */ | |||||
+ | + | ||||
+# if defined(OPENSSL_SYS_LINUX) | + msg.msg_control = buf; | ||||
+# include <linux/version.h> | + msg.msg_controllen = sizeof(buf); | ||||
+ | + | ||||
+# define K_MAJ 4 | + msg_iov.iov_base = p + prepend_length; | ||||
+# define K_MIN1 13 | + msg_iov.iov_len = length - prepend_length; | ||||
+# define K_MIN2 0 | + msg.msg_iov = &msg_iov; | ||||
+# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2) | + msg.msg_iovlen = 1; | ||||
+ | + | ||||
+# ifndef PEDANTIC | + ret = recvmsg(fd, &msg, 0); | ||||
+# warning "KTLS requires Kernel Headers >= 4.13.0" | + if (ret <= 0) | ||||
+# warning "Skipping Compilation of KTLS" | + return ret; | ||||
+# endif | |||||
+ | + | ||||
+# define TLS_TX 1 | + if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) { | ||||
+# define TLS_RX 2 | + errno = EMSGSIZE; | ||||
+ | + return -1; | ||||
+# 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 | |||||
+ | |||||
+# define TLS_SET_RECORD_TYPE 1 | |||||
+ | |||||
+struct tls_crypto_info { | |||||
+ unsigned short version; | |||||
+ unsigned short cipher_type; | |||||
+}; | |||||
+ | |||||
+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]; | |||||
+}; | |||||
+ | |||||
+/* Dummy functions here */ | |||||
+static ossl_inline int ktls_enable(int fd) | |||||
+{ | |||||
+ return 0; | |||||
+} | + } | ||||
+ | + | ||||
+static ossl_inline int ktls_start(int fd, | + if (msg.msg_controllen == 0) { | ||||
+ struct tls12_crypto_info_aes_gcm_128 | + errno = EBADMSG; | ||||
+ *crypto_info, size_t len, int is_tx) | + return -1; | ||||
+{ | |||||
+ return 0; | |||||
+} | + } | ||||
+ | + | ||||
+static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, | + cmsg = CMSG_FIRSTHDR(&msg); | ||||
+ const void *data, size_t length) | + if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD | ||||
+{ | + || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) { | ||||
+ errno = EBADMSG; | |||||
+ return -1; | + return -1; | ||||
+} | + } | ||||
+ | + | ||||
+static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | + tgr = (struct tls_get_record *)CMSG_DATA(cmsg); | ||||
+{ | + p[0] = tgr->tls_type; | ||||
+ return -1; | + p[1] = tgr->tls_vmajor; | ||||
+ p[2] = tgr->tls_vminor; | |||||
+ *(uint16_t *)(p + 3) = htons(ret); | |||||
+ | |||||
+ return ret + prepend_length; | |||||
+} | +} | ||||
+ | + | ||||
+static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) | +# endif /* OPENSSL_NO_KTLS_RX */ | ||||
+ | |||||
+/* | |||||
+ * KTLS enables the sendfile system call to send data from a file over | |||||
+ * TLS. | |||||
+ */ | |||||
+static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, | |||||
+ size_t size, int flags) | |||||
+{ | +{ | ||||
+ off_t sbytes; | |||||
+ int ret; | |||||
+ | |||||
+ ret = sendfile(fd, s, off, size, NULL, &sbytes, flags); | |||||
+ if (ret == -1) { | |||||
+ if (errno == EAGAIN && sbytes != 0) | |||||
+ return sbytes; | |||||
+ return -1; | + return -1; | ||||
+} | + } | ||||
+ return sbytes; | |||||
+} | |||||
+ | + | ||||
+# else /* KERNEL_VERSION */ | +# endif /* __FreeBSD__ */ | ||||
+ | + | ||||
+# if defined(OPENSSL_SYS_LINUX) | |||||
+ | |||||
+# include <linux/tls.h> | |||||
+# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) | |||||
+# define 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 | |||||
+# 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 | |||||
+ | |||||
+# include <sys/sendfile.h> | +# include <sys/sendfile.h> | ||||
+# include <netinet/tcp.h> | +# include <netinet/tcp.h> | ||||
+# include <linux/tls.h> | |||||
+# include <linux/socket.h> | +# include <linux/socket.h> | ||||
+# include "openssl/ssl3.h" | +# include "openssl/ssl3.h" | ||||
+# include "openssl/tls1.h" | +# include "openssl/tls1.h" | ||||
+# include "openssl/evp.h" | +# include "openssl/evp.h" | ||||
+ | + | ||||
+# ifndef SOL_TLS | +# ifndef SOL_TLS | ||||
+# define SOL_TLS 282 | +# define SOL_TLS 282 | ||||
+# endif | +# endif | ||||
+ | + | ||||
+# ifndef TCP_ULP | +# ifndef TCP_ULP | ||||
+# define TCP_ULP 31 | +# define TCP_ULP 31 | ||||
+# endif | +# endif | ||||
+ | + | ||||
+# ifndef TLS_RX | +# ifndef TLS_RX | ||||
+# define TLS_RX 2 | +# define TLS_RX 2 | ||||
+# endif | +# endif | ||||
+ | + | ||||
+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; | |||||
+}; | |||||
+ | |||||
+typedef struct tls_crypto_info_all ktls_crypto_info_t; | |||||
+ | |||||
+/* | +/* | ||||
+ * When successful, this socket option doesn't change the behaviour of the | + * When successful, this socket option doesn't change the behaviour of the | ||||
+ * TCP socket, except changing the TCP setsockopt handler to enable the | + * TCP socket, except changing the TCP setsockopt handler to enable the | ||||
+ * processing of SOL_TLS socket options. All other functionality remains the | + * processing of SOL_TLS socket options. All other functionality remains the | ||||
+ * same. | + * same. | ||||
+ */ | + */ | ||||
+static ossl_inline int ktls_enable(int fd) | +static ossl_inline int ktls_enable(int fd) | ||||
+{ | +{ | ||||
+ return setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) ? 0 : 1; | + return setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) ? 0 : 1; | ||||
+} | +} | ||||
+ | + | ||||
+/* | +/* | ||||
+ * The TLS_TX socket option changes the send/sendmsg handlers of the TCP socket. | + * The TLS_TX socket option changes the send/sendmsg handlers of the TCP socket. | ||||
+ * If successful, then data sent using this socket will be encrypted and | + * If successful, then data sent using this socket will be encrypted and | ||||
+ * encapsulated in TLS records using the crypto_info provided here. | + * encapsulated in TLS records using the crypto_info provided here. | ||||
+ * The TLS_RX socket option changes the recv/recvmsg handlers of the TCP socket. | + * The TLS_RX socket option changes the recv/recvmsg handlers of the TCP socket. | ||||
+ * If successful, then data received using this socket will be decrypted, | + * If successful, then data received using this socket will be decrypted, | ||||
+ * authenticated and decapsulated using the crypto_info provided here. | + * authenticated and decapsulated using the crypto_info provided here. | ||||
+ */ | + */ | ||||
+static ossl_inline int ktls_start(int fd, | +static ossl_inline int ktls_start(int fd, void *crypto_info, | ||||
+ struct tls12_crypto_info_aes_gcm_128 | + size_t len, int is_tx) | ||||
+ *crypto_info, size_t len, int is_tx) | |||||
+{ | +{ | ||||
+ return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, | + return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, | ||||
+ crypto_info, sizeof(*crypto_info)) ? 0 : 1; | + crypto_info, len) ? 0 : 1; | ||||
+} | +} | ||||
+ | + | ||||
+/* | +/* | ||||
+ * Send a TLS record using the crypto_info provided in ktls_start and use | + * Send a TLS record using the crypto_info provided in ktls_start and use | ||||
+ * record_type instead of the default SSL3_RT_APPLICATION_DATA. | + * record_type instead of the default SSL3_RT_APPLICATION_DATA. | ||||
+ * When the socket is non-blocking, then this call either returns EAGAIN or | + * When the socket is non-blocking, then this call either returns EAGAIN or | ||||
+ * the entire record is pushed to TCP. It is impossible to send a partial | + * the entire record is pushed to TCP. It is impossible to send a partial | ||||
+ * record using this control message. | + * record using this control message. | ||||
Show All 32 Lines | |||||
+ * KTLS enables the sendfile system call to send data from a file over TLS. | + * KTLS enables the sendfile system call to send data from a file over TLS. | ||||
+ * @flags are ignored on Linux. (placeholder for FreeBSD sendfile) | + * @flags are ignored on Linux. (placeholder for FreeBSD sendfile) | ||||
+ * */ | + * */ | ||||
+static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) | +static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) | ||||
+{ | +{ | ||||
+ return sendfile(s, fd, &off, size); | + return sendfile(s, fd, &off, size); | ||||
+} | +} | ||||
+ | + | ||||
+# define K_MIN1_RX 17 | +# ifdef OPENSSL_NO_KTLS_RX | ||||
+# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1_RX, K_MIN2) | |||||
+ | + | ||||
+# 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) | +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | ||||
+{ | +{ | ||||
+ return -1; | + return -1; | ||||
+} | +} | ||||
+ | + | ||||
+# else | +# else /* !defined(OPENSSL_NO_KTLS_RX) */ | ||||
+ | + | ||||
+/* | +/* | ||||
+ * Receive a TLS record using the crypto_info provided in ktls_start. | + * Receive a TLS record using the crypto_info provided in ktls_start. | ||||
+ * The kernel strips the TLS record header, IV and authentication tag, | + * The kernel strips the TLS record header, IV and authentication tag, | ||||
+ * returning only the plaintext data or an error on failure. | + * returning only the plaintext data or an error on failure. | ||||
+ * We add the TLS record header here to satisfy routines in rec_layer_s3.c | + * We add the TLS record header here to satisfy routines in rec_layer_s3.c | ||||
+ */ | + */ | ||||
+static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) | ||||
Show All 38 Lines | |||||
+ p[4] = ret & 0xff; | + p[4] = ret & 0xff; | ||||
+ ret += prepend_length; | + ret += prepend_length; | ||||
+ } | + } | ||||
+ } | + } | ||||
+ | + | ||||
+ return ret; | + return ret; | ||||
+} | +} | ||||
+ | + | ||||
+# endif | +# endif /* OPENSSL_NO_KTLS_RX */ | ||||
+# endif | + | ||||
+# endif | +# endif /* OPENSSL_SYS_LINUX */ | ||||
+# endif | +# else /* OPENSSL_NO_KTLS */ | ||||
+#endif | +/* 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 | diff --git include/openssl/bio.h include/openssl/bio.h | ||||
index ae559a5105..fa50337aab 100644 | index ae559a5105..fa50337aab 100644 | ||||
--- include/openssl/bio.h | --- include/openssl/bio.h | ||||
+++ include/openssl/bio.h | +++ include/openssl/bio.h | ||||
@@ -141,6 +141,26 @@ extern "C" { | @@ -141,6 +141,26 @@ extern "C" { | ||||
# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 | # define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
# define EVP_CTRL_GET_IVLEN 0x25 | # define EVP_CTRL_GET_IVLEN 0x25 | ||||
+/* Get the IV used by the cipher */ | +/* Get the IV used by the cipher */ | ||||
+# define EVP_CTRL_GET_IV 0x26 | +# define EVP_CTRL_GET_IV 0x26 | ||||
/* Padding modes */ | /* Padding modes */ | ||||
#define EVP_PADDING_PKCS7 1 | #define EVP_PADDING_PKCS7 1 | ||||
diff --git include/openssl/ssl.h include/openssl/ssl.h | 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 | ||||
+++ 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); | @@ -493,6 +493,10 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); | ||||
* Support Asynchronous operation | * Support Asynchronous operation | ||||
*/ | */ | ||||
# define SSL_MODE_ASYNC 0x00000100U | # define SSL_MODE_ASYNC 0x00000100U | ||||
+/* | +/* | ||||
+ * Don't use the kernel TLS data-path for sending. | + * Don't use the kernel TLS data-path for sending. | ||||
Show All 17 Lines | @@ -1837,6 +1845,8 @@ __owur int SSL_read_early_data(SSL *s, void *buf, size_t num, | ||||
size_t *readbytes); | size_t *readbytes); | ||||
__owur int SSL_peek(SSL *ssl, void *buf, int num); | __owur int SSL_peek(SSL *ssl, void *buf, int num); | ||||
__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); | __owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); | ||||
+__owur ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, | +__owur ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, | ||||
+ int flags); | + int flags); | ||||
__owur int SSL_write(SSL *ssl, const void *buf, int num); | __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_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, | __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 | diff --git include/openssl/sslerr.h include/openssl/sslerr.h | ||||
index 82983d3c1e..0bdc8f3b2c 100644 | index 82983d3c1e..0bdc8f3b2c 100644 | ||||
--- include/openssl/sslerr.h | --- include/openssl/sslerr.h | ||||
+++ include/openssl/sslerr.h | +++ include/openssl/sslerr.h | ||||
@@ -219,6 +219,7 @@ int ERR_load_SSL_strings(void); | @@ -219,6 +219,7 @@ int ERR_load_SSL_strings(void); | ||||
# define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546 | # define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546 | ||||
# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 | # define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 | ||||
# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 | # define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 | ||||
+# define SSL_F_SSL_SENDFILE 639 | +# define SSL_F_SSL_SENDFILE 639 | ||||
# define SSL_F_SSL_SESSION_DUP 348 | # define SSL_F_SSL_SESSION_DUP 348 | ||||
# define SSL_F_SSL_SESSION_NEW 189 | # define SSL_F_SSL_SESSION_NEW 189 | ||||
# define SSL_F_SSL_SESSION_PRINT_FP 190 | # 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 <crypto/cryptodev.h> | |||||
+ | |||||
+/*- | |||||
+ * 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 | 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 | ||||
+++ 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, | @@ -268,11 +268,15 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, | ||||
return -1; | return -1; | ||||
} | } | ||||
- /* We always act like read_ahead is set for DTLS */ | - /* We always act like read_ahead is set for DTLS */ | ||||
- if (!s->rlayer.read_ahead && !SSL_IS_DTLS(s)) | - if (!s->rlayer.read_ahead && !SSL_IS_DTLS(s)) | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | + && (!WPACKET_put_bytes_u8(thispkt, rectype) | ||||
&& !WPACKET_allocate_bytes(thispkt, eivlen, NULL)) | && !WPACKET_allocate_bytes(thispkt, eivlen, NULL)) | ||||
|| (maxcomplen > 0 | || (maxcomplen > 0 | ||||
&& !WPACKET_reserve_bytes(thispkt, maxcomplen, | && !WPACKET_reserve_bytes(thispkt, maxcomplen, | ||||
- &compressdata))) { | - &compressdata))) { | ||||
+ &compressdata)))) { | + &compressdata)))) { | ||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | ||||
ERR_R_INTERNAL_ERROR); | ERR_R_INTERNAL_ERROR); | ||||
goto err; | 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; | goto err; | ||||
} | } | ||||
} else { | } else { | ||||
- if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { | - if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { | ||||
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | ||||
- ERR_R_INTERNAL_ERROR); | - ERR_R_INTERNAL_ERROR); | ||||
- goto err; | - goto err; | ||||
+ if (BIO_get_ktls_send(s->wbio)) { | + if (BIO_get_ktls_send(s->wbio)) { | ||||
+ SSL3_RECORD_reset_data(&wr[j]); | + SSL3_RECORD_reset_data(&wr[j]); | ||||
+ } else { | + } else { | ||||
+ if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { | + if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { | ||||
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | ||||
+ ERR_R_INTERNAL_ERROR); | + ERR_R_INTERNAL_ERROR); | ||||
+ goto err; | + goto err; | ||||
+ } | + } | ||||
+ SSL3_RECORD_reset_input(&wr[j]); | + SSL3_RECORD_reset_input(&wr[j]); | ||||
} | } | ||||
- SSL3_RECORD_reset_input(&wr[j]); | - SSL3_RECORD_reset_input(&wr[j]); | ||||
} | } | ||||
if (SSL_TREAT_AS_TLS13(s) | 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 | * in the wb->buf | ||||
*/ | */ | ||||
- if (!SSL_WRITE_ETM(s) && mac_size != 0) { | - if (!SSL_WRITE_ETM(s) && mac_size != 0) { | ||||
+ if (!BIO_get_ktls_send(s->wbio) && !SSL_WRITE_ETM(s) && mac_size != 0) { | + if (!BIO_get_ktls_send(s->wbio) && !SSL_WRITE_ETM(s) && mac_size != 0) { | ||||
unsigned char *mac; | unsigned char *mac; | ||||
if (!WPACKET_allocate_bytes(thispkt, mac_size, &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 | * This will be at most one cipher block or the tag length if using | ||||
* AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case. | * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case. | ||||
*/ | */ | ||||
- if (!WPACKET_reserve_bytes(thispkt, SSL_RT_MAX_CIPHER_BLOCK_SIZE, | - if (!WPACKET_reserve_bytes(thispkt, SSL_RT_MAX_CIPHER_BLOCK_SIZE, | ||||
- NULL) | - NULL) | ||||
- /* | - /* | ||||
- * We also need next the amount of bytes written to this | - * We also need next the amount of bytes written to this | ||||
- * sub-packet | - * sub-packet | ||||
Show All 23 Lines | |||||
- recordstart = WPACKET_get_curr(thispkt) - len; | - recordstart = WPACKET_get_curr(thispkt) - len; | ||||
- | - | ||||
- SSL3_RECORD_set_data(thiswr, recordstart); | - SSL3_RECORD_set_data(thiswr, recordstart); | ||||
- SSL3_RECORD_reset_input(thiswr); | - SSL3_RECORD_reset_input(thiswr); | ||||
- SSL3_RECORD_set_length(thiswr, len); | - SSL3_RECORD_set_length(thiswr, len); | ||||
} | } | ||||
if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) { | 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; | goto err; | ||||
} | } | ||||
} else { | } else { | ||||
- if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) { | - if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) { | ||||
- if (!ossl_statem_in_error(s)) { | - if (!ossl_statem_in_error(s)) { | ||||
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | ||||
- ERR_R_INTERNAL_ERROR); | - ERR_R_INTERNAL_ERROR); | ||||
+ if (!BIO_get_ktls_send(s->wbio)) { | + if (!BIO_get_ktls_send(s->wbio)) { | ||||
+ if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) { | + if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) { | ||||
+ if (!ossl_statem_in_error(s)) { | + if (!ossl_statem_in_error(s)) { | ||||
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | ||||
+ ERR_R_INTERNAL_ERROR); | + ERR_R_INTERNAL_ERROR); | ||||
+ } | + } | ||||
+ goto err; | + goto err; | ||||
} | } | ||||
- goto err; | - goto err; | ||||
} | } | ||||
} | } | ||||
@@ -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]; | thispkt = &pkt[j]; | ||||
thiswr = &wr[j]; | thiswr = &wr[j]; | ||||
+ if (BIO_get_ktls_send(s->wbio)) | + if (BIO_get_ktls_send(s->wbio)) | ||||
+ goto mac_done; | + goto mac_done; | ||||
+ | + | ||||
/* Allocate bytes for the encryption overhead */ | /* Allocate bytes for the encryption overhead */ | ||||
if (!WPACKET_get_length(thispkt, &origlen) | if (!WPACKET_get_length(thispkt, &origlen) | ||||
/* Encryption should never shrink the data! */ | /* Encryption should never shrink the data! */ | ||||
|| origlen > thiswr->length | || origlen > thiswr->length | ||||
|| (thiswr->length > origlen | || (thiswr->length > origlen | ||||
&& !WPACKET_allocate_bytes(thispkt, | && !WPACKET_allocate_bytes(thispkt, | ||||
- thiswr->length - origlen, NULL))) { | - thiswr->length - origlen, NULL))) { | ||||
+ thiswr->length - origlen, | + thiswr->length - origlen, | ||||
+ NULL))) { | + NULL))) { | ||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | ||||
ERR_R_INTERNAL_ERROR); | ERR_R_INTERNAL_ERROR); | ||||
goto err; | 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; | goto err; | ||||
} | } | ||||
- /* | - /* | ||||
- * we should now have thiswr->data pointing to the encrypted data, which | - * we should now have thiswr->data pointing to the encrypted data, which | ||||
- * is thiswr->length long | - * is thiswr->length long | ||||
- */ | - */ | ||||
- SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for | - SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for | ||||
- * debugging */ | - * debugging */ | ||||
- SSL3_RECORD_add_length(thiswr, SSL3_RT_HEADER_LENGTH); | - SSL3_RECORD_add_length(thiswr, SSL3_RT_HEADER_LENGTH); | ||||
+ /* header is added by the kernel when using offload */ | + /* header is added by the kernel when using offload */ | ||||
+ SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH); | + SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH); | ||||
if (create_empty_fragment) { | 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; | return 1; | ||||
} | } | ||||
+ mac_done: | + mac_done: | ||||
+ /* | + /* | ||||
+ * we should now have thiswr->data pointing to the encrypted data, which | + * we should now have thiswr->data pointing to the encrypted data, which | ||||
+ * is thiswr->length long | + * is thiswr->length long | ||||
+ */ | + */ | ||||
+ SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for | + SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for | ||||
+ * debugging */ | + * debugging */ | ||||
+ | + | ||||
/* now let's set up wb */ | /* now let's set up wb */ | ||||
SSL3_BUFFER_set_left(&s->rlayer.wbuf[j], | SSL3_BUFFER_set_left(&s->rlayer.wbuf[j], | ||||
prefix_len + SSL3_RECORD_get_length(thiswr)); | 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(); | clear_sys_error(); | ||||
if (s->wbio != NULL) { | if (s->wbio != NULL) { | ||||
s->rwstate = SSL_WRITING; | s->rwstate = SSL_WRITING; | ||||
+ | + | ||||
+ /* | + /* | ||||
+ * To prevent coalescing of control and data messages, | + * To prevent coalescing of control and data messages, | ||||
+ * such as in buffer_write, we flush the BIO | + * such as in buffer_write, we flush the BIO | ||||
+ */ | + */ | ||||
Show All 40 Lines | |||||
#define SSL3_RECORD_get_input(r) ((r)->input) | #define SSL3_RECORD_get_input(r) ((r)->input) | ||||
#define SSL3_RECORD_set_input(r, i) ((r)->input = (i)) | #define SSL3_RECORD_set_input(r, i) ((r)->input = (i)) | ||||
#define SSL3_RECORD_reset_input(r) ((r)->input = (r)->data) | #define SSL3_RECORD_reset_input(r) ((r)->input = (r)->data) | ||||
+#define SSL3_RECORD_reset_data(r) ((r)->data = (r)->input) | +#define SSL3_RECORD_reset_data(r) ((r)->data = (r)->input) | ||||
#define SSL3_RECORD_get_seq_num(r) ((r)->seq_num) | #define SSL3_RECORD_get_seq_num(r) ((r)->seq_num) | ||||
#define SSL3_RECORD_get_off(r) ((r)->off) | #define SSL3_RECORD_get_off(r) ((r)->off) | ||||
#define SSL3_RECORD_set_off(r, o) ((r)->off = (o)) | #define SSL3_RECORD_set_off(r, o) ((r)->off = (o)) | ||||
diff --git ssl/record/ssl3_buffer.c ssl/record/ssl3_buffer.c | 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 | ||||
+++ 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) | @@ -111,23 +111,27 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) | ||||
for (currpipe = 0; currpipe < numwpipes; currpipe++) { | for (currpipe = 0; currpipe < numwpipes; currpipe++) { | ||||
SSL3_BUFFER *thiswb = &wb[currpipe]; | SSL3_BUFFER *thiswb = &wb[currpipe]; | ||||
- if (thiswb->buf != NULL && thiswb->len != len) { | - if (thiswb->buf != NULL && thiswb->len != len) { | ||||
+ if (thiswb->len != len) { | + if (thiswb->len != len) { | ||||
Show All 39 Lines | |||||
+ if (SSL3_BUFFER_is_app_buffer(wb)) | + if (SSL3_BUFFER_is_app_buffer(wb)) | ||||
+ SSL3_BUFFER_set_app_buffer(wb, 0); | + SSL3_BUFFER_set_app_buffer(wb, 0); | ||||
+ else | + else | ||||
+ OPENSSL_free(wb->buf); | + OPENSSL_free(wb->buf); | ||||
wb->buf = NULL; | wb->buf = NULL; | ||||
pipes--; | pipes--; | ||||
} | } | ||||
diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c | 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 | ||||
+++ ssl/record/ssl3_record.c | +++ ssl/record/ssl3_record.c | ||||
@@ -186,9 +186,11 @@ int ssl3_get_record(SSL *s) | @@ -186,9 +186,11 @@ int ssl3_get_record(SSL *s) | ||||
size_t num_recs = 0, max_recs, j; | size_t num_recs = 0, max_recs, j; | ||||
PACKET pkt, sslv2pkt; | PACKET pkt, sslv2pkt; | ||||
size_t first_rec_len; | size_t first_rec_len; | ||||
+ int is_ktls_left; | + int is_ktls_left; | ||||
rr = RECORD_LAYER_get_rrec(&s->rlayer); | rr = RECORD_LAYER_get_rrec(&s->rlayer); | ||||
rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | ||||
+ is_ktls_left = (rbuf->left > 0); | + is_ktls_left = (rbuf->left > 0); | ||||
max_recs = s->max_pipelines; | max_recs = s->max_pipelines; | ||||
if (max_recs == 0) | if (max_recs == 0) | ||||
max_recs = 1; | max_recs = 1; | ||||
@@ -207,8 +209,32 @@ int ssl3_get_record(SSL *s) | @@ -207,8 +209,32 @@ int ssl3_get_record(SSL *s) | ||||
rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, | rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, | ||||
SSL3_BUFFER_get_len(rbuf), 0, | SSL3_BUFFER_get_len(rbuf), 0, | ||||
num_recs == 0 ? 1 : 0, &n); | num_recs == 0 ? 1 : 0, &n); | ||||
- if (rret <= 0) | - if (rret <= 0) | ||||
- return rret; /* error or non-blocking */ | - return rret; /* error or non-blocking */ | ||||
+ if (rret <= 0) { | + if (rret <= 0) { | ||||
+#ifndef OPENSSL_NO_KTLS | +#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 */ | + return rret; /* error or non-blocking */ | ||||
+ switch (errno) { | + switch (errno) { | ||||
+ case EBADMSG: | + case EBADMSG: | ||||
+ SSLfatal(s, SSL_AD_BAD_RECORD_MAC, | + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, | ||||
+ SSL_F_SSL3_GET_RECORD, | + SSL_F_SSL3_GET_RECORD, | ||||
+ SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | ||||
+ break; | + break; | ||||
+ case EMSGSIZE: | + case EMSGSIZE: | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | @@ -312,6 +312,7 @@ static const ERR_STRING_DATA SSL_str_functs[] = { | ||||
"SSL_renegotiate_abbreviated"}, | "SSL_renegotiate_abbreviated"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""}, | ||||
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SENDFILE, 0), "SSL_sendfile"}, | + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SENDFILE, 0), "SSL_sendfile"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"}, | {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), | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0), | ||||
diff --git ssl/ssl_lib.c ssl/ssl_lib.c | 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 | ||||
+++ ssl/ssl_lib.c | +++ ssl/ssl_lib.c | ||||
@@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "ssl_local.h" | #include "ssl_local.h" | ||||
+#include "e_os.h" | +#include "e_os.h" | ||||
#include <openssl/objects.h> | #include <openssl/objects.h> | ||||
Show All 18 Lines | + | ||||
BIO_free_all(s->wbio); | BIO_free_all(s->wbio); | ||||
+ s->wbio = NULL; | + s->wbio = NULL; | ||||
BIO_free_all(s->rbio); | BIO_free_all(s->rbio); | ||||
+ s->rbio = NULL; | + s->rbio = NULL; | ||||
BUF_MEM_free(s->init_buf); | 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) | if (s->method != NULL) | ||||
s->method->ssl_free(s); | s->method->ssl_free(s); | ||||
- RECORD_LAYER_release(&s->rlayer); | - RECORD_LAYER_release(&s->rlayer); | ||||
- | - | ||||
SSL_CTX_free(s->ctx); | SSL_CTX_free(s->ctx); | ||||
ASYNC_WAIT_CTX_free(s->waitctx); | 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); | BIO_set_fd(bio, fd, BIO_NOCLOSE); | ||||
SSL_set_bio(s, bio, bio); | SSL_set_bio(s, bio, bio); | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ /* | + /* | ||||
+ * The new socket is created successfully regardless of ktls_enable. | + * The new socket is created successfully regardless of ktls_enable. | ||||
+ * ktls_enable doesn't change any functionality of the socket, except | + * ktls_enable doesn't change any functionality of the socket, except | ||||
+ * changing the setsockopt to enable the processing of ktls_start. | + * changing the setsockopt to enable the processing of ktls_start. | ||||
+ * Thus, it is not a problem to call it for non-TLS sockets. | + * Thus, it is not a problem to call it for non-TLS sockets. | ||||
+ */ | + */ | ||||
+ ktls_enable(fd); | + ktls_enable(fd); | ||||
+#endif /* OPENSSL_NO_KTLS */ | +#endif /* OPENSSL_NO_KTLS */ | ||||
ret = 1; | ret = 1; | ||||
err: | err: | ||||
return ret; | 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); | BIO_set_fd(bio, fd, BIO_NOCLOSE); | ||||
SSL_set0_wbio(s, bio); | SSL_set0_wbio(s, bio); | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ /* | + /* | ||||
+ * The new socket is created successfully regardless of ktls_enable. | + * The new socket is created successfully regardless of ktls_enable. | ||||
+ * ktls_enable doesn't change any functionality of the socket, except | + * ktls_enable doesn't change any functionality of the socket, except | ||||
+ * changing the setsockopt to enable the processing of ktls_start. | + * changing the setsockopt to enable the processing of ktls_start. | ||||
+ * Thus, it is not a problem to call it for non-TLS sockets. | + * Thus, it is not a problem to call it for non-TLS sockets. | ||||
+ */ | + */ | ||||
+ ktls_enable(fd); | + ktls_enable(fd); | ||||
+#endif /* OPENSSL_NO_KTLS */ | +#endif /* OPENSSL_NO_KTLS */ | ||||
} else { | } else { | ||||
BIO_up_ref(rbio); | BIO_up_ref(rbio); | ||||
SSL_set0_wbio(s, 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) | ||||
} | } | ||||
} | } | ||||
+ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) | +ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) | ||||
+{ | +{ | ||||
+ ossl_ssize_t ret; | + ossl_ssize_t ret; | ||||
+ | + | ||||
+ if (s->handshake_func == NULL) { | + if (s->handshake_func == NULL) { | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
+ s->rwstate = SSL_NOTHING; | + s->rwstate = SSL_NOTHING; | ||||
+ return ret; | + return ret; | ||||
+#endif | +#endif | ||||
+} | +} | ||||
+ | + | ||||
int SSL_write(SSL *s, const void *buf, int num) | int SSL_write(SSL *s, const void *buf, int num) | ||||
{ | { | ||||
int ret; | 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: | case SSL_CTRL_SET_MAX_SEND_FRAGMENT: | ||||
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) | if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) | ||||
return 0; | return 0; | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (s->wbio != NULL && BIO_get_ktls_send(s->wbio)) | + if (s->wbio != NULL && BIO_get_ktls_send(s->wbio)) | ||||
+ return 0; | + return 0; | ||||
+#endif /* OPENSSL_NO_KTLS */ | +#endif /* OPENSSL_NO_KTLS */ | ||||
s->max_send_fragment = larg; | s->max_send_fragment = larg; | ||||
if (s->max_send_fragment < s->split_send_fragment) | if (s->max_send_fragment < s->split_send_fragment) | ||||
s->split_send_fragment = s->max_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 | 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 | ||||
+++ ssl/ssl_local.h | +++ ssl/ssl_local.h | ||||
@@ -34,6 +34,7 @@ | @@ -34,6 +34,8 @@ | ||||
# include "internal/dane.h" | # include "internal/dane.h" | ||||
# include "internal/refcount.h" | # include "internal/refcount.h" | ||||
# include "internal/tsan_assist.h" | # include "internal/tsan_assist.h" | ||||
+# include "internal/bio.h" | +# include "internal/bio.h" | ||||
+# include "internal/ktls.h" | |||||
# ifdef OPENSSL_BUILD_SHLIBSSL | # ifdef OPENSSL_BUILD_SHLIBSSL | ||||
# undef OPENSSL_EXTERN | # 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 | 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 | ||||
+++ ssl/t1_enc.c | +++ ssl/t1_enc.c | ||||
@@ -10,10 +10,14 @@ | @@ -10,10 +10,14 @@ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "ssl_local.h" | #include "ssl_local.h" | ||||
+#include "record/record_local.h" | +#include "record/record_local.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
+#include "internal/cryptlib.h" | +#include "internal/cryptlib.h" | ||||
#include <openssl/comp.h> | #include <openssl/comp.h> | ||||
#include <openssl/evp.h> | #include <openssl/evp.h> | ||||
#include <openssl/kdf.h> | #include <openssl/kdf.h> | ||||
#include <openssl/rand.h> | #include <openssl/rand.h> | ||||
+#include <openssl/obj_mac.h> | +#include <openssl/obj_mac.h> | ||||
/* seed1 through seed5 are concatenated */ | /* seed1 through seed5 are concatenated */ | ||||
static int tls1_PRF(SSL *s, | 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; | return ret; | ||||
} | } | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ /* | + /* | ||||
+ * Count the number of records that were not processed yet from record boundary. | + * Count the number of records that were not processed yet from record boundary. | ||||
+ * | + * | ||||
+ * This function assumes that there are only fully formed records read in the | + * This function assumes that there are only fully formed records read in the | ||||
+ * record layer. If read_ahead is enabled, then this might be false and this | + * record layer. If read_ahead is enabled, then this might be false and this | ||||
+ * function will fail. | + * function will fail. | ||||
+ */ | + */ | ||||
+# ifndef OPENSSL_NO_KTLS_RX | |||||
+static int count_unprocessed_records(SSL *s) | +static int count_unprocessed_records(SSL *s) | ||||
+{ | +{ | ||||
+ SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | + SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | ||||
+ PACKET pkt, subpkt; | + PACKET pkt, subpkt; | ||||
+ int count = 0; | + int count = 0; | ||||
+ | + | ||||
+ if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left)) | + if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left)) | ||||
+ return -1; | + return -1; | ||||
+ | + | ||||
+ while (PACKET_remaining(&pkt) > 0) { | + while (PACKET_remaining(&pkt) > 0) { | ||||
+ /* Skip record type and version */ | + /* Skip record type and version */ | ||||
+ if (!PACKET_forward(&pkt, 3)) | + if (!PACKET_forward(&pkt, 3)) | ||||
+ return -1; | + return -1; | ||||
+ | + | ||||
+ /* Read until next record */ | + /* Read until next record */ | ||||
+ if (PACKET_get_length_prefixed_2(&pkt, &subpkt)) | + if (PACKET_get_length_prefixed_2(&pkt, &subpkt)) | ||||
+ return -1; | + return -1; | ||||
+ | + | ||||
+ count += 1; | + count += 1; | ||||
+ } | + } | ||||
+ | + | ||||
+ return count; | + return count; | ||||
+} | +} | ||||
+#endif | +# endif | ||||
+#endif | |||||
+ | + | ||||
int tls1_change_cipher_state(SSL *s, int which) | int tls1_change_cipher_state(SSL *s, int which) | ||||
{ | { | ||||
unsigned char *p, *mac_secret; | 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; | EVP_PKEY *mac_key; | ||||
size_t n, i, j, k, cl; | size_t n, i, j, k, cl; | ||||
int reuse_dd = 0; | int reuse_dd = 0; | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+# ifdef __FreeBSD__ | + ktls_crypto_info_t crypto_info; | ||||
+ struct tls_enable crypto_info; | + unsigned char *rec_seq; | ||||
+# else | + void *rl_sequence; | ||||
+ struct tls12_crypto_info_aes_gcm_128 crypto_info; | +# ifndef OPENSSL_NO_KTLS_RX | ||||
+ unsigned char geniv[12]; | |||||
+ int count_unprocessed; | + int count_unprocessed; | ||||
+ int bit; | + int bit; | ||||
+# endif | +# endif | ||||
+ BIO *bio; | + BIO *bio; | ||||
+#endif | +#endif | ||||
c = s->s3->tmp.new_sym_enc; | c = s->s3->tmp.new_sym_enc; | ||||
m = s->s3->tmp.new_hash; | 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); | ERR_R_INTERNAL_ERROR); | ||||
goto err; | goto err; | ||||
} | } | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (s->compress) | + if (s->compress) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ if (((which & SSL3_CC_READ) && (s->mode & SSL_MODE_NO_KTLS_RX)) | + if (((which & SSL3_CC_READ) && (s->mode & SSL_MODE_NO_KTLS_RX)) | ||||
+ || ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX))) | + || ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX))) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* ktls supports only the maximum fragment size */ | + /* ktls supports only the maximum fragment size */ | ||||
+ if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) | + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+# ifdef __FreeBSD__ | + /* check that cipher is supported */ | ||||
+ memset(&crypto_info, 0, sizeof(crypto_info)); | + if (!ktls_check_supported_cipher(s, c, dd)) | ||||
+ 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; | + 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: | |||||
+ 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) | + if (which & SSL3_CC_WRITE) | ||||
+ bio = s->wbio; | + bio = s->wbio; | ||||
+ else | + else | ||||
+ bio = s->rbio; | + bio = s->rbio; | ||||
+ | + | ||||
+ if (!ossl_assert(bio != NULL)) { | + if (!ossl_assert(bio != NULL)) { | ||||
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, | + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, | ||||
+ ERR_R_INTERNAL_ERROR); | + ERR_R_INTERNAL_ERROR); | ||||
Show All 9 Lines | |||||
+ /* ktls doesn't support renegotiation */ | + /* ktls doesn't support renegotiation */ | ||||
+ if ((BIO_get_ktls_send(s->wbio) && (which & SSL3_CC_WRITE)) || | + if ((BIO_get_ktls_send(s->wbio) && (which & SSL3_CC_WRITE)) || | ||||
+ (BIO_get_ktls_recv(s->rbio) && (which & SSL3_CC_READ))) { | + (BIO_get_ktls_recv(s->rbio) && (which & SSL3_CC_READ))) { | ||||
+ SSLfatal(s, SSL_AD_NO_RENEGOTIATION, SSL_F_TLS1_CHANGE_CIPHER_STATE, | + SSLfatal(s, SSL_AD_NO_RENEGOTIATION, SSL_F_TLS1_CHANGE_CIPHER_STATE, | ||||
+ ERR_R_INTERNAL_ERROR); | + ERR_R_INTERNAL_ERROR); | ||||
+ goto err; | + 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) | + if (which & SSL3_CC_WRITE) | ||||
+ memcpy(crypto_info.rec_seq, &s->rlayer.write_sequence, | + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | |||||
+ else | + else | ||||
+ memcpy(crypto_info.rec_seq, &s->rlayer.read_sequence, | + rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | |||||
+ | + | ||||
+ 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) { | + if (which & SSL3_CC_READ) { | ||||
+# ifndef OPENSSL_NO_KTLS_RX | |||||
+ count_unprocessed = count_unprocessed_records(s); | + count_unprocessed = count_unprocessed_records(s); | ||||
+ if (count_unprocessed < 0) | + if (count_unprocessed < 0) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* increment the crypto_info record sequence */ | + /* increment the crypto_info record sequence */ | ||||
+ while (count_unprocessed) { | + while (count_unprocessed) { | ||||
+ for (bit = 7; bit >= 0; bit--) { /* increment */ | + for (bit = 7; bit >= 0; bit--) { /* increment */ | ||||
+ ++crypto_info.rec_seq[bit]; | + ++rec_seq[bit]; | ||||
+ if (crypto_info.rec_seq[bit] != 0) | + if (rec_seq[bit] != 0) | ||||
+ break; | + break; | ||||
+ } | + } | ||||
+ count_unprocessed--; | + count_unprocessed--; | ||||
+ } | + } | ||||
+ } | +# else | ||||
+ goto skip_ktls; | |||||
+# endif | +# endif | ||||
+ } | |||||
+ | + | ||||
+ /* ktls works with user provided buffers directly */ | + /* ktls works with user provided buffers directly */ | ||||
+ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { | + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { | ||||
+ if (which & SSL3_CC_WRITE) | + if (which & SSL3_CC_WRITE) | ||||
+ ssl3_release_write_buffer(s); | + ssl3_release_write_buffer(s); | ||||
+ SSL_set_options(s, SSL_OP_NO_RENEGOTIATION); | + SSL_set_options(s, SSL_OP_NO_RENEGOTIATION); | ||||
+ } | + } | ||||
+ | + | ||||
+ skip_ktls: | + skip_ktls: | ||||
+#endif /* OPENSSL_NO_KTLS */ | +#endif /* OPENSSL_NO_KTLS */ | ||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | ||||
#ifdef SSL_DEBUG | #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 <stdlib.h> | |||||
#include "ssl_local.h" | |||||
+#include "internal/ktls.h" | |||||
+#include "record/record_local.h" | |||||
#include "internal/cryptlib.h" | |||||
#include <openssl/evp.h> | |||||
#include <openssl/kdf.h> | |||||
@@ -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 | diff --git test/sslapitest.c test/sslapitest.c | ||||
index 5c118108ef..98b8574aba 100644 | index ad1824c68d..f6a61cab4e 100644 | ||||
--- test/sslapitest.c | --- test/sslapitest.c | ||||
+++ test/sslapitest.c | +++ test/sslapitest.c | ||||
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||||
* https://www.openssl.org/source/license.html | * https://www.openssl.org/source/license.html | ||||
*/ | */ | ||||
+#include <stdio.h> | +#include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <openssl/opensslconf.h> | #include <openssl/opensslconf.h> | ||||
@@ -17,11 +18,13 @@ | @@ -17,11 +18,13 @@ | ||||
#include <openssl/srp.h> | #include <openssl/srp.h> | ||||
#include <openssl/txt_db.h> | #include <openssl/txt_db.h> | ||||
#include <openssl/aes.h> | #include <openssl/aes.h> | ||||
+#include <openssl/rand.h> | +#include <openssl/rand.h> | ||||
#include "ssltestlib.h" | #include "ssltestlib.h" | ||||
#include "testutil.h" | #include "testutil.h" | ||||
#include "testutil/output.h" | #include "testutil/output.h" | ||||
#include "internal/nelem.h" | #include "internal/nelem.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
#include "../ssl/ssl_local.h" | #include "../ssl/ssl_local.h" | ||||
#ifndef OPENSSL_NO_TLS1_3 | #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; | return testresult; | ||||
} | } | ||||
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ | +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_KTLS) && \ | ||||
+ && !defined(OPENSSL_NO_SOCK) | + !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_TLS1_2)) | ||||
+ | +#define TLS_CIPHER_MAX_REC_SEQ_SIZE 8 | ||||
+/* sock must be connected */ | +/* sock must be connected */ | ||||
+static int ktls_chk_platform(int sock) | +static int ktls_chk_platform(int sock) | ||||
+{ | +{ | ||||
+ if (!ktls_enable(sock)) | + if (!ktls_enable(sock)) | ||||
+ return 0; | + return 0; | ||||
+ return 1; | + 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; | + static char count = 1; | ||||
+ unsigned char cbuf[16000] = {0}; | + unsigned char cbuf[16000] = {0}; | ||||
+ unsigned char sbuf[16000]; | + unsigned char sbuf[16000]; | ||||
+ size_t err = 0; | + size_t err = 0; | ||||
+ char crec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char crec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char crec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char crec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char crec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char crec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char crec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char crec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char srec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char srec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char srec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char srec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char srec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char srec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ char srec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; | + char srec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; | ||||
+ | + | ||||
+ cbuf[0] = count++; | + cbuf[0] = count++; | ||||
+ memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, | + memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, rec_seq_size); | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | + memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, rec_seq_size); | ||||
+ memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, | + memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, rec_seq_size); | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | + memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, 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); | |||||
+ | + | ||||
+ if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf))) | + if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf))) | ||||
+ goto end; | + goto end; | ||||
+ | + | ||||
+ while ((err = SSL_read(serverssl, &sbuf, sizeof(sbuf))) != sizeof(sbuf)) { | + while ((err = SSL_read(serverssl, &sbuf, sizeof(sbuf))) != sizeof(sbuf)) { | ||||
+ if (SSL_get_error(serverssl, err) != SSL_ERROR_WANT_READ) { | + if (SSL_get_error(serverssl, err) != SSL_ERROR_WANT_READ) { | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ } | + } | ||||
+ | + | ||||
+ if (!TEST_true(SSL_write(serverssl, sbuf, sizeof(sbuf)) == sizeof(sbuf))) | + if (!TEST_true(SSL_write(serverssl, sbuf, sizeof(sbuf)) == sizeof(sbuf))) | ||||
+ goto end; | + goto end; | ||||
+ | + | ||||
+ while ((err = SSL_read(clientssl, &cbuf, sizeof(cbuf))) != sizeof(cbuf)) { | + while ((err = SSL_read(clientssl, &cbuf, sizeof(cbuf))) != sizeof(cbuf)) { | ||||
+ if (SSL_get_error(clientssl, err) != SSL_ERROR_WANT_READ) { | + if (SSL_get_error(clientssl, err) != SSL_ERROR_WANT_READ) { | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ } | + } | ||||
+ | + | ||||
+ memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, | + memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, rec_seq_size); | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | + memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, rec_seq_size); | ||||
+ memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, | + memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, rec_seq_size); | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | + memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, 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); | |||||
+ | + | ||||
+ /* verify the payload */ | + /* verify the payload */ | ||||
+ if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf))) | + if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf))) | ||||
+ goto end; | + goto end; | ||||
+ | + | ||||
+ /* ktls is used then kernel sequences are used instead of OpenSSL sequences */ | + /* ktls is used then kernel sequences are used instead of OpenSSL sequences */ | ||||
+ if (clientssl->mode & SSL_MODE_NO_KTLS_TX) { | + if (clientssl->mode & SSL_MODE_NO_KTLS_TX) { | ||||
+ if (!TEST_mem_ne(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_ne(crec_wseq_before, rec_seq_size, | ||||
+ crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + crec_wseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } else { | + } else { | ||||
+ if (!TEST_mem_eq(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_eq(crec_wseq_before, rec_seq_size, | ||||
+ crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + crec_wseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ | + | ||||
+ if (serverssl->mode & SSL_MODE_NO_KTLS_TX) { | + if (serverssl->mode & SSL_MODE_NO_KTLS_TX) { | ||||
+ if (!TEST_mem_ne(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_ne(srec_wseq_before, rec_seq_size, | ||||
+ srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + srec_wseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } else { | + } else { | ||||
+ if (!TEST_mem_eq(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_eq(srec_wseq_before, rec_seq_size, | ||||
+ srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + srec_wseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ | + | ||||
+ if (clientssl->mode & SSL_MODE_NO_KTLS_RX) { | + if (clientssl->mode & SSL_MODE_NO_KTLS_RX) { | ||||
+ if (!TEST_mem_ne(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_ne(crec_rseq_before, rec_seq_size, | ||||
+ crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + crec_rseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } else { | + } else { | ||||
+ if (!TEST_mem_eq(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_eq(crec_rseq_before, rec_seq_size, | ||||
+ crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + crec_rseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ | + | ||||
+ if (serverssl->mode & SSL_MODE_NO_KTLS_RX) { | + if (serverssl->mode & SSL_MODE_NO_KTLS_RX) { | ||||
+ if (!TEST_mem_ne(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_ne(srec_rseq_before, rec_seq_size, | ||||
+ srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + srec_rseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } else { | + } else { | ||||
+ if (!TEST_mem_eq(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, | + if (!TEST_mem_eq(srec_rseq_before, rec_seq_size, | ||||
+ srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) | + srec_rseq_after, rec_seq_size)) | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ | + | ||||
+ return 1; | + return 1; | ||||
+end: | +end: | ||||
+ return 0; | + return 0; | ||||
+} | +} | ||||
+ | + | ||||
+static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, | +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_CTX *cctx = NULL, *sctx = NULL; | ||||
+ SSL *clientssl = NULL, *serverssl = NULL; | + SSL *clientssl = NULL, *serverssl = NULL; | ||||
+ int testresult = 0; | + int testresult = 0; | ||||
+ int cfd, sfd; | + int cfd, sfd; | ||||
+ | + | ||||
+ if (!TEST_true(create_test_sockets(&cfd, &sfd))) | + if (!TEST_true(create_test_sockets(&cfd, &sfd))) | ||||
+ goto end; | + goto end; | ||||
+ | + | ||||
+ /* Skip this test if the platform does not support ktls */ | + /* Skip this test if the platform does not support ktls */ | ||||
+ if (!ktls_chk_platform(cfd)) | + if (!ktls_chk_platform(cfd)) | ||||
+ return 1; | + return 1; | ||||
+ | + | ||||
+ /* Create a session based on SHA-256 */ | + /* Create a session based on SHA-256 */ | ||||
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), | + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), | ||||
+ TLS_client_method(), | + TLS_client_method(), | ||||
+ TLS1_2_VERSION, TLS1_2_VERSION, | + tls_version, tls_version, | ||||
+ &sctx, &cctx, cert, privkey)) | + &sctx, &cctx, cert, privkey)) | ||||
+ || !TEST_true(SSL_CTX_set_cipher_list(cctx, | + || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) | ||||
+ "AES128-GCM-SHA256")) | + || !TEST_true(SSL_CTX_set_cipher_list(sctx, cipher)) | ||||
+ || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, | + || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, | ||||
+ &clientssl, sfd, cfd))) | + &clientssl, sfd, cfd))) | ||||
+ goto end; | + goto end; | ||||
+ | + | ||||
+ if (!cis_ktls_tx) { | + if (!cis_ktls_tx) { | ||||
+ if (!TEST_true(SSL_set_mode(clientssl, SSL_MODE_NO_KTLS_TX))) | + if (!TEST_true(SSL_set_mode(clientssl, SSL_MODE_NO_KTLS_TX))) | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
+ if (!sis_ktls_rx) { | + if (!sis_ktls_rx) { | ||||
+ if (!TEST_false(BIO_get_ktls_recv(serverssl->rbio))) | + if (!TEST_false(BIO_get_ktls_recv(serverssl->rbio))) | ||||
+ goto end; | + goto end; | ||||
+ } else { | + } else { | ||||
+ if (!TEST_true(BIO_get_ktls_recv(serverssl->rbio))) | + if (!TEST_true(BIO_get_ktls_recv(serverssl->rbio))) | ||||
+ goto end; | + 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; | + goto end; | ||||
+ | + | ||||
+ testresult = 1; | + testresult = 1; | ||||
+end: | +end: | ||||
+ if (clientssl) { | + if (clientssl) { | ||||
+ SSL_shutdown(clientssl); | + SSL_shutdown(clientssl); | ||||
+ SSL_free(clientssl); | + SSL_free(clientssl); | ||||
+ } | + } | ||||
+ if (serverssl) { | + if (serverssl) { | ||||
+ SSL_shutdown(serverssl); | + SSL_shutdown(serverssl); | ||||
+ SSL_free(serverssl); | + SSL_free(serverssl); | ||||
+ } | + } | ||||
+ SSL_CTX_free(sctx); | + SSL_CTX_free(sctx); | ||||
+ SSL_CTX_free(cctx); | + SSL_CTX_free(cctx); | ||||
+ serverssl = clientssl = NULL; | + serverssl = clientssl = NULL; | ||||
+ return testresult; | + return testresult; | ||||
+} | +} | ||||
+ | + | ||||
+#define SENDFILE_SZ (16 * 4096) | +#define SENDFILE_SZ (16 * 4096) | ||||
+#define SENDFILE_CHUNK (4 * 4096) | +#define SENDFILE_CHUNK (4 * 4096) | ||||
+#define min(a,b) ((a) > (b) ? (b) : (a)) | +#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_CTX *cctx = NULL, *sctx = NULL; | ||||
+ SSL *clientssl = NULL, *serverssl = NULL; | + SSL *clientssl = NULL, *serverssl = NULL; | ||||
+ unsigned char *buf, *buf_dst; | + unsigned char *buf, *buf_dst; | ||||
+ BIO *out = NULL, *in = NULL; | + BIO *out = NULL, *in = NULL; | ||||
+ int cfd, sfd, ffd, err; | + int cfd, sfd, ffd, err; | ||||
+ ssize_t chunk_size = 0; | + ssize_t chunk_size = 0; | ||||
+ off_t chunk_off = 0; | + off_t chunk_off = 0; | ||||
Show All 10 Lines | |||||
+ if (!ktls_chk_platform(sfd)) { | + if (!ktls_chk_platform(sfd)) { | ||||
+ testresult = 1; | + testresult = 1; | ||||
+ goto end; | + goto end; | ||||
+ } | + } | ||||
+ | + | ||||
+ /* Create a session based on SHA-256 */ | + /* Create a session based on SHA-256 */ | ||||
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), | + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), | ||||
+ TLS_client_method(), | + TLS_client_method(), | ||||
+ TLS1_2_VERSION, TLS1_2_VERSION, | + tls_version, tls_version, | ||||
+ &sctx, &cctx, cert, privkey)) | + &sctx, &cctx, cert, privkey)) | ||||
+ || !TEST_true(SSL_CTX_set_cipher_list(cctx, | + || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) | ||||
+ "AES128-GCM-SHA256")) | + || !TEST_true(SSL_CTX_set_cipher_list(sctx, cipher)) | ||||
+ || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, | + || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, | ||||
+ &clientssl, sfd, cfd))) | + &clientssl, sfd, cfd))) | ||||
+ goto end; | + goto end; | ||||
+ | + | ||||
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, | + if (!TEST_true(create_ssl_connection(serverssl, clientssl, | ||||
+ SSL_ERROR_NONE)) | + SSL_ERROR_NONE)) | ||||
+ || !TEST_true(BIO_get_ktls_send(serverssl->wbio))) | + || !TEST_true(BIO_get_ktls_send(serverssl->wbio))) | ||||
+ goto end; | + goto end; | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
+ serverssl = clientssl = NULL; | + serverssl = clientssl = NULL; | ||||
+ BIO_free(out); | + BIO_free(out); | ||||
+ BIO_free(in); | + BIO_free(in); | ||||
+ OPENSSL_free(buf); | + OPENSSL_free(buf); | ||||
+ OPENSSL_free(buf_dst); | + OPENSSL_free(buf_dst); | ||||
+ return testresult; | + 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) | + if (test > 15) { | ||||
+{ | +#if defined(OPENSSL_NO_TLS1_3) | ||||
+ return execute_test_ktls(1, 0, 0, 0); | + 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) | + cis_ktls_tx = (test & 1) != 0; | ||||
+{ | + cis_ktls_rx = (test & 2) != 0; | ||||
+ return execute_test_ktls(0, 1, 0, 0); | + sis_ktls_tx = (test & 4) != 0; | ||||
+} | + sis_ktls_rx = (test & 8) != 0; | ||||
+ | + | ||||
+static int test_ktls_client_no_txrx_server(void) | +#if defined(OPENSSL_NO_KTLS_RX) | ||||
+{ | + if (cis_ktls_rx || sis_ktls_rx) | ||||
+ return execute_test_ktls(1, 1, 0, 0); | + 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) | + testresult = 1; | ||||
+{ | +#ifdef OPENSSL_KTLS_AES_GCM_128 | ||||
+ return execute_test_ktls(0, 0, 1, 0); | + 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) | + if (tst > 2) { | ||||
+{ | +#if defined(OPENSSL_NO_TLS1_3) | ||||
+ return execute_test_ktls(0, 1, 1, 0); | + 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) | +#ifndef OPENSSL_KTLS_AES_GCM_128 | ||||
+{ | + if(tst == 0) return 1; | ||||
+ return execute_test_ktls(1, 1, 1, 0); | +#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 | ||||
+#endif | |||||
+ | + | ||||
static int test_large_message_tls(void) | static int test_large_message_tls(void) | ||||
{ | { | ||||
return execute_test_large_message(TLS_server_method(), TLS_client_method(), | 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; | return 0; | ||||
} | } | ||||
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ | +#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) | ||||
+ && !defined(OPENSSL_NO_SOCK) | +#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) | ||||
+ ADD_TEST(test_ktls_no_txrx_client_no_txrx_server); | + ADD_ALL_TESTS(test_ktls, 32); | ||||
+ ADD_TEST(test_ktls_no_rx_client_no_txrx_server); | + ADD_ALL_TESTS(test_ktls_sendfile_anytls, 6); | ||||
+ 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); | |||||
+#endif | +#endif | ||||
+#endif | |||||
ADD_TEST(test_large_message_tls); | ADD_TEST(test_large_message_tls); | ||||
ADD_TEST(test_large_message_tls_read_ahead); | ADD_TEST(test_large_message_tls_read_ahead); | ||||
#ifndef OPENSSL_NO_DTLS | #ifndef OPENSSL_NO_DTLS | ||||
diff --git test/ssltestlib.c test/ssltestlib.c | diff --git test/ssltestlib.c test/ssltestlib.c | ||||
index 456afdf471..bae39823d2 100644 | index 456afdf471..bae39823d2 100644 | ||||
--- test/ssltestlib.c | --- test/ssltestlib.c | ||||
+++ test/ssltestlib.c | +++ test/ssltestlib.c | ||||
@@ -16,6 +16,14 @@ | @@ -16,6 +16,14 @@ | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | |||||
@@ -109,6 +109,8 @@ BIO_get_buffer_num_lines define | @@ -109,6 +109,8 @@ BIO_get_buffer_num_lines define | ||||
BIO_get_cipher_ctx define | BIO_get_cipher_ctx define | ||||
BIO_get_cipher_status define | BIO_get_cipher_status define | ||||
BIO_get_close define | BIO_get_close define | ||||
+BIO_get_ktls_send define | +BIO_get_ktls_send define | ||||
+BIO_get_ktls_recv define | +BIO_get_ktls_recv define | ||||
BIO_get_conn_address define | BIO_get_conn_address define | ||||
BIO_get_conn_hostname define | BIO_get_conn_hostname define | ||||
BIO_get_conn_port definE | BIO_get_conn_port define |