1 // SPDX-License-Identifier: GPL-2.0-only
3 * Establish a TLS session for a kernel socket consumer
4 * using the tlshd user space handler.
6 * Author: Chuck Lever <chuck.lever@oracle.com>
8 * Copyright (c) 2021-2023, Oracle and/or its affiliates.
11 #include <linux/types.h>
12 #include <linux/socket.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/key.h>
19 #include <net/handshake.h>
20 #include <net/genetlink.h>
22 #include <uapi/linux/keyctl.h>
23 #include <uapi/linux/handshake.h>
24 #include "handshake.h"
26 struct tls_handshake_req {
27 void (*th_consumer_done)(void *data, int status,
29 void *th_consumer_data;
32 unsigned int th_timeout_ms;
34 const char *th_peername;
35 key_serial_t th_keyring;
36 key_serial_t th_certificate;
37 key_serial_t th_privkey;
39 unsigned int th_num_peerids;
40 key_serial_t th_peerid[5];
43 static struct tls_handshake_req *
44 tls_handshake_req_init(struct handshake_req *req,
45 const struct tls_handshake_args *args)
47 struct tls_handshake_req *treq = handshake_req_private(req);
49 treq->th_timeout_ms = args->ta_timeout_ms;
50 treq->th_consumer_done = args->ta_done;
51 treq->th_consumer_data = args->ta_data;
52 treq->th_peername = args->ta_peername;
53 treq->th_keyring = args->ta_keyring;
54 treq->th_num_peerids = 0;
55 treq->th_certificate = TLS_NO_CERT;
56 treq->th_privkey = TLS_NO_PRIVKEY;
60 static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
61 struct genl_info *info)
63 struct nlattr *head = nlmsg_attrdata(info->nlhdr, GENL_HDRLEN);
64 int rem, len = nlmsg_attrlen(info->nlhdr, GENL_HDRLEN);
69 nla_for_each_attr(nla, head, len, rem) {
70 if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
75 treq->th_num_peerids = min_t(unsigned int, i,
76 ARRAY_SIZE(treq->th_peerid));
79 nla_for_each_attr(nla, head, len, rem) {
80 if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
81 treq->th_peerid[i++] = nla_get_u32(nla);
82 if (i >= treq->th_num_peerids)
88 * tls_handshake_done - callback to handle a CMD_DONE request
89 * @req: socket on which the handshake was performed
90 * @status: session status code
91 * @info: full results of session establishment
94 static void tls_handshake_done(struct handshake_req *req,
95 unsigned int status, struct genl_info *info)
97 struct tls_handshake_req *treq = handshake_req_private(req);
99 treq->th_peerid[0] = TLS_NO_PEERID;
101 tls_handshake_remote_peerids(treq, info);
103 treq->th_consumer_done(treq->th_consumer_data, -status,
107 #if IS_ENABLED(CONFIG_KEYS)
108 static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
110 key_ref_t process_keyring_ref, keyring_ref;
113 if (treq->th_keyring == TLS_NO_KEYRING)
116 process_keyring_ref = lookup_user_key(KEY_SPEC_PROCESS_KEYRING,
119 if (IS_ERR(process_keyring_ref)) {
120 ret = PTR_ERR(process_keyring_ref);
124 keyring_ref = lookup_user_key(treq->th_keyring, KEY_LOOKUP_CREATE,
126 if (IS_ERR(keyring_ref)) {
127 ret = PTR_ERR(keyring_ref);
131 ret = key_link(key_ref_to_ptr(process_keyring_ref),
132 key_ref_to_ptr(keyring_ref));
134 key_ref_put(keyring_ref);
136 key_ref_put(process_keyring_ref);
141 static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
147 static int tls_handshake_put_peer_identity(struct sk_buff *msg,
148 struct tls_handshake_req *treq)
152 for (i = 0; i < treq->th_num_peerids; i++)
153 if (nla_put_u32(msg, HANDSHAKE_A_ACCEPT_PEER_IDENTITY,
154 treq->th_peerid[i]) < 0)
159 static int tls_handshake_put_certificate(struct sk_buff *msg,
160 struct tls_handshake_req *treq)
162 struct nlattr *entry_attr;
164 if (treq->th_certificate == TLS_NO_CERT &&
165 treq->th_privkey == TLS_NO_PRIVKEY)
168 entry_attr = nla_nest_start(msg, HANDSHAKE_A_ACCEPT_CERTIFICATE);
172 if (nla_put_u32(msg, HANDSHAKE_A_X509_CERT,
173 treq->th_certificate) ||
174 nla_put_u32(msg, HANDSHAKE_A_X509_PRIVKEY,
176 nla_nest_cancel(msg, entry_attr);
180 nla_nest_end(msg, entry_attr);
185 * tls_handshake_accept - callback to construct a CMD_ACCEPT response
186 * @req: handshake parameters to return
187 * @info: generic netlink message context
188 * @fd: file descriptor to be returned
190 * Returns zero on success, or a negative errno on failure.
192 static int tls_handshake_accept(struct handshake_req *req,
193 struct genl_info *info, int fd)
195 struct tls_handshake_req *treq = handshake_req_private(req);
196 struct nlmsghdr *hdr;
200 ret = tls_handshake_private_keyring(treq);
205 msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
208 hdr = handshake_genl_put(msg, info);
213 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_SOCKFD, fd);
216 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, treq->th_type);
219 if (treq->th_peername) {
220 ret = nla_put_string(msg, HANDSHAKE_A_ACCEPT_PEERNAME,
225 if (treq->th_timeout_ms) {
226 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_TIMEOUT, treq->th_timeout_ms);
231 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_AUTH_MODE,
235 switch (treq->th_auth_mode) {
236 case HANDSHAKE_AUTH_PSK:
237 ret = tls_handshake_put_peer_identity(msg, treq);
241 case HANDSHAKE_AUTH_X509:
242 ret = tls_handshake_put_certificate(msg, treq);
248 genlmsg_end(msg, hdr);
249 return genlmsg_reply(msg, info);
252 genlmsg_cancel(msg, hdr);
257 static const struct handshake_proto tls_handshake_proto = {
258 .hp_handler_class = HANDSHAKE_HANDLER_CLASS_TLSHD,
259 .hp_privsize = sizeof(struct tls_handshake_req),
260 .hp_flags = BIT(HANDSHAKE_F_PROTO_NOTIFY),
262 .hp_accept = tls_handshake_accept,
263 .hp_done = tls_handshake_done,
267 * tls_client_hello_anon - request an anonymous TLS handshake on a socket
268 * @args: socket and handshake parameters for this request
269 * @flags: memory allocation control flags
272 * %0: Handshake request enqueue; ->done will be called when complete
273 * %-ESRCH: No user agent is available
274 * %-ENOMEM: Memory allocation failed
276 int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags)
278 struct tls_handshake_req *treq;
279 struct handshake_req *req;
281 req = handshake_req_alloc(&tls_handshake_proto, flags);
284 treq = tls_handshake_req_init(req, args);
285 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
286 treq->th_auth_mode = HANDSHAKE_AUTH_UNAUTH;
288 return handshake_req_submit(args->ta_sock, req, flags);
290 EXPORT_SYMBOL(tls_client_hello_anon);
293 * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket
294 * @args: socket and handshake parameters for this request
295 * @flags: memory allocation control flags
298 * %0: Handshake request enqueue; ->done will be called when complete
299 * %-ESRCH: No user agent is available
300 * %-ENOMEM: Memory allocation failed
302 int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
304 struct tls_handshake_req *treq;
305 struct handshake_req *req;
307 req = handshake_req_alloc(&tls_handshake_proto, flags);
310 treq = tls_handshake_req_init(req, args);
311 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
312 treq->th_auth_mode = HANDSHAKE_AUTH_X509;
313 treq->th_certificate = args->ta_my_cert;
314 treq->th_privkey = args->ta_my_privkey;
316 return handshake_req_submit(args->ta_sock, req, flags);
318 EXPORT_SYMBOL(tls_client_hello_x509);
321 * tls_client_hello_psk - request a PSK-based TLS handshake on a socket
322 * @args: socket and handshake parameters for this request
323 * @flags: memory allocation control flags
326 * %0: Handshake request enqueue; ->done will be called when complete
327 * %-EINVAL: Wrong number of local peer IDs
328 * %-ESRCH: No user agent is available
329 * %-ENOMEM: Memory allocation failed
331 int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
333 struct tls_handshake_req *treq;
334 struct handshake_req *req;
337 if (!args->ta_num_peerids ||
338 args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid))
341 req = handshake_req_alloc(&tls_handshake_proto, flags);
344 treq = tls_handshake_req_init(req, args);
345 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
346 treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
347 treq->th_num_peerids = args->ta_num_peerids;
348 for (i = 0; i < args->ta_num_peerids; i++)
349 treq->th_peerid[i] = args->ta_my_peerids[i];
351 return handshake_req_submit(args->ta_sock, req, flags);
353 EXPORT_SYMBOL(tls_client_hello_psk);
356 * tls_server_hello_x509 - request a server TLS handshake on a socket
357 * @args: socket and handshake parameters for this request
358 * @flags: memory allocation control flags
361 * %0: Handshake request enqueue; ->done will be called when complete
362 * %-ESRCH: No user agent is available
363 * %-ENOMEM: Memory allocation failed
365 int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
367 struct tls_handshake_req *treq;
368 struct handshake_req *req;
370 req = handshake_req_alloc(&tls_handshake_proto, flags);
373 treq = tls_handshake_req_init(req, args);
374 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
375 treq->th_auth_mode = HANDSHAKE_AUTH_X509;
376 treq->th_certificate = args->ta_my_cert;
377 treq->th_privkey = args->ta_my_privkey;
379 return handshake_req_submit(args->ta_sock, req, flags);
381 EXPORT_SYMBOL(tls_server_hello_x509);
384 * tls_server_hello_psk - request a server TLS handshake on a socket
385 * @args: socket and handshake parameters for this request
386 * @flags: memory allocation control flags
389 * %0: Handshake request enqueue; ->done will be called when complete
390 * %-ESRCH: No user agent is available
391 * %-ENOMEM: Memory allocation failed
393 int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
395 struct tls_handshake_req *treq;
396 struct handshake_req *req;
398 req = handshake_req_alloc(&tls_handshake_proto, flags);
401 treq = tls_handshake_req_init(req, args);
402 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
403 treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
404 treq->th_num_peerids = 1;
405 treq->th_peerid[0] = args->ta_my_peerids[0];
407 return handshake_req_submit(args->ta_sock, req, flags);
409 EXPORT_SYMBOL(tls_server_hello_psk);
412 * tls_handshake_cancel - cancel a pending handshake
413 * @sk: socket on which there is an ongoing handshake
415 * Request cancellation races with request completion. To determine
416 * who won, callers examine the return value from this function.
419 * %true - Uncompleted handshake request was canceled
420 * %false - Handshake request already completed or not found
422 bool tls_handshake_cancel(struct sock *sk)
424 return handshake_req_cancel(sk);
426 EXPORT_SYMBOL(tls_handshake_cancel);