QUIC APL, TSERVER: Start using a QUIC_ENGINE object
[openssl.git] / include / internal / ktls.h
1 /*
2  * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #if defined(OPENSSL_SYS_LINUX)
11 # ifndef OPENSSL_NO_KTLS
12 #  include <linux/version.h>
13 #  if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
14 #   define OPENSSL_NO_KTLS
15 #   ifndef PEDANTIC
16 #    warning "KTLS requires Kernel Headers >= 4.13.0"
17 #    warning "Skipping Compilation of KTLS"
18 #   endif
19 #  endif
20 # endif
21 #endif
22
23 #ifndef HEADER_INTERNAL_KTLS
24 # define HEADER_INTERNAL_KTLS
25 # pragma once
26
27 # ifndef OPENSSL_NO_KTLS
28
29 #  if defined(__FreeBSD__)
30 #   include <sys/types.h>
31 #   include <sys/socket.h>
32 #   include <sys/ktls.h>
33 #   include <netinet/in.h>
34 #   include <netinet/tcp.h>
35 #   include <openssl/ssl3.h>
36
37 #   ifndef TCP_RXTLS_ENABLE
38 #    define OPENSSL_NO_KTLS_RX
39 #   endif
40 #   define OPENSSL_KTLS_AES_GCM_128
41 #   define OPENSSL_KTLS_AES_GCM_256
42 #   define OPENSSL_KTLS_TLS13
43 #   ifdef TLS_CHACHA20_IV_LEN
44 #    ifndef OPENSSL_NO_CHACHA
45 #     define OPENSSL_KTLS_CHACHA20_POLY1305
46 #    endif
47 #   endif
48
49 typedef struct tls_enable ktls_crypto_info_t;
50
51 /*
52  * FreeBSD does not require any additional steps to enable KTLS before
53  * setting keys.
54  */
55 static ossl_inline int ktls_enable(int fd)
56 {
57     return 1;
58 }
59
60 /*
61  * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer
62  * as using TLS.  If successful, then data sent using this socket will
63  * be encrypted and encapsulated in TLS records using the tls_en
64  * provided here.
65  *
66  * The TCP_RXTLS_ENABLE socket option marks the incoming socket buffer
67  * as using TLS.  If successful, then data received for this socket will
68  * be authenticated and decrypted using the tls_en provided here.
69  */
70 static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *tls_en, int is_tx)
71 {
72     if (is_tx)
73         return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE,
74                           tls_en, sizeof(*tls_en)) ? 0 : 1;
75 #   ifndef OPENSSL_NO_KTLS_RX
76     return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en,
77                       sizeof(*tls_en)) ? 0 : 1;
78 #   else
79     return 0;
80 #   endif
81 }
82
83 /*
84  * Send a TLS record using the tls_en provided in ktls_start and use
85  * record_type instead of the default SSL3_RT_APPLICATION_DATA.
86  * When the socket is non-blocking, then this call either returns EAGAIN or
87  * the entire record is pushed to TCP. It is impossible to send a partial
88  * record using this control message.
89  */
90 static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
91                                               const void *data, size_t length)
92 {
93     struct msghdr msg = { 0 };
94     int cmsg_len = sizeof(record_type);
95     struct cmsghdr *cmsg;
96     char buf[CMSG_SPACE(cmsg_len)];
97     struct iovec msg_iov;   /* Vector of data to send/receive into */
98
99     msg.msg_control = buf;
100     msg.msg_controllen = sizeof(buf);
101     cmsg = CMSG_FIRSTHDR(&msg);
102     cmsg->cmsg_level = IPPROTO_TCP;
103     cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
104     cmsg->cmsg_len = CMSG_LEN(cmsg_len);
105     *((unsigned char *)CMSG_DATA(cmsg)) = record_type;
106     msg.msg_controllen = cmsg->cmsg_len;
107
108     msg_iov.iov_base = (void *)data;
109     msg_iov.iov_len = length;
110     msg.msg_iov = &msg_iov;
111     msg.msg_iovlen = 1;
112
113     return sendmsg(fd, &msg, 0);
114 }
115
116 #   ifdef OPENSSL_NO_KTLS_RX
117
118 static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
119 {
120     return -1;
121 }
122
123 #   else /* !defined(OPENSSL_NO_KTLS_RX) */
124
125 /*
126  * Receive a TLS record using the tls_en provided in ktls_start.  The
127  * kernel strips any explicit IV and authentication tag, but provides
128  * the TLS record header via a control message.  If there is an error
129  * with the TLS record such as an invalid header, invalid padding, or
130  * authentication failure recvmsg() will fail with an error.
131  */
132 static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
133 {
134     struct msghdr msg = { 0 };
135     int cmsg_len = sizeof(struct tls_get_record);
136     struct tls_get_record *tgr;
137     struct cmsghdr *cmsg;
138     char buf[CMSG_SPACE(cmsg_len)];
139     struct iovec msg_iov;   /* Vector of data to send/receive into */
140     int ret;
141     unsigned char *p = data;
142     const size_t prepend_length = SSL3_RT_HEADER_LENGTH;
143
144     if (length <= prepend_length) {
145         errno = EINVAL;
146         return -1;
147     }
148
149     msg.msg_control = buf;
150     msg.msg_controllen = sizeof(buf);
151
152     msg_iov.iov_base = p + prepend_length;
153     msg_iov.iov_len = length - prepend_length;
154     msg.msg_iov = &msg_iov;
155     msg.msg_iovlen = 1;
156
157     ret = recvmsg(fd, &msg, 0);
158     if (ret <= 0)
159         return ret;
160
161     if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) {
162         errno = EMSGSIZE;
163         return -1;
164     }
165
166     if (msg.msg_controllen == 0) {
167         errno = EBADMSG;
168         return -1;
169     }
170
171     cmsg = CMSG_FIRSTHDR(&msg);
172     if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD
173         || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) {
174         errno = EBADMSG;
175         return -1;
176     }
177
178     tgr = (struct tls_get_record *)CMSG_DATA(cmsg);
179     p[0] = tgr->tls_type;
180     p[1] = tgr->tls_vmajor;
181     p[2] = tgr->tls_vminor;
182     *(uint16_t *)(p + 3) = htons(ret);
183
184     return ret + prepend_length;
185 }
186
187 #   endif /* OPENSSL_NO_KTLS_RX */
188
189 /*
190  * KTLS enables the sendfile system call to send data from a file over
191  * TLS.
192  */
193 static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off,
194                                               size_t size, int flags)
195 {
196     off_t sbytes = 0;
197     int ret;
198
199     ret = sendfile(fd, s, off, size, NULL, &sbytes, flags);
200     if (ret == -1 && sbytes == 0)
201         return -1;
202     return sbytes;
203 }
204
205 #  endif                         /* __FreeBSD__ */
206
207 #  if defined(OPENSSL_SYS_LINUX)
208
209 #   include <linux/tls.h>
210 #   if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
211 #    define OPENSSL_NO_KTLS_RX
212 #    ifndef PEDANTIC
213 #     warning "KTLS requires Kernel Headers >= 4.17.0 for receiving"
214 #     warning "Skipping Compilation of KTLS receive data path"
215 #    endif
216 #   endif
217 #   if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
218 #    define OPENSSL_NO_KTLS_ZC_TX
219 #    ifndef PEDANTIC
220 #     warning "KTLS requires Kernel Headers >= 5.19.0 for zerocopy sendfile"
221 #     warning "Skipping Compilation of KTLS zerocopy sendfile"
222 #    endif
223 #   endif
224 #   define OPENSSL_KTLS_AES_GCM_128
225 #   if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
226 #    define OPENSSL_KTLS_AES_GCM_256
227 #    define OPENSSL_KTLS_TLS13
228 #    if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
229 #     define OPENSSL_KTLS_AES_CCM_128
230 #     if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
231 #      ifndef OPENSSL_NO_CHACHA
232 #       define OPENSSL_KTLS_CHACHA20_POLY1305
233 #      endif
234 #     endif
235 #    endif
236 #   endif
237
238 #   include <sys/sendfile.h>
239 #   include <netinet/tcp.h>
240 #   include <linux/socket.h>
241 #   include <openssl/ssl3.h>
242 #   include <openssl/tls1.h>
243 #   include <openssl/evp.h>
244
245 #   ifndef SOL_TLS
246 #    define SOL_TLS 282
247 #   endif
248
249 #   ifndef TCP_ULP
250 #    define TCP_ULP 31
251 #   endif
252
253 #   ifndef TLS_RX
254 #    define TLS_RX                  2
255 #   endif
256
257 struct tls_crypto_info_all {
258     union {
259 #   ifdef OPENSSL_KTLS_AES_GCM_128
260         struct tls12_crypto_info_aes_gcm_128 gcm128;
261 #   endif
262 #   ifdef OPENSSL_KTLS_AES_GCM_256
263         struct tls12_crypto_info_aes_gcm_256 gcm256;
264 #   endif
265 #   ifdef OPENSSL_KTLS_AES_CCM_128
266         struct tls12_crypto_info_aes_ccm_128 ccm128;
267 #   endif
268 #   ifdef OPENSSL_KTLS_CHACHA20_POLY1305
269         struct tls12_crypto_info_chacha20_poly1305 chacha20poly1305;
270 #   endif
271     };
272     size_t tls_crypto_info_len;
273 };
274
275 typedef struct tls_crypto_info_all ktls_crypto_info_t;
276
277 /*
278  * When successful, this socket option doesn't change the behaviour of the
279  * TCP socket, except changing the TCP setsockopt handler to enable the
280  * processing of SOL_TLS socket options. All other functionality remains the
281  * same.
282  */
283 static ossl_inline int ktls_enable(int fd)
284 {
285     return setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) ? 0 : 1;
286 }
287
288 /*
289  * The TLS_TX socket option changes the send/sendmsg handlers of the TCP socket.
290  * If successful, then data sent using this socket will be encrypted and
291  * encapsulated in TLS records using the crypto_info provided here.
292  * The TLS_RX socket option changes the recv/recvmsg handlers of the TCP socket.
293  * If successful, then data received using this socket will be decrypted,
294  * authenticated and decapsulated using the crypto_info provided here.
295  */
296 static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *crypto_info,
297                                   int is_tx)
298 {
299     return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX,
300                       crypto_info, crypto_info->tls_crypto_info_len) ? 0 : 1;
301 }
302
303 static ossl_inline int ktls_enable_tx_zerocopy_sendfile(int fd)
304 {
305 #ifndef OPENSSL_NO_KTLS_ZC_TX
306     int enable = 1;
307
308     return setsockopt(fd, SOL_TLS, TLS_TX_ZEROCOPY_RO,
309                       &enable, sizeof(enable)) ? 0 : 1;
310 #else
311     return 0;
312 #endif
313 }
314
315 /*
316  * Send a TLS record using the crypto_info provided in ktls_start and use
317  * record_type instead of the default SSL3_RT_APPLICATION_DATA.
318  * When the socket is non-blocking, then this call either returns EAGAIN or
319  * the entire record is pushed to TCP. It is impossible to send a partial
320  * record using this control message.
321  */
322 static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
323                                               const void *data, size_t length)
324 {
325     struct msghdr msg;
326     int cmsg_len = sizeof(record_type);
327     struct cmsghdr *cmsg;
328     union {
329         struct cmsghdr hdr;
330         char buf[CMSG_SPACE(sizeof(unsigned char))];
331     } cmsgbuf;
332     struct iovec msg_iov;       /* Vector of data to send/receive into */
333
334     memset(&msg, 0, sizeof(msg));
335     msg.msg_control = cmsgbuf.buf;
336     msg.msg_controllen = sizeof(cmsgbuf.buf);
337     cmsg = CMSG_FIRSTHDR(&msg);
338     cmsg->cmsg_level = SOL_TLS;
339     cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
340     cmsg->cmsg_len = CMSG_LEN(cmsg_len);
341     *((unsigned char *)CMSG_DATA(cmsg)) = record_type;
342     msg.msg_controllen = cmsg->cmsg_len;
343
344     msg_iov.iov_base = (void *)data;
345     msg_iov.iov_len = length;
346     msg.msg_iov = &msg_iov;
347     msg.msg_iovlen = 1;
348
349     return sendmsg(fd, &msg, 0);
350 }
351
352 /*
353  * KTLS enables the sendfile system call to send data from a file over TLS.
354  * @flags are ignored on Linux. (placeholder for FreeBSD sendfile)
355  * */
356 static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags)
357 {
358     return sendfile(s, fd, &off, size);
359 }
360
361 #   ifdef OPENSSL_NO_KTLS_RX
362
363
364 static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
365 {
366     return -1;
367 }
368
369 #   else /* !defined(OPENSSL_NO_KTLS_RX) */
370
371 /*
372  * Receive a TLS record using the crypto_info provided in ktls_start.
373  * The kernel strips the TLS record header, IV and authentication tag,
374  * returning only the plaintext data or an error on failure.
375  * We add the TLS record header here to satisfy routines in rec_layer_s3.c
376  */
377 static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
378 {
379     struct msghdr msg;
380     struct cmsghdr *cmsg;
381     union {
382         struct cmsghdr hdr;
383         char buf[CMSG_SPACE(sizeof(unsigned char))];
384     } cmsgbuf;
385     struct iovec msg_iov;
386     int ret;
387     unsigned char *p = data;
388     const size_t prepend_length = SSL3_RT_HEADER_LENGTH;
389
390     if (length < prepend_length + EVP_GCM_TLS_TAG_LEN) {
391         errno = EINVAL;
392         return -1;
393     }
394
395     memset(&msg, 0, sizeof(msg));
396     msg.msg_control = cmsgbuf.buf;
397     msg.msg_controllen = sizeof(cmsgbuf.buf);
398
399     msg_iov.iov_base = p + prepend_length;
400     msg_iov.iov_len = length - prepend_length - EVP_GCM_TLS_TAG_LEN;
401     msg.msg_iov = &msg_iov;
402     msg.msg_iovlen = 1;
403
404     ret = recvmsg(fd, &msg, 0);
405     if (ret < 0)
406         return ret;
407
408     if (msg.msg_controllen > 0) {
409         cmsg = CMSG_FIRSTHDR(&msg);
410         if (cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
411             p[0] = *((unsigned char *)CMSG_DATA(cmsg));
412             p[1] = TLS1_2_VERSION_MAJOR;
413             p[2] = TLS1_2_VERSION_MINOR;
414             /* returned length is limited to msg_iov.iov_len above */
415             p[3] = (ret >> 8) & 0xff;
416             p[4] = ret & 0xff;
417             ret += prepend_length;
418         }
419     }
420
421     return ret;
422 }
423
424 #   endif /* OPENSSL_NO_KTLS_RX */
425
426 #  endif /* OPENSSL_SYS_LINUX */
427 # endif /* OPENSSL_NO_KTLS */
428 #endif /* HEADER_INTERNAL_KTLS */