@@ -7,7 +7,8 @@ CFLAGS_trace.o := -I$(src)
obj-$(CONFIG_TLS) += tls.o
-tls-y := af_tlsh.o tls_main.o tls_sw.o tls_proc.o trace.o tls_strp.o
+tls-y := af_tlsh.o tls_handshake.o tls_main.o tls_sw.o tls_proc.o \
+ trace.o tls_strp.o
tls-$(CONFIG_TLS_TOE) += tls_toe.o
tls-$(CONFIG_TLS_DEVICE) += tls_device.o tls_device_fallback.o
new file mode 100644
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TLS handshake consumer API
+ *
+ * Author: Chuck Lever <chuck.lever@oracle.com>
+ *
+ * Copyright (c) 2023, Oracle and/or its affiliates.
+ *
+ * When a kernel TLS consumer wants to establish a TLS session, it
+ * uses the API calls in this file to request a TLS handshake.
+ *
+ * This is an asynchronous API. These calls do not sleep.
+ */
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+#include <net/tls.h>
+#include <net/tlsh.h>
+
+#include "tls.h"
+
+/**
+ * tls_client_hello_anon - request an anonymous TLS handshake on a socket
+ * @sock: connected socket on which to perform the handshake
+ * @done: function to call when the handshake has completed
+ * @data: token to pass back to @done
+ * @priorities: GnuTLS TLS priorities string
+ *
+ * Return values:
+ * %0: Handshake request enqueue; ->done will be called when complete
+ * %-ENOENT: No user agent is available
+ * %-ENOMEM: Memory allocation failed
+ */
+int tls_client_hello_anon(struct socket *sock,
+ void (*done)(void *data, int status), void *data,
+ const char *priorities)
+{
+ /* Use the listen/accept upcall mechanism */
+ return tlsh_client_hello_anon(sock, done, data, priorities);
+}
+EXPORT_SYMBOL(tls_client_hello_anon);
+
+/**
+ * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket
+ * @sock: connected socket on which to perform the handshake
+ * @done: function to call when the handshake has completed
+ * @data: token to pass back to @done
+ * @priorities: GnuTLS TLS priorities string
+ * @cert: serial number of key containing client's x.509 certificate
+ * @privkey: serial number of key containing client's private key
+ *
+ * Return values:
+ * %0: Handshake request enqueue; ->done will be called when complete
+ * %-ENOENT: No user agent is available
+ * %-ENOMEM: Memory allocation failed
+ */
+int tls_client_hello_x509(struct socket *sock,
+ void (*done)(void *data, int status), void *data,
+ const char *priorities, key_serial_t cert,
+ key_serial_t privkey)
+{
+ /* Use the listen/accept upcall mechanism */
+ return tlsh_client_hello_x509(sock, done, data, priorities, cert,
+ privkey);
+}
+EXPORT_SYMBOL(tls_client_hello_x509);
+
+/**
+ * tls_client_hello_psk - request a PSK-based TLS handshake on a socket
+ * @sock: connected socket on which to perform the handshake
+ * @done: function to call when the handshake has completed
+ * @data: token to pass back to @done
+ * @priorities: GnuTLS TLS priorities string
+ * @peerid: serial number of key containing TLS identity
+ *
+ * Return values:
+ * %0: Handshake request enqueue; ->done will be called when complete
+ * %-ENOENT: No user agent is available
+ * %-ENOMEM: Memory allocation failed
+ */
+int tls_client_hello_psk(struct socket *sock,
+ void (*done)(void *data, int status), void *data,
+ const char *priorities, key_serial_t peerid)
+{
+ /* Use the listen/accept upcall mechanism */
+ return tlsh_client_hello_psk(sock, done, data, priorities, peerid);
+}
+EXPORT_SYMBOL(tls_client_hello_psk);
We don't want to perturb API consumers whenever the upcall mechanism is changed or replaced. The handshake API therefore is not a part of the listen/accept upcall mechanism, but is a separate fixed component. Create the consumer handshake API in its own source file to make it straightforward to modify the handshake mechanism later. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- net/tls/Makefile | 3 +- net/tls/tls_handshake.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 net/tls/tls_handshake.c