summaryrefslogtreecommitdiffstats
path: root/crypto/bio
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-11-19 14:12:56 -0800
committerTomas Mraz <tmraz@fedoraproject.org>2020-03-16 10:41:51 +0100
commitb1f79e7ce54afc28bfb5dfcfdd379782ed501b0a (patch)
treecb508795d111211912bb91cfaef00e76debd2952 /crypto/bio
parentfda127beb2b3c029741573b0dd931295b3446fd2 (diff)
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 <matt@openssl.org> Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/10489)
Diffstat (limited to 'crypto/bio')
-rw-r--r--crypto/bio/b_sock2.c12
-rw-r--r--crypto/bio/bss_conn.c54
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 <errno.h>
#include "bio_local.h"
+#include "internal/ktls.h"
#include <openssl/err.h>
@@ -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 <errno.h>
#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;