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