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