1.. SPDX-License-Identifier: GPL-2.0 2 3======================= 4In-Kernel TLS Handshake 5======================= 6 7Overview 8======== 9 10Transport Layer Security (TLS) is a Upper Layer Protocol (ULP) that runs 11over TCP. TLS provides end-to-end data integrity and confidentiality in 12addition to peer authentication. 13 14The kernel's kTLS implementation handles the TLS record subprotocol, but 15does not handle the TLS handshake subprotocol which is used to establish 16a TLS session. Kernel consumers can use the API described here to 17request TLS session establishment. 18 19There are several possible ways to provide a handshake service in the 20kernel. The API described here is designed to hide the details of those 21implementations so that in-kernel TLS consumers do not need to be 22aware of how the handshake gets done. 23 24 25User handshake agent 26==================== 27 28As of this writing, there is no TLS handshake implementation in the 29Linux kernel. To provide a handshake service, a handshake agent 30(typically in user space) is started in each network namespace where a 31kernel consumer might require a TLS handshake. Handshake agents listen 32for events sent from the kernel that indicate a handshake request is 33waiting. 34 35An open socket is passed to a handshake agent via a netlink operation, 36which creates a socket descriptor in the agent's file descriptor table. 37If the handshake completes successfully, the handshake agent promotes 38the socket to use the TLS ULP and sets the session information using the 39SOL_TLS socket options. The handshake agent returns the socket to the 40kernel via a second netlink operation. 41 42 43Kernel Handshake API 44==================== 45 46A kernel TLS consumer initiates a client-side TLS handshake on an open 47socket by invoking one of the tls_client_hello() functions. First, it 48fills in a structure that contains the parameters of the request: 49 50.. code-block:: c 51 52 struct tls_handshake_args { 53 struct socket *ta_sock; 54 tls_done_func_t ta_done; 55 void *ta_data; 56 unsigned int ta_timeout_ms; 57 key_serial_t ta_keyring; 58 key_serial_t ta_my_cert; 59 key_serial_t ta_my_privkey; 60 unsigned int ta_num_peerids; 61 key_serial_t ta_my_peerids[5]; 62 }; 63 64The @ta_sock field references an open and connected socket. The consumer 65must hold a reference on the socket to prevent it from being destroyed 66while the handshake is in progress. The consumer must also have 67instantiated a struct file in sock->file. 68 69 70@ta_done contains a callback function that is invoked when the handshake 71has completed. Further explanation of this function is in the "Handshake 72Completion" sesction below. 73 74The consumer can fill in the @ta_timeout_ms field to force the servicing 75handshake agent to exit after a number of milliseconds. This enables the 76socket to be fully closed once both the kernel and the handshake agent 77have closed their endpoints. 78 79Authentication material such as x.509 certificates, private certificate 80keys, and pre-shared keys are provided to the handshake agent in keys 81that are instantiated by the consumer before making the handshake 82request. The consumer can provide a private keyring that is linked into 83the handshake agent's process keyring in the @ta_keyring field to prevent 84access of those keys by other subsystems. 85 86To request an x.509-authenticated TLS session, the consumer fills in 87the @ta_my_cert and @ta_my_privkey fields with the serial numbers of 88keys containing an x.509 certificate and the private key for that 89certificate. Then, it invokes this function: 90 91.. code-block:: c 92 93 ret = tls_client_hello_x509(args, gfp_flags); 94 95The function returns zero when the handshake request is under way. A 96zero return guarantees the callback function @ta_done will be invoked 97for this socket. The function returns a negative errno if the handshake 98could not be started. A negative errno guarantees the callback function 99@ta_done will not be invoked on this socket. 100 101 102To initiate a client-side TLS handshake with a pre-shared key, use: 103 104.. code-block:: c 105 106 ret = tls_client_hello_psk(args, gfp_flags); 107 108However, in this case, the consumer fills in the @ta_my_peerids array 109with serial numbers of keys containing the peer identities it wishes 110to offer, and the @ta_num_peerids field with the number of array 111entries it has filled in. The other fields are filled in as above. 112 113 114To initiate an anonymous client-side TLS handshake use: 115 116.. code-block:: c 117 118 ret = tls_client_hello_anon(args, gfp_flags); 119 120The handshake agent presents no peer identity information to the remote 121during this type of handshake. Only server authentication (ie the client 122verifies the server's identity) is performed during the handshake. Thus 123the established session uses encryption only. 124 125 126Consumers that are in-kernel servers use: 127 128.. code-block:: c 129 130 ret = tls_server_hello_x509(args, gfp_flags); 131 132or 133 134.. code-block:: c 135 136 ret = tls_server_hello_psk(args, gfp_flags); 137 138The argument structure is filled in as above. 139 140 141If the consumer needs to cancel the handshake request, say, due to a ^C 142or other exigent event, the consumer can invoke: 143 144.. code-block:: c 145 146 bool tls_handshake_cancel(sock); 147 148This function returns true if the handshake request associated with 149@sock has been canceled. The consumer's handshake completion callback 150will not be invoked. If this function returns false, then the consumer's 151completion callback has already been invoked. 152 153 154Handshake Completion 155==================== 156 157When the handshake agent has completed processing, it notifies the 158kernel that the socket may be used by the consumer again. At this point, 159the consumer's handshake completion callback, provided in the @ta_done 160field in the tls_handshake_args structure, is invoked. 161 162The synopsis of this function is: 163 164.. code-block:: c 165 166 typedef void (*tls_done_func_t)(void *data, int status, 167 key_serial_t peerid); 168 169The consumer provides a cookie in the @ta_data field of the 170tls_handshake_args structure that is returned in the @data parameter of 171this callback. The consumer uses the cookie to match the callback to the 172thread waiting for the handshake to complete. 173 174The success status of the handshake is returned via the @status 175parameter: 176 177+------------+----------------------------------------------+ 178| status | meaning | 179+============+==============================================+ 180| 0 | TLS session established successfully | 181+------------+----------------------------------------------+ 182| -EACCESS | Remote peer rejected the handshake or | 183| | authentication failed | 184+------------+----------------------------------------------+ 185| -ENOMEM | Temporary resource allocation failure | 186+------------+----------------------------------------------+ 187| -EINVAL | Consumer provided an invalid argument | 188+------------+----------------------------------------------+ 189| -ENOKEY | Missing authentication material | 190+------------+----------------------------------------------+ 191| -EIO | An unexpected fault occurred | 192+------------+----------------------------------------------+ 193 194The @peerid parameter contains the serial number of a key containing the 195remote peer's identity or the value TLS_NO_PEERID if the session is not 196authenticated. 197 198A best practice is to close and destroy the socket immediately if the 199handshake failed. 200 201 202Other considerations 203-------------------- 204 205While a handshake is under way, the kernel consumer must alter the 206socket's sk_data_ready callback function to ignore all incoming data. 207Once the handshake completion callback function has been invoked, normal 208receive operation can be resumed. 209 210Once a TLS session is established, the consumer must provide a buffer 211for and then examine the control message (CMSG) that is part of every 212subsequent sock_recvmsg(). Each control message indicates whether the 213received message data is TLS record data or session metadata. 214 215See tls.rst for details on how a kTLS consumer recognizes incoming 216(decrypted) application data, alerts, and handshake packets once the 217socket has been promoted to use the TLS ULP. 218