Skip to content

Commit 3b3009e

Browse files
chuckleverkuba-moo
authored andcommitted
net/handshake: Create a NETLINK service for handling handshake requests
When a kernel consumer needs a transport layer security session, it first needs a handshake to negotiate and establish a session. This negotiation can be done in user space via one of the several existing library implementations, or it can be done in the kernel. No in-kernel handshake implementations yet exist. In their absence, we add a netlink service that can: a. Notify a user space daemon that a handshake is needed. b. Once notified, the daemon calls the kernel back via this netlink service to get the handshake parameters, including an open socket on which to establish the session. c. Once the handshake is complete, the daemon reports the session status and other information via a second netlink operation. This operation marks that it is safe for the kernel to use the open socket and the security session established there. The notification service uses a multicast group. Each handshake mechanism (eg, tlshd) adopts its own group number so that the handshake services are completely independent of one another. The kernel can then tell via netlink_has_listeners() whether a handshake service is active and prepared to handle a handshake request. A new netlink operation, ACCEPT, acts like accept(2) in that it instantiates a file descriptor in the user space daemon's fd table. If this operation is successful, the reply carries the fd number, which can be treated as an open and ready file descriptor. While user space is performing the handshake, the kernel keeps its muddy paws off the open socket. A second new netlink operation, DONE, indicates that the user space daemon is finished with the socket and it is safe for the kernel to use again. The operation also indicates whether a session was established successfully. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 2bc42f4 commit 3b3009e

File tree

13 files changed

+1211
-0
lines changed

13 files changed

+1211
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2+
#
3+
# Author: Chuck Lever <chuck.lever@oracle.com>
4+
#
5+
# Copyright (c) 2023, Oracle and/or its affiliates.
6+
#
7+
8+
name: handshake
9+
10+
protocol: genetlink
11+
12+
doc: Netlink protocol to request a transport layer security handshake.
13+
14+
definitions:
15+
-
16+
type: enum
17+
name: handler-class
18+
value-start: 0
19+
entries: [ none, max ]
20+
-
21+
type: enum
22+
name: msg-type
23+
value-start: 0
24+
entries: [ unspec, clienthello, serverhello ]
25+
-
26+
type: enum
27+
name: auth
28+
value-start: 0
29+
entries: [ unspec, unauth, psk, x509 ]
30+
31+
attribute-sets:
32+
-
33+
name: x509
34+
attributes:
35+
-
36+
name: cert
37+
type: u32
38+
-
39+
name: privkey
40+
type: u32
41+
-
42+
name: accept
43+
attributes:
44+
-
45+
name: sockfd
46+
type: u32
47+
-
48+
name: handler-class
49+
type: u32
50+
enum: handler-class
51+
-
52+
name: message-type
53+
type: u32
54+
enum: msg-type
55+
-
56+
name: timeout
57+
type: u32
58+
-
59+
name: auth-mode
60+
type: u32
61+
enum: auth
62+
-
63+
name: peer-identity
64+
type: u32
65+
multi-attr: true
66+
-
67+
name: certificate
68+
type: nest
69+
nested-attributes: x509
70+
multi-attr: true
71+
-
72+
name: done
73+
attributes:
74+
-
75+
name: status
76+
type: u32
77+
-
78+
name: sockfd
79+
type: u32
80+
-
81+
name: remote-auth
82+
type: u32
83+
multi-attr: true
84+
85+
operations:
86+
list:
87+
-
88+
name: ready
89+
doc: Notify handlers that a new handshake request is waiting
90+
notify: accept
91+
-
92+
name: accept
93+
doc: Handler retrieves next queued handshake request
94+
attribute-set: accept
95+
flags: [ admin-perm ]
96+
do:
97+
request:
98+
attributes:
99+
- handler-class
100+
reply:
101+
attributes:
102+
- sockfd
103+
- message-type
104+
- timeout
105+
- auth-mode
106+
- peer-identity
107+
- certificate
108+
-
109+
name: done
110+
doc: Handler reports handshake completion
111+
attribute-set: done
112+
do:
113+
request:
114+
attributes:
115+
- status
116+
- sockfd
117+
- remote-auth
118+
119+
mcast-groups:
120+
list:
121+
-
122+
name: none

MAINTAINERS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8947,6 +8947,15 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
89478947
T: git git://linuxtv.org/anttip/media_tree.git
89488948
F: drivers/media/usb/hackrf/
89498949

8950+
HANDSHAKE UPCALL FOR TRANSPORT LAYER SECURITY
8951+
M: Chuck Lever <chuck.lever@oracle.com>
8952+
L: kernel-tls-handshake@lists.linux.dev
8953+
L: netdev@vger.kernel.org
8954+
S: Maintained
8955+
F: Documentation/netlink/specs/handshake.yaml
8956+
F: include/trace/events/handshake.h
8957+
F: net/handshake/
8958+
89508959
HANTRO VPU CODEC DRIVER
89518960
M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
89528961
M: Philipp Zabel <p.zabel@pengutronix.de>

include/trace/events/handshake.h

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#undef TRACE_SYSTEM
3+
#define TRACE_SYSTEM handshake
4+
5+
#if !defined(_TRACE_HANDSHAKE_H) || defined(TRACE_HEADER_MULTI_READ)
6+
#define _TRACE_HANDSHAKE_H
7+
8+
#include <linux/net.h>
9+
#include <linux/tracepoint.h>
10+
11+
DECLARE_EVENT_CLASS(handshake_event_class,
12+
TP_PROTO(
13+
const struct net *net,
14+
const struct handshake_req *req,
15+
const struct sock *sk
16+
),
17+
TP_ARGS(net, req, sk),
18+
TP_STRUCT__entry(
19+
__field(const void *, req)
20+
__field(const void *, sk)
21+
__field(unsigned int, netns_ino)
22+
),
23+
TP_fast_assign(
24+
__entry->req = req;
25+
__entry->sk = sk;
26+
__entry->netns_ino = net->ns.inum;
27+
),
28+
TP_printk("req=%p sk=%p",
29+
__entry->req, __entry->sk
30+
)
31+
);
32+
#define DEFINE_HANDSHAKE_EVENT(name) \
33+
DEFINE_EVENT(handshake_event_class, name, \
34+
TP_PROTO( \
35+
const struct net *net, \
36+
const struct handshake_req *req, \
37+
const struct sock *sk \
38+
), \
39+
TP_ARGS(net, req, sk))
40+
41+
DECLARE_EVENT_CLASS(handshake_fd_class,
42+
TP_PROTO(
43+
const struct net *net,
44+
const struct handshake_req *req,
45+
const struct sock *sk,
46+
int fd
47+
),
48+
TP_ARGS(net, req, sk, fd),
49+
TP_STRUCT__entry(
50+
__field(const void *, req)
51+
__field(const void *, sk)
52+
__field(int, fd)
53+
__field(unsigned int, netns_ino)
54+
),
55+
TP_fast_assign(
56+
__entry->req = req;
57+
__entry->sk = req->hr_sk;
58+
__entry->fd = fd;
59+
__entry->netns_ino = net->ns.inum;
60+
),
61+
TP_printk("req=%p sk=%p fd=%d",
62+
__entry->req, __entry->sk, __entry->fd
63+
)
64+
);
65+
#define DEFINE_HANDSHAKE_FD_EVENT(name) \
66+
DEFINE_EVENT(handshake_fd_class, name, \
67+
TP_PROTO( \
68+
const struct net *net, \
69+
const struct handshake_req *req, \
70+
const struct sock *sk, \
71+
int fd \
72+
), \
73+
TP_ARGS(net, req, sk, fd))
74+
75+
DECLARE_EVENT_CLASS(handshake_error_class,
76+
TP_PROTO(
77+
const struct net *net,
78+
const struct handshake_req *req,
79+
const struct sock *sk,
80+
int err
81+
),
82+
TP_ARGS(net, req, sk, err),
83+
TP_STRUCT__entry(
84+
__field(const void *, req)
85+
__field(const void *, sk)
86+
__field(int, err)
87+
__field(unsigned int, netns_ino)
88+
),
89+
TP_fast_assign(
90+
__entry->req = req;
91+
__entry->sk = sk;
92+
__entry->err = err;
93+
__entry->netns_ino = net->ns.inum;
94+
),
95+
TP_printk("req=%p sk=%p err=%d",
96+
__entry->req, __entry->sk, __entry->err
97+
)
98+
);
99+
#define DEFINE_HANDSHAKE_ERROR(name) \
100+
DEFINE_EVENT(handshake_error_class, name, \
101+
TP_PROTO( \
102+
const struct net *net, \
103+
const struct handshake_req *req, \
104+
const struct sock *sk, \
105+
int err \
106+
), \
107+
TP_ARGS(net, req, sk, err))
108+
109+
110+
/*
111+
* Request lifetime events
112+
*/
113+
114+
DEFINE_HANDSHAKE_EVENT(handshake_submit);
115+
DEFINE_HANDSHAKE_ERROR(handshake_submit_err);
116+
DEFINE_HANDSHAKE_EVENT(handshake_cancel);
117+
DEFINE_HANDSHAKE_EVENT(handshake_cancel_none);
118+
DEFINE_HANDSHAKE_EVENT(handshake_cancel_busy);
119+
DEFINE_HANDSHAKE_EVENT(handshake_destruct);
120+
121+
122+
TRACE_EVENT(handshake_complete,
123+
TP_PROTO(
124+
const struct net *net,
125+
const struct handshake_req *req,
126+
const struct sock *sk,
127+
int status
128+
),
129+
TP_ARGS(net, req, sk, status),
130+
TP_STRUCT__entry(
131+
__field(const void *, req)
132+
__field(const void *, sk)
133+
__field(int, status)
134+
__field(unsigned int, netns_ino)
135+
),
136+
TP_fast_assign(
137+
__entry->req = req;
138+
__entry->sk = sk;
139+
__entry->status = status;
140+
__entry->netns_ino = net->ns.inum;
141+
),
142+
TP_printk("req=%p sk=%p status=%d",
143+
__entry->req, __entry->sk, __entry->status
144+
)
145+
);
146+
147+
/*
148+
* Netlink events
149+
*/
150+
151+
DEFINE_HANDSHAKE_ERROR(handshake_notify_err);
152+
DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_accept);
153+
DEFINE_HANDSHAKE_ERROR(handshake_cmd_accept_err);
154+
DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_done);
155+
DEFINE_HANDSHAKE_ERROR(handshake_cmd_done_err);
156+
157+
#endif /* _TRACE_HANDSHAKE_H */
158+
159+
#include <trace/define_trace.h>

include/uapi/linux/handshake.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
2+
/* Do not edit directly, auto-generated from: */
3+
/* Documentation/netlink/specs/handshake.yaml */
4+
/* YNL-GEN uapi header */
5+
6+
#ifndef _UAPI_LINUX_HANDSHAKE_H
7+
#define _UAPI_LINUX_HANDSHAKE_H
8+
9+
#define HANDSHAKE_FAMILY_NAME "handshake"
10+
#define HANDSHAKE_FAMILY_VERSION 1
11+
12+
enum handshake_handler_class {
13+
HANDSHAKE_HANDLER_CLASS_NONE,
14+
HANDSHAKE_HANDLER_CLASS_MAX,
15+
};
16+
17+
enum handshake_msg_type {
18+
HANDSHAKE_MSG_TYPE_UNSPEC,
19+
HANDSHAKE_MSG_TYPE_CLIENTHELLO,
20+
HANDSHAKE_MSG_TYPE_SERVERHELLO,
21+
};
22+
23+
enum handshake_auth {
24+
HANDSHAKE_AUTH_UNSPEC,
25+
HANDSHAKE_AUTH_UNAUTH,
26+
HANDSHAKE_AUTH_PSK,
27+
HANDSHAKE_AUTH_X509,
28+
};
29+
30+
enum {
31+
HANDSHAKE_A_X509_CERT = 1,
32+
HANDSHAKE_A_X509_PRIVKEY,
33+
34+
__HANDSHAKE_A_X509_MAX,
35+
HANDSHAKE_A_X509_MAX = (__HANDSHAKE_A_X509_MAX - 1)
36+
};
37+
38+
enum {
39+
HANDSHAKE_A_ACCEPT_SOCKFD = 1,
40+
HANDSHAKE_A_ACCEPT_HANDLER_CLASS,
41+
HANDSHAKE_A_ACCEPT_MESSAGE_TYPE,
42+
HANDSHAKE_A_ACCEPT_TIMEOUT,
43+
HANDSHAKE_A_ACCEPT_AUTH_MODE,
44+
HANDSHAKE_A_ACCEPT_PEER_IDENTITY,
45+
HANDSHAKE_A_ACCEPT_CERTIFICATE,
46+
47+
__HANDSHAKE_A_ACCEPT_MAX,
48+
HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1)
49+
};
50+
51+
enum {
52+
HANDSHAKE_A_DONE_STATUS = 1,
53+
HANDSHAKE_A_DONE_SOCKFD,
54+
HANDSHAKE_A_DONE_REMOTE_AUTH,
55+
56+
__HANDSHAKE_A_DONE_MAX,
57+
HANDSHAKE_A_DONE_MAX = (__HANDSHAKE_A_DONE_MAX - 1)
58+
};
59+
60+
enum {
61+
HANDSHAKE_CMD_READY = 1,
62+
HANDSHAKE_CMD_ACCEPT,
63+
HANDSHAKE_CMD_DONE,
64+
65+
__HANDSHAKE_CMD_MAX,
66+
HANDSHAKE_CMD_MAX = (__HANDSHAKE_CMD_MAX - 1)
67+
};
68+
69+
#define HANDSHAKE_MCGRP_NONE "none"
70+
71+
#endif /* _UAPI_LINUX_HANDSHAKE_H */

net/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ source "net/iucv/Kconfig"
6868
source "net/smc/Kconfig"
6969
source "net/xdp/Kconfig"
7070

71+
config NET_HANDSHAKE
72+
bool
73+
depends on SUNRPC || NVME_TARGET_TCP || NVME_TCP
74+
default y
75+
7176
config INET
7277
bool "TCP/IP networking"
7378
help

net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ obj-$(CONFIG_NET_NCSI) += ncsi/
7979
obj-$(CONFIG_XDP_SOCKETS) += xdp/
8080
obj-$(CONFIG_MPTCP) += mptcp/
8181
obj-$(CONFIG_MCTP) += mctp/
82+
obj-$(CONFIG_NET_HANDSHAKE) += handshake/

net/handshake/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
#
3+
# Makefile for the Generic HANDSHAKE service
4+
#
5+
# Author: Chuck Lever <chuck.lever@oracle.com>
6+
#
7+
# Copyright (c) 2023, Oracle and/or its affiliates.
8+
#
9+
10+
obj-y += handshake.o
11+
handshake-y := genl.o netlink.o request.o trace.o

0 commit comments

Comments
 (0)