~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/networking/tls-handshake.rst

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php