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