brintos

brintos / linux-shallow public Read only

0
0
Text · 8.3 KiB · 6f5ea16 Raw
223 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3=======================4In-Kernel TLS Handshake5=======================6 7Overview8========9 10Transport Layer Security (TLS) is a Upper Layer Protocol (ULP) that runs11over TCP. TLS provides end-to-end data integrity and confidentiality in12addition to peer authentication.13 14The kernel's kTLS implementation handles the TLS record subprotocol, but15does not handle the TLS handshake subprotocol which is used to establish16a TLS session. Kernel consumers can use the API described here to17request TLS session establishment.18 19There are several possible ways to provide a handshake service in the20kernel. The API described here is designed to hide the details of those21implementations so that in-kernel TLS consumers do not need to be22aware of how the handshake gets done.23 24 25User handshake agent26====================27 28As of this writing, there is no TLS handshake implementation in the29Linux kernel. To provide a handshake service, a handshake agent30(typically in user space) is started in each network namespace where a31kernel consumer might require a TLS handshake. Handshake agents listen32for events sent from the kernel that indicate a handshake request is33waiting.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 promotes38the socket to use the TLS ULP and sets the session information using the39SOL_TLS socket options. The handshake agent returns the socket to the40kernel via a second netlink operation.41 42 43Kernel Handshake API44====================45 46A kernel TLS consumer initiates a client-side TLS handshake on an open47socket by invoking one of the tls_client_hello() functions. First, it48fills in a structure that contains the parameters of the request:49 50.. code-block:: c51 52  struct tls_handshake_args {53        struct socket   *ta_sock;54        tls_done_func_t ta_done;55        void            *ta_data;56        const char      *ta_peername;57        unsigned int    ta_timeout_ms;58        key_serial_t    ta_keyring;59        key_serial_t    ta_my_cert;60        key_serial_t    ta_my_privkey;61        unsigned int    ta_num_peerids;62        key_serial_t    ta_my_peerids[5];63  };64 65The @ta_sock field references an open and connected socket. The consumer66must hold a reference on the socket to prevent it from being destroyed67while the handshake is in progress. The consumer must also have68instantiated a struct file in sock->file.69 70 71@ta_done contains a callback function that is invoked when the handshake72has completed. Further explanation of this function is in the "Handshake73Completion" sesction below.74 75The consumer can provide a NUL-terminated hostname in the @ta_peername76field that is sent as part of ClientHello. If no peername is provided,77the DNS hostname associated with the server's IP address is used instead.78 79The consumer can fill in the @ta_timeout_ms field to force the servicing80handshake agent to exit after a number of milliseconds. This enables the81socket to be fully closed once both the kernel and the handshake agent82have closed their endpoints.83 84Authentication material such as x.509 certificates, private certificate85keys, and pre-shared keys are provided to the handshake agent in keys86that are instantiated by the consumer before making the handshake87request. The consumer can provide a private keyring that is linked into88the handshake agent's process keyring in the @ta_keyring field to prevent89access of those keys by other subsystems.90 91To request an x.509-authenticated TLS session, the consumer fills in92the @ta_my_cert and @ta_my_privkey fields with the serial numbers of93keys containing an x.509 certificate and the private key for that94certificate. Then, it invokes this function:95 96.. code-block:: c97 98  ret = tls_client_hello_x509(args, gfp_flags);99 100The function returns zero when the handshake request is under way. A101zero return guarantees the callback function @ta_done will be invoked102for this socket. The function returns a negative errno if the handshake103could not be started. A negative errno guarantees the callback function104@ta_done will not be invoked on this socket.105 106 107To initiate a client-side TLS handshake with a pre-shared key, use:108 109.. code-block:: c110 111  ret = tls_client_hello_psk(args, gfp_flags);112 113However, in this case, the consumer fills in the @ta_my_peerids array114with serial numbers of keys containing the peer identities it wishes115to offer, and the @ta_num_peerids field with the number of array116entries it has filled in. The other fields are filled in as above.117 118 119To initiate an anonymous client-side TLS handshake use:120 121.. code-block:: c122 123  ret = tls_client_hello_anon(args, gfp_flags);124 125The handshake agent presents no peer identity information to the remote126during this type of handshake. Only server authentication (ie the client127verifies the server's identity) is performed during the handshake. Thus128the established session uses encryption only.129 130 131Consumers that are in-kernel servers use:132 133.. code-block:: c134 135  ret = tls_server_hello_x509(args, gfp_flags);136 137or138 139.. code-block:: c140 141  ret = tls_server_hello_psk(args, gfp_flags);142 143The argument structure is filled in as above.144 145 146If the consumer needs to cancel the handshake request, say, due to a ^C147or other exigent event, the consumer can invoke:148 149.. code-block:: c150 151  bool tls_handshake_cancel(sock);152 153This function returns true if the handshake request associated with154@sock has been canceled. The consumer's handshake completion callback155will not be invoked. If this function returns false, then the consumer's156completion callback has already been invoked.157 158 159Handshake Completion160====================161 162When the handshake agent has completed processing, it notifies the163kernel that the socket may be used by the consumer again. At this point,164the consumer's handshake completion callback, provided in the @ta_done165field in the tls_handshake_args structure, is invoked.166 167The synopsis of this function is:168 169.. code-block:: c170 171  typedef void	(*tls_done_func_t)(void *data, int status,172                                   key_serial_t peerid);173 174The consumer provides a cookie in the @ta_data field of the175tls_handshake_args structure that is returned in the @data parameter of176this callback. The consumer uses the cookie to match the callback to the177thread waiting for the handshake to complete.178 179The success status of the handshake is returned via the @status180parameter:181 182+------------+----------------------------------------------+183|  status    |  meaning                                     |184+============+==============================================+185|  0         |  TLS session established successfully        |186+------------+----------------------------------------------+187|  -EACCESS  |  Remote peer rejected the handshake or       |188|            |  authentication failed                       |189+------------+----------------------------------------------+190|  -ENOMEM   |  Temporary resource allocation failure       |191+------------+----------------------------------------------+192|  -EINVAL   |  Consumer provided an invalid argument       |193+------------+----------------------------------------------+194|  -ENOKEY   |  Missing authentication material             |195+------------+----------------------------------------------+196|  -EIO      |  An unexpected fault occurred                |197+------------+----------------------------------------------+198 199The @peerid parameter contains the serial number of a key containing the200remote peer's identity or the value TLS_NO_PEERID if the session is not201authenticated.202 203A best practice is to close and destroy the socket immediately if the204handshake failed.205 206 207Other considerations208--------------------209 210While a handshake is under way, the kernel consumer must alter the211socket's sk_data_ready callback function to ignore all incoming data.212Once the handshake completion callback function has been invoked, normal213receive operation can be resumed.214 215Once a TLS session is established, the consumer must provide a buffer216for and then examine the control message (CMSG) that is part of every217subsequent sock_recvmsg(). Each control message indicates whether the218received message data is TLS record data or session metadata.219 220See tls.rst for details on how a kTLS consumer recognizes incoming221(decrypted) application data, alerts, and handshake packets once the222socket has been promoted to use the TLS ULP.223