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