1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Establish a TLS session for a kernel socket consumer 4 * using the tlshd user space handler. 5 * 6 * Author: Chuck Lever <chuck.lever@oracle.com> 7 * 8 * Copyright (c) 2021-2023, Oracle and/or its affiliates. 9 */ 10 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> 17 18 #include <net/sock.h> 19 #include <net/handshake.h> 20 #include <net/genetlink.h> 21 22 #include <uapi/linux/keyctl.h> 23 #include <uapi/linux/handshake.h> 24 #include "handshake.h" 25 26 struct tls_handshake_req { 27 void (*th_consumer_done)(void *data, int status, 28 key_serial_t peerid); 29 void *th_consumer_data; 30 31 int th_type; 32 unsigned int th_timeout_ms; 33 int th_auth_mode; 34 key_serial_t th_keyring; 35 key_serial_t th_certificate; 36 key_serial_t th_privkey; 37 38 unsigned int th_num_peerids; 39 key_serial_t th_peerid[5]; 40 }; 41 42 static struct tls_handshake_req * 43 tls_handshake_req_init(struct handshake_req *req, 44 const struct tls_handshake_args *args) 45 { 46 struct tls_handshake_req *treq = handshake_req_private(req); 47 48 treq->th_timeout_ms = args->ta_timeout_ms; 49 treq->th_consumer_done = args->ta_done; 50 treq->th_consumer_data = args->ta_data; 51 treq->th_keyring = args->ta_keyring; 52 treq->th_num_peerids = 0; 53 treq->th_certificate = TLS_NO_CERT; 54 treq->th_privkey = TLS_NO_PRIVKEY; 55 return treq; 56 } 57 58 static void tls_handshake_remote_peerids(struct tls_handshake_req *treq, 59 struct genl_info *info) 60 { 61 struct nlattr *head = nlmsg_attrdata(info->nlhdr, GENL_HDRLEN); 62 int rem, len = nlmsg_attrlen(info->nlhdr, GENL_HDRLEN); 63 struct nlattr *nla; 64 unsigned int i; 65 66 i = 0; 67 nla_for_each_attr(nla, head, len, rem) { 68 if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH) 69 i++; 70 } 71 if (!i) 72 return; 73 treq->th_num_peerids = min_t(unsigned int, i, 74 ARRAY_SIZE(treq->th_peerid)); 75 76 i = 0; 77 nla_for_each_attr(nla, head, len, rem) { 78 if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH) 79 treq->th_peerid[i++] = nla_get_u32(nla); 80 if (i >= treq->th_num_peerids) 81 break; 82 } 83 } 84 85 /** 86 * tls_handshake_done - callback to handle a CMD_DONE request 87 * @req: socket on which the handshake was performed 88 * @status: session status code 89 * @info: full results of session establishment 90 * 91 */ 92 static void tls_handshake_done(struct handshake_req *req, 93 unsigned int status, struct genl_info *info) 94 { 95 struct tls_handshake_req *treq = handshake_req_private(req); 96 97 treq->th_peerid[0] = TLS_NO_PEERID; 98 if (info) 99 tls_handshake_remote_peerids(treq, info); 100 101 treq->th_consumer_done(treq->th_consumer_data, -status, 102 treq->th_peerid[0]); 103 } 104 105 #if IS_ENABLED(CONFIG_KEYS) 106 static int tls_handshake_private_keyring(struct tls_handshake_req *treq) 107 { 108 key_ref_t process_keyring_ref, keyring_ref; 109 int ret; 110 111 if (treq->th_keyring == TLS_NO_KEYRING) 112 return 0; 113 114 process_keyring_ref = lookup_user_key(KEY_SPEC_PROCESS_KEYRING, 115 KEY_LOOKUP_CREATE, 116 KEY_NEED_WRITE); 117 if (IS_ERR(process_keyring_ref)) { 118 ret = PTR_ERR(process_keyring_ref); 119 goto out; 120 } 121 122 keyring_ref = lookup_user_key(treq->th_keyring, KEY_LOOKUP_CREATE, 123 KEY_NEED_LINK); 124 if (IS_ERR(keyring_ref)) { 125 ret = PTR_ERR(keyring_ref); 126 goto out_put_key; 127 } 128 129 ret = key_link(key_ref_to_ptr(process_keyring_ref), 130 key_ref_to_ptr(keyring_ref)); 131 132 key_ref_put(keyring_ref); 133 out_put_key: 134 key_ref_put(process_keyring_ref); 135 out: 136 return ret; 137 } 138 #else 139 static int tls_handshake_private_keyring(struct tls_handshake_req *treq) 140 { 141 return 0; 142 } 143 #endif 144 145 static int tls_handshake_put_peer_identity(struct sk_buff *msg, 146 struct tls_handshake_req *treq) 147 { 148 unsigned int i; 149 150 for (i = 0; i < treq->th_num_peerids; i++) 151 if (nla_put_u32(msg, HANDSHAKE_A_ACCEPT_PEER_IDENTITY, 152 treq->th_peerid[i]) < 0) 153 return -EMSGSIZE; 154 return 0; 155 } 156 157 static int tls_handshake_put_certificate(struct sk_buff *msg, 158 struct tls_handshake_req *treq) 159 { 160 struct nlattr *entry_attr; 161 162 if (treq->th_certificate == TLS_NO_CERT && 163 treq->th_privkey == TLS_NO_PRIVKEY) 164 return 0; 165 166 entry_attr = nla_nest_start(msg, HANDSHAKE_A_ACCEPT_CERTIFICATE); 167 if (!entry_attr) 168 return -EMSGSIZE; 169 170 if (nla_put_u32(msg, HANDSHAKE_A_X509_CERT, 171 treq->th_certificate) || 172 nla_put_u32(msg, HANDSHAKE_A_X509_PRIVKEY, 173 treq->th_privkey)) { 174 nla_nest_cancel(msg, entry_attr); 175 return -EMSGSIZE; 176 } 177 178 nla_nest_end(msg, entry_attr); 179 return 0; 180 } 181 182 /** 183 * tls_handshake_accept - callback to construct a CMD_ACCEPT response 184 * @req: handshake parameters to return 185 * @info: generic netlink message context 186 * @fd: file descriptor to be returned 187 * 188 * Returns zero on success, or a negative errno on failure. 189 */ 190 static int tls_handshake_accept(struct handshake_req *req, 191 struct genl_info *info, int fd) 192 { 193 struct tls_handshake_req *treq = handshake_req_private(req); 194 struct nlmsghdr *hdr; 195 struct sk_buff *msg; 196 int ret; 197 198 ret = tls_handshake_private_keyring(treq); 199 if (ret < 0) 200 goto out; 201 202 ret = -ENOMEM; 203 msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 204 if (!msg) 205 goto out; 206 hdr = handshake_genl_put(msg, info); 207 if (!hdr) 208 goto out_cancel; 209 210 ret = -EMSGSIZE; 211 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_SOCKFD, fd); 212 if (ret < 0) 213 goto out_cancel; 214 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, treq->th_type); 215 if (ret < 0) 216 goto out_cancel; 217 if (treq->th_timeout_ms) { 218 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_TIMEOUT, treq->th_timeout_ms); 219 if (ret < 0) 220 goto out_cancel; 221 } 222 223 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_AUTH_MODE, 224 treq->th_auth_mode); 225 if (ret < 0) 226 goto out_cancel; 227 switch (treq->th_auth_mode) { 228 case HANDSHAKE_AUTH_PSK: 229 ret = tls_handshake_put_peer_identity(msg, treq); 230 if (ret < 0) 231 goto out_cancel; 232 break; 233 case HANDSHAKE_AUTH_X509: 234 ret = tls_handshake_put_certificate(msg, treq); 235 if (ret < 0) 236 goto out_cancel; 237 break; 238 } 239 240 genlmsg_end(msg, hdr); 241 return genlmsg_reply(msg, info); 242 243 out_cancel: 244 genlmsg_cancel(msg, hdr); 245 out: 246 return ret; 247 } 248 249 static const struct handshake_proto tls_handshake_proto = { 250 .hp_handler_class = HANDSHAKE_HANDLER_CLASS_TLSHD, 251 .hp_privsize = sizeof(struct tls_handshake_req), 252 .hp_flags = BIT(HANDSHAKE_F_PROTO_NOTIFY), 253 254 .hp_accept = tls_handshake_accept, 255 .hp_done = tls_handshake_done, 256 }; 257 258 /** 259 * tls_client_hello_anon - request an anonymous TLS handshake on a socket 260 * @args: socket and handshake parameters for this request 261 * @flags: memory allocation control flags 262 * 263 * Return values: 264 * %0: Handshake request enqueue; ->done will be called when complete 265 * %-ESRCH: No user agent is available 266 * %-ENOMEM: Memory allocation failed 267 */ 268 int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags) 269 { 270 struct tls_handshake_req *treq; 271 struct handshake_req *req; 272 273 req = handshake_req_alloc(&tls_handshake_proto, flags); 274 if (!req) 275 return -ENOMEM; 276 treq = tls_handshake_req_init(req, args); 277 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO; 278 treq->th_auth_mode = HANDSHAKE_AUTH_UNAUTH; 279 280 return handshake_req_submit(args->ta_sock, req, flags); 281 } 282 EXPORT_SYMBOL(tls_client_hello_anon); 283 284 /** 285 * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket 286 * @args: socket and handshake parameters for this request 287 * @flags: memory allocation control flags 288 * 289 * Return values: 290 * %0: Handshake request enqueue; ->done will be called when complete 291 * %-ESRCH: No user agent is available 292 * %-ENOMEM: Memory allocation failed 293 */ 294 int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags) 295 { 296 struct tls_handshake_req *treq; 297 struct handshake_req *req; 298 299 req = handshake_req_alloc(&tls_handshake_proto, flags); 300 if (!req) 301 return -ENOMEM; 302 treq = tls_handshake_req_init(req, args); 303 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO; 304 treq->th_auth_mode = HANDSHAKE_AUTH_X509; 305 treq->th_certificate = args->ta_my_cert; 306 treq->th_privkey = args->ta_my_privkey; 307 308 return handshake_req_submit(args->ta_sock, req, flags); 309 } 310 EXPORT_SYMBOL(tls_client_hello_x509); 311 312 /** 313 * tls_client_hello_psk - request a PSK-based TLS handshake on a socket 314 * @args: socket and handshake parameters for this request 315 * @flags: memory allocation control flags 316 * 317 * Return values: 318 * %0: Handshake request enqueue; ->done will be called when complete 319 * %-EINVAL: Wrong number of local peer IDs 320 * %-ESRCH: No user agent is available 321 * %-ENOMEM: Memory allocation failed 322 */ 323 int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags) 324 { 325 struct tls_handshake_req *treq; 326 struct handshake_req *req; 327 unsigned int i; 328 329 if (!args->ta_num_peerids || 330 args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid)) 331 return -EINVAL; 332 333 req = handshake_req_alloc(&tls_handshake_proto, flags); 334 if (!req) 335 return -ENOMEM; 336 treq = tls_handshake_req_init(req, args); 337 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO; 338 treq->th_auth_mode = HANDSHAKE_AUTH_PSK; 339 treq->th_num_peerids = args->ta_num_peerids; 340 for (i = 0; i < args->ta_num_peerids; i++) 341 treq->th_peerid[i] = args->ta_my_peerids[i]; 342 343 return handshake_req_submit(args->ta_sock, req, flags); 344 } 345 EXPORT_SYMBOL(tls_client_hello_psk); 346 347 /** 348 * tls_server_hello_x509 - request a server TLS handshake on a socket 349 * @args: socket and handshake parameters for this request 350 * @flags: memory allocation control flags 351 * 352 * Return values: 353 * %0: Handshake request enqueue; ->done will be called when complete 354 * %-ESRCH: No user agent is available 355 * %-ENOMEM: Memory allocation failed 356 */ 357 int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags) 358 { 359 struct tls_handshake_req *treq; 360 struct handshake_req *req; 361 362 req = handshake_req_alloc(&tls_handshake_proto, flags); 363 if (!req) 364 return -ENOMEM; 365 treq = tls_handshake_req_init(req, args); 366 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO; 367 treq->th_auth_mode = HANDSHAKE_AUTH_X509; 368 treq->th_certificate = args->ta_my_cert; 369 treq->th_privkey = args->ta_my_privkey; 370 371 return handshake_req_submit(args->ta_sock, req, flags); 372 } 373 EXPORT_SYMBOL(tls_server_hello_x509); 374 375 /** 376 * tls_server_hello_psk - request a server TLS handshake on a socket 377 * @args: socket and handshake parameters for this request 378 * @flags: memory allocation control flags 379 * 380 * Return values: 381 * %0: Handshake request enqueue; ->done will be called when complete 382 * %-ESRCH: No user agent is available 383 * %-ENOMEM: Memory allocation failed 384 */ 385 int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags) 386 { 387 struct tls_handshake_req *treq; 388 struct handshake_req *req; 389 390 req = handshake_req_alloc(&tls_handshake_proto, flags); 391 if (!req) 392 return -ENOMEM; 393 treq = tls_handshake_req_init(req, args); 394 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO; 395 treq->th_auth_mode = HANDSHAKE_AUTH_PSK; 396 treq->th_num_peerids = 1; 397 treq->th_peerid[0] = args->ta_my_peerids[0]; 398 399 return handshake_req_submit(args->ta_sock, req, flags); 400 } 401 EXPORT_SYMBOL(tls_server_hello_psk); 402 403 /** 404 * tls_handshake_cancel - cancel a pending handshake 405 * @sk: socket on which there is an ongoing handshake 406 * 407 * Request cancellation races with request completion. To determine 408 * who won, callers examine the return value from this function. 409 * 410 * Return values: 411 * %true - Uncompleted handshake request was canceled 412 * %false - Handshake request already completed or not found 413 */ 414 bool tls_handshake_cancel(struct sock *sk) 415 { 416 return handshake_req_cancel(sk); 417 } 418 EXPORT_SYMBOL(tls_handshake_cancel); 419