diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2023-04-19 18:48:50 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2023-04-19 18:48:50 -0700 |
| commit | a5962e0a8b7b0da2350b4baeefaf7dfa3377bc89 (patch) | |
| tree | 3b7255875d4f657e0cf0e3087ecab918f3d01ba3 /include | |
| parent | f1836a424518a09b17ee2b69e81e9477321a0aff (diff) | |
| parent | 88232ec1ec5ecf4aa5de439cff3d5e2b7adcac93 (diff) | |
| download | lwn-a5962e0a8b7b0da2350b4baeefaf7dfa3377bc89.tar.gz lwn-a5962e0a8b7b0da2350b4baeefaf7dfa3377bc89.zip | |
Merge branch 'another-crack-at-a-handshake-upcall-mechanism'
Chuck Lever says:
====================
Another crack at a handshake upcall mechanism
Here is v10 of a series to add generic support for transport layer
security handshake on behalf of kernel socket consumers (user space
consumers use a security library directly, of course). A summary of
the purpose of these patches is archived here:
https://lore.kernel.org/netdev/1DE06BB1-6BA9-4DB4-B2AA-07DE532963D6@oracle.com/
The first patch in the series applies to the top-level .gitignore
file to address the build warnings reported a few days ago. I intend
to submit that separately. I'd like you to consider taking the rest
of this series for v6.4.
The full patch set to support SunRPC with TLSv1.3 is available in
the topic-rpc-with-tls-upcall branch here, based on net-next/main:
https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
This patch set includes support for in-transit confidentiality and
peer authentication for both the Linux NFS client and server.
A user space handshake agent for TLSv1.3 to go along with the kernel
patches is available in the "main" branch here:
https://github.com/oracle/ktls-utils
====================
Link: https://lore.kernel.org/r/168174169259.9520.1911007910797225963.stgit@91.116.238.104.host.secureserver.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/handshake.h | 43 | ||||
| -rw-r--r-- | include/trace/events/handshake.h | 159 | ||||
| -rw-r--r-- | include/uapi/linux/handshake.h | 73 |
3 files changed, 275 insertions, 0 deletions
diff --git a/include/net/handshake.h b/include/net/handshake.h new file mode 100644 index 000000000000..3352b1ab43b3 --- /dev/null +++ b/include/net/handshake.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Generic netlink HANDSHAKE service. + * + * Author: Chuck Lever <chuck.lever@oracle.com> + * + * Copyright (c) 2023, Oracle and/or its affiliates. + */ + +#ifndef _NET_HANDSHAKE_H +#define _NET_HANDSHAKE_H + +enum { + TLS_NO_KEYRING = 0, + TLS_NO_PEERID = 0, + TLS_NO_CERT = 0, + TLS_NO_PRIVKEY = 0, +}; + +typedef void (*tls_done_func_t)(void *data, int status, + key_serial_t peerid); + +struct tls_handshake_args { + struct socket *ta_sock; + tls_done_func_t ta_done; + void *ta_data; + unsigned int ta_timeout_ms; + key_serial_t ta_keyring; + key_serial_t ta_my_cert; + key_serial_t ta_my_privkey; + unsigned int ta_num_peerids; + key_serial_t ta_my_peerids[5]; +}; + +int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags); +int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags); +int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags); +int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags); +int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags); + +bool tls_handshake_cancel(struct sock *sk); + +#endif /* _NET_HANDSHAKE_H */ diff --git a/include/trace/events/handshake.h b/include/trace/events/handshake.h new file mode 100644 index 000000000000..8dadcab5f12a --- /dev/null +++ b/include/trace/events/handshake.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM handshake + +#if !defined(_TRACE_HANDSHAKE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HANDSHAKE_H + +#include <linux/net.h> +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(handshake_event_class, + TP_PROTO( + const struct net *net, + const struct handshake_req *req, + const struct sock *sk + ), + TP_ARGS(net, req, sk), + TP_STRUCT__entry( + __field(const void *, req) + __field(const void *, sk) + __field(unsigned int, netns_ino) + ), + TP_fast_assign( + __entry->req = req; + __entry->sk = sk; + __entry->netns_ino = net->ns.inum; + ), + TP_printk("req=%p sk=%p", + __entry->req, __entry->sk + ) +); +#define DEFINE_HANDSHAKE_EVENT(name) \ + DEFINE_EVENT(handshake_event_class, name, \ + TP_PROTO( \ + const struct net *net, \ + const struct handshake_req *req, \ + const struct sock *sk \ + ), \ + TP_ARGS(net, req, sk)) + +DECLARE_EVENT_CLASS(handshake_fd_class, + TP_PROTO( + const struct net *net, + const struct handshake_req *req, + const struct sock *sk, + int fd + ), + TP_ARGS(net, req, sk, fd), + TP_STRUCT__entry( + __field(const void *, req) + __field(const void *, sk) + __field(int, fd) + __field(unsigned int, netns_ino) + ), + TP_fast_assign( + __entry->req = req; + __entry->sk = req->hr_sk; + __entry->fd = fd; + __entry->netns_ino = net->ns.inum; + ), + TP_printk("req=%p sk=%p fd=%d", + __entry->req, __entry->sk, __entry->fd + ) +); +#define DEFINE_HANDSHAKE_FD_EVENT(name) \ + DEFINE_EVENT(handshake_fd_class, name, \ + TP_PROTO( \ + const struct net *net, \ + const struct handshake_req *req, \ + const struct sock *sk, \ + int fd \ + ), \ + TP_ARGS(net, req, sk, fd)) + +DECLARE_EVENT_CLASS(handshake_error_class, + TP_PROTO( + const struct net *net, + const struct handshake_req *req, + const struct sock *sk, + int err + ), + TP_ARGS(net, req, sk, err), + TP_STRUCT__entry( + __field(const void *, req) + __field(const void *, sk) + __field(int, err) + __field(unsigned int, netns_ino) + ), + TP_fast_assign( + __entry->req = req; + __entry->sk = sk; + __entry->err = err; + __entry->netns_ino = net->ns.inum; + ), + TP_printk("req=%p sk=%p err=%d", + __entry->req, __entry->sk, __entry->err + ) +); +#define DEFINE_HANDSHAKE_ERROR(name) \ + DEFINE_EVENT(handshake_error_class, name, \ + TP_PROTO( \ + const struct net *net, \ + const struct handshake_req *req, \ + const struct sock *sk, \ + int err \ + ), \ + TP_ARGS(net, req, sk, err)) + + +/* + * Request lifetime events + */ + +DEFINE_HANDSHAKE_EVENT(handshake_submit); +DEFINE_HANDSHAKE_ERROR(handshake_submit_err); +DEFINE_HANDSHAKE_EVENT(handshake_cancel); +DEFINE_HANDSHAKE_EVENT(handshake_cancel_none); +DEFINE_HANDSHAKE_EVENT(handshake_cancel_busy); +DEFINE_HANDSHAKE_EVENT(handshake_destruct); + + +TRACE_EVENT(handshake_complete, + TP_PROTO( + const struct net *net, + const struct handshake_req *req, + const struct sock *sk, + int status + ), + TP_ARGS(net, req, sk, status), + TP_STRUCT__entry( + __field(const void *, req) + __field(const void *, sk) + __field(int, status) + __field(unsigned int, netns_ino) + ), + TP_fast_assign( + __entry->req = req; + __entry->sk = sk; + __entry->status = status; + __entry->netns_ino = net->ns.inum; + ), + TP_printk("req=%p sk=%p status=%d", + __entry->req, __entry->sk, __entry->status + ) +); + +/* + * Netlink events + */ + +DEFINE_HANDSHAKE_ERROR(handshake_notify_err); +DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_accept); +DEFINE_HANDSHAKE_ERROR(handshake_cmd_accept_err); +DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_done); +DEFINE_HANDSHAKE_ERROR(handshake_cmd_done_err); + +#endif /* _TRACE_HANDSHAKE_H */ + +#include <trace/define_trace.h> diff --git a/include/uapi/linux/handshake.h b/include/uapi/linux/handshake.h new file mode 100644 index 000000000000..1de4d0b95325 --- /dev/null +++ b/include/uapi/linux/handshake.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/handshake.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_HANDSHAKE_H +#define _UAPI_LINUX_HANDSHAKE_H + +#define HANDSHAKE_FAMILY_NAME "handshake" +#define HANDSHAKE_FAMILY_VERSION 1 + +enum handshake_handler_class { + HANDSHAKE_HANDLER_CLASS_NONE, + HANDSHAKE_HANDLER_CLASS_TLSHD, + HANDSHAKE_HANDLER_CLASS_MAX, +}; + +enum handshake_msg_type { + HANDSHAKE_MSG_TYPE_UNSPEC, + HANDSHAKE_MSG_TYPE_CLIENTHELLO, + HANDSHAKE_MSG_TYPE_SERVERHELLO, +}; + +enum handshake_auth { + HANDSHAKE_AUTH_UNSPEC, + HANDSHAKE_AUTH_UNAUTH, + HANDSHAKE_AUTH_PSK, + HANDSHAKE_AUTH_X509, +}; + +enum { + HANDSHAKE_A_X509_CERT = 1, + HANDSHAKE_A_X509_PRIVKEY, + + __HANDSHAKE_A_X509_MAX, + HANDSHAKE_A_X509_MAX = (__HANDSHAKE_A_X509_MAX - 1) +}; + +enum { + HANDSHAKE_A_ACCEPT_SOCKFD = 1, + HANDSHAKE_A_ACCEPT_HANDLER_CLASS, + HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, + HANDSHAKE_A_ACCEPT_TIMEOUT, + HANDSHAKE_A_ACCEPT_AUTH_MODE, + HANDSHAKE_A_ACCEPT_PEER_IDENTITY, + HANDSHAKE_A_ACCEPT_CERTIFICATE, + + __HANDSHAKE_A_ACCEPT_MAX, + HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1) +}; + +enum { + HANDSHAKE_A_DONE_STATUS = 1, + HANDSHAKE_A_DONE_SOCKFD, + HANDSHAKE_A_DONE_REMOTE_AUTH, + + __HANDSHAKE_A_DONE_MAX, + HANDSHAKE_A_DONE_MAX = (__HANDSHAKE_A_DONE_MAX - 1) +}; + +enum { + HANDSHAKE_CMD_READY = 1, + HANDSHAKE_CMD_ACCEPT, + HANDSHAKE_CMD_DONE, + + __HANDSHAKE_CMD_MAX, + HANDSHAKE_CMD_MAX = (__HANDSHAKE_CMD_MAX - 1) +}; + +#define HANDSHAKE_MCGRP_NONE "none" +#define HANDSHAKE_MCGRP_TLSHD "tlshd" + +#endif /* _UAPI_LINUX_HANDSHAKE_H */ |
