From b1f79e7ce54afc28bfb5dfcfdd379782ed501b0a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 19 Nov 2019 14:12:56 -0800 Subject: [PATCH] Support KTLS on connections using BIO_TYPE_CONNECT. This requires duplicating the KTLS changes from bss_sock.c in bss_conn.c. One difference from BIO_TYPE_SOCKET is that the call to ktls_enable is performed after the socket is created in BIO_socket rather than BIO_new_connect. Some applications such as 'openssl s_time' use connect BIOs instead of socket BIOs. Note that the new connections created for accept BIOs use BIO_TYPE_SOCKET via BIO_new_socket, so bss_acpt.c does not require changes. Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/10489) --- crypto/bio/b_sock2.c | 12 ++++++++++ crypto/bio/bss_conn.c | 54 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/crypto/bio/b_sock2.c b/crypto/bio/b_sock2.c index 942825a8e0..df13d58c71 100644 --- a/crypto/bio/b_sock2.c +++ b/crypto/bio/b_sock2.c @@ -12,6 +12,7 @@ #include #include "bio_local.h" +#include "internal/ktls.h" #include @@ -51,6 +52,17 @@ int BIO_socket(int domain, int socktype, int protocol, int options) BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); return INVALID_SOCKET; } +# ifndef OPENSSL_NO_KTLS + { + /* + * The new socket is created successfully regardless of ktls_enable. + * ktls_enable doesn't change any functionality of the socket, except + * changing the setsockopt to enable the processing of ktls_start. + * Thus, it is not a problem to call it for non-TLS sockets. + */ + ktls_enable(sock); + } +# endif return sock; } diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index 6c554ff6e6..87009fb61d 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -11,6 +11,7 @@ #include #include "bio_local.h" +#include "internal/ktls.h" #ifndef OPENSSL_NO_SOCK @@ -20,6 +21,9 @@ typedef struct bio_connect_st { char *param_hostname; char *param_service; int connect_mode; +# ifndef OPENSSL_NO_KTLS + unsigned char record_type; +# endif BIO_ADDRINFO *addr_first; const BIO_ADDRINFO *addr_iter; @@ -308,7 +312,12 @@ static int conn_read(BIO *b, char *out, int outl) if (out != NULL) { clear_socket_error(); - ret = readsocket(b->num, out, outl); +# ifndef OPENSSL_NO_KTLS + if (BIO_get_ktls_recv(b)) + ret = ktls_read_record(b->num, out, outl); + else +# endif + ret = readsocket(b->num, out, outl); BIO_clear_retry_flags(b); if (ret <= 0) { if (BIO_sock_should_retry(ret)) @@ -333,7 +342,16 @@ static int conn_write(BIO *b, const char *in, int inl) } clear_socket_error(); - ret = writesocket(b->num, in, inl); +# ifndef OPENSSL_NO_KTLS + if (BIO_should_ktls_ctrl_msg_flag(b)) { + ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl); + if (ret >= 0) { + ret = inl; + BIO_clear_ktls_ctrl_msg_flag(b); + } + } else +# endif + ret = writesocket(b->num, in, inl); BIO_clear_retry_flags(b); if (ret <= 0) { if (BIO_sock_should_retry(ret)) @@ -349,6 +367,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) const char **pptr = NULL; long ret = 1; BIO_CONNECT *data; +# ifndef OPENSSL_NO_KTLS +# ifdef __FreeBSD__ + struct tls_enable *crypto_info; +# else + struct tls12_crypto_info_aes_gcm_128 *crypto_info; +# endif +# endif data = (BIO_CONNECT *)b->ptr; @@ -497,6 +522,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_EOF: ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; break; +# ifndef OPENSSL_NO_KTLS + case BIO_CTRL_SET_KTLS: +# ifdef __FreeBSD__ + crypto_info = (struct tls_enable *)ptr; +# else + crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr; +# endif + ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num); + if (ret) + BIO_set_ktls_flag(b, num); + break; + case BIO_CTRL_GET_KTLS_SEND: + return BIO_should_ktls_flag(b, 1); + case BIO_CTRL_GET_KTLS_RECV: + return BIO_should_ktls_flag(b, 0); + case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG: + BIO_set_ktls_ctrl_msg_flag(b); + data->record_type = num; + ret = 0; + break; + case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG: + BIO_clear_ktls_ctrl_msg_flag(b); + ret = 0; + break; +# endif default: ret = 0; break; -- 2.25.1