From 2ae34b67e36b8ba05132d481876eb4ed7a826283 Mon Sep 17 00:00:00 2001 From: BobTheBob9 Date: Thu, 7 Jul 2022 21:31:41 +0100 Subject: almost fully replaced hooking lib --- NorthstarDLL/include/internal/ktls.h | 808 +++++++++++++++++------------------ 1 file changed, 404 insertions(+), 404 deletions(-) (limited to 'NorthstarDLL/include/internal/ktls.h') diff --git a/NorthstarDLL/include/internal/ktls.h b/NorthstarDLL/include/internal/ktls.h index 95492fd0..8fca812f 100644 --- a/NorthstarDLL/include/internal/ktls.h +++ b/NorthstarDLL/include/internal/ktls.h @@ -1,404 +1,404 @@ -/* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#if defined(OPENSSL_SYS_LINUX) -# ifndef OPENSSL_NO_KTLS -# include -# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) -# define OPENSSL_NO_KTLS -# ifndef PEDANTIC -# warning "KTLS requires Kernel Headers >= 4.13.0" -# warning "Skipping Compilation of KTLS" -# endif -# endif -# endif -#endif - -#ifndef HEADER_INTERNAL_KTLS -# define HEADER_INTERNAL_KTLS -# pragma once - -# ifndef OPENSSL_NO_KTLS - -# if defined(__FreeBSD__) -# include -# include -# include -# include -# include -# include - -# ifndef TCP_RXTLS_ENABLE -# define OPENSSL_NO_KTLS_RX -# endif -# define OPENSSL_KTLS_AES_GCM_128 -# define OPENSSL_KTLS_AES_GCM_256 -# define OPENSSL_KTLS_TLS13 - -typedef struct tls_enable ktls_crypto_info_t; - -/* - * FreeBSD does not require any additional steps to enable KTLS before - * setting keys. - */ -static ossl_inline int ktls_enable(int fd) -{ - return 1; -} - -/* - * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer - * as using TLS. If successful, then data sent using this socket will - * be encrypted and encapsulated in TLS records using the tls_en - * provided here. - * - * The TCP_RXTLS_ENABLE socket option marks the incoming socket buffer - * as using TLS. If successful, then data received for this socket will - * be authenticated and decrypted using the tls_en provided here. - */ -static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *tls_en, int is_tx) -{ - if (is_tx) - return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, - tls_en, sizeof(*tls_en)) ? 0 : 1; -# ifndef OPENSSL_NO_KTLS_RX - return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, - sizeof(*tls_en)) ? 0 : 1; -# else - return 0; -# endif -} - -/* - * Send a TLS record using the tls_en provided in ktls_start and use - * record_type instead of the default SSL3_RT_APPLICATION_DATA. - * When the socket is non-blocking, then this call either returns EAGAIN or - * the entire record is pushed to TCP. It is impossible to send a partial - * record using this control message. - */ -static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, - const void *data, size_t length) -{ - struct msghdr msg = { 0 }; - int cmsg_len = sizeof(record_type); - struct cmsghdr *cmsg; - char buf[CMSG_SPACE(cmsg_len)]; - struct iovec msg_iov; /* Vector of data to send/receive into */ - - msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = IPPROTO_TCP; - cmsg->cmsg_type = TLS_SET_RECORD_TYPE; - cmsg->cmsg_len = CMSG_LEN(cmsg_len); - *((unsigned char *)CMSG_DATA(cmsg)) = record_type; - msg.msg_controllen = cmsg->cmsg_len; - - msg_iov.iov_base = (void *)data; - msg_iov.iov_len = length; - msg.msg_iov = &msg_iov; - msg.msg_iovlen = 1; - - return sendmsg(fd, &msg, 0); -} - -# ifdef OPENSSL_NO_KTLS_RX - -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - return -1; -} - -# else /* !defined(OPENSSL_NO_KTLS_RX) */ - -/* - * Receive a TLS record using the tls_en provided in ktls_start. The - * kernel strips any explicit IV and authentication tag, but provides - * the TLS record header via a control message. If there is an error - * with the TLS record such as an invalid header, invalid padding, or - * authentication failure recvmsg() will fail with an error. - */ -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - struct msghdr msg = { 0 }; - int cmsg_len = sizeof(struct tls_get_record); - struct tls_get_record *tgr; - struct cmsghdr *cmsg; - char buf[CMSG_SPACE(cmsg_len)]; - struct iovec msg_iov; /* Vector of data to send/receive into */ - int ret; - unsigned char *p = data; - const size_t prepend_length = SSL3_RT_HEADER_LENGTH; - - if (length <= prepend_length) { - errno = EINVAL; - return -1; - } - - msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); - - msg_iov.iov_base = p + prepend_length; - msg_iov.iov_len = length - prepend_length; - msg.msg_iov = &msg_iov; - msg.msg_iovlen = 1; - - ret = recvmsg(fd, &msg, 0); - if (ret <= 0) - return ret; - - if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) { - errno = EMSGSIZE; - return -1; - } - - if (msg.msg_controllen == 0) { - errno = EBADMSG; - return -1; - } - - cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD - || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) { - errno = EBADMSG; - return -1; - } - - tgr = (struct tls_get_record *)CMSG_DATA(cmsg); - p[0] = tgr->tls_type; - p[1] = tgr->tls_vmajor; - p[2] = tgr->tls_vminor; - *(uint16_t *)(p + 3) = htons(ret); - - return ret + prepend_length; -} - -# endif /* OPENSSL_NO_KTLS_RX */ - -/* - * KTLS enables the sendfile system call to send data from a file over - * TLS. - */ -static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, - size_t size, int flags) -{ - off_t sbytes = 0; - int ret; - - ret = sendfile(fd, s, off, size, NULL, &sbytes, flags); - if (ret == -1 && sbytes == 0) - return -1; - return sbytes; -} - -# endif /* __FreeBSD__ */ - -# if defined(OPENSSL_SYS_LINUX) - -# include -# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) -# define OPENSSL_NO_KTLS_RX -# ifndef PEDANTIC -# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" -# warning "Skipping Compilation of KTLS receive data path" -# endif -# endif -# define OPENSSL_KTLS_AES_GCM_128 -# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) -# define OPENSSL_KTLS_AES_GCM_256 -# define OPENSSL_KTLS_TLS13 -# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) -# define OPENSSL_KTLS_AES_CCM_128 -# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -# ifndef OPENSSL_NO_CHACHA -# define OPENSSL_KTLS_CHACHA20_POLY1305 -# endif -# endif -# endif -# endif - -# include -# include -# include -# include -# include -# include - -# ifndef SOL_TLS -# define SOL_TLS 282 -# endif - -# ifndef TCP_ULP -# define TCP_ULP 31 -# endif - -# ifndef TLS_RX -# define TLS_RX 2 -# endif - -struct tls_crypto_info_all { - union { -# ifdef OPENSSL_KTLS_AES_GCM_128 - struct tls12_crypto_info_aes_gcm_128 gcm128; -# endif -# ifdef OPENSSL_KTLS_AES_GCM_256 - struct tls12_crypto_info_aes_gcm_256 gcm256; -# endif -# ifdef OPENSSL_KTLS_AES_CCM_128 - struct tls12_crypto_info_aes_ccm_128 ccm128; -# endif -# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 - struct tls12_crypto_info_chacha20_poly1305 chacha20poly1305; -# endif - }; - size_t tls_crypto_info_len; -}; - -typedef struct tls_crypto_info_all ktls_crypto_info_t; - -/* - * When successful, this socket option doesn't change the behaviour of the - * TCP socket, except changing the TCP setsockopt handler to enable the - * processing of SOL_TLS socket options. All other functionality remains the - * same. - */ -static ossl_inline int ktls_enable(int fd) -{ - return setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) ? 0 : 1; -} - -/* - * The TLS_TX socket option changes the send/sendmsg handlers of the TCP socket. - * If successful, then data sent using this socket will be encrypted and - * encapsulated in TLS records using the crypto_info provided here. - * The TLS_RX socket option changes the recv/recvmsg handlers of the TCP socket. - * If successful, then data received using this socket will be decrypted, - * authenticated and decapsulated using the crypto_info provided here. - */ -static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *crypto_info, - int is_tx) -{ - return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, - crypto_info, crypto_info->tls_crypto_info_len) ? 0 : 1; -} - -/* - * Send a TLS record using the crypto_info provided in ktls_start and use - * record_type instead of the default SSL3_RT_APPLICATION_DATA. - * When the socket is non-blocking, then this call either returns EAGAIN or - * the entire record is pushed to TCP. It is impossible to send a partial - * record using this control message. - */ -static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, - const void *data, size_t length) -{ - struct msghdr msg; - int cmsg_len = sizeof(record_type); - struct cmsghdr *cmsg; - union { - struct cmsghdr hdr; - char buf[CMSG_SPACE(sizeof(unsigned char))]; - } cmsgbuf; - struct iovec msg_iov; /* Vector of data to send/receive into */ - - memset(&msg, 0, sizeof(msg)); - msg.msg_control = cmsgbuf.buf; - msg.msg_controllen = sizeof(cmsgbuf.buf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_TLS; - cmsg->cmsg_type = TLS_SET_RECORD_TYPE; - cmsg->cmsg_len = CMSG_LEN(cmsg_len); - *((unsigned char *)CMSG_DATA(cmsg)) = record_type; - msg.msg_controllen = cmsg->cmsg_len; - - msg_iov.iov_base = (void *)data; - msg_iov.iov_len = length; - msg.msg_iov = &msg_iov; - msg.msg_iovlen = 1; - - return sendmsg(fd, &msg, 0); -} - -/* - * KTLS enables the sendfile system call to send data from a file over TLS. - * @flags are ignored on Linux. (placeholder for FreeBSD sendfile) - * */ -static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) -{ - return sendfile(s, fd, &off, size); -} - -# ifdef OPENSSL_NO_KTLS_RX - - -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - return -1; -} - -# else /* !defined(OPENSSL_NO_KTLS_RX) */ - -/* - * Receive a TLS record using the crypto_info provided in ktls_start. - * The kernel strips the TLS record header, IV and authentication tag, - * returning only the plaintext data or an error on failure. - * We add the TLS record header here to satisfy routines in rec_layer_s3.c - */ -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - struct msghdr msg; - struct cmsghdr *cmsg; - union { - struct cmsghdr hdr; - char buf[CMSG_SPACE(sizeof(unsigned char))]; - } cmsgbuf; - struct iovec msg_iov; - int ret; - unsigned char *p = data; - const size_t prepend_length = SSL3_RT_HEADER_LENGTH; - - if (length < prepend_length + EVP_GCM_TLS_TAG_LEN) { - errno = EINVAL; - return -1; - } - - memset(&msg, 0, sizeof(msg)); - msg.msg_control = cmsgbuf.buf; - msg.msg_controllen = sizeof(cmsgbuf.buf); - - msg_iov.iov_base = p + prepend_length; - msg_iov.iov_len = length - prepend_length - EVP_GCM_TLS_TAG_LEN; - msg.msg_iov = &msg_iov; - msg.msg_iovlen = 1; - - ret = recvmsg(fd, &msg, 0); - if (ret < 0) - return ret; - - if (msg.msg_controllen > 0) { - cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg->cmsg_type == TLS_GET_RECORD_TYPE) { - p[0] = *((unsigned char *)CMSG_DATA(cmsg)); - p[1] = TLS1_2_VERSION_MAJOR; - p[2] = TLS1_2_VERSION_MINOR; - /* returned length is limited to msg_iov.iov_len above */ - p[3] = (ret >> 8) & 0xff; - p[4] = ret & 0xff; - ret += prepend_length; - } - } - - return ret; -} - -# endif /* OPENSSL_NO_KTLS_RX */ - -# endif /* OPENSSL_SYS_LINUX */ -# endif /* OPENSSL_NO_KTLS */ -#endif /* HEADER_INTERNAL_KTLS */ +/* + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#if defined(OPENSSL_SYS_LINUX) +# ifndef OPENSSL_NO_KTLS +# include +# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +# define OPENSSL_NO_KTLS +# ifndef PEDANTIC +# warning "KTLS requires Kernel Headers >= 4.13.0" +# warning "Skipping Compilation of KTLS" +# endif +# endif +# endif +#endif + +#ifndef HEADER_INTERNAL_KTLS +# define HEADER_INTERNAL_KTLS +# pragma once + +# ifndef OPENSSL_NO_KTLS + +# if defined(__FreeBSD__) +# include +# include +# include +# include +# include +# include + +# ifndef TCP_RXTLS_ENABLE +# define OPENSSL_NO_KTLS_RX +# endif +# define OPENSSL_KTLS_AES_GCM_128 +# define OPENSSL_KTLS_AES_GCM_256 +# define OPENSSL_KTLS_TLS13 + +typedef struct tls_enable ktls_crypto_info_t; + +/* + * FreeBSD does not require any additional steps to enable KTLS before + * setting keys. + */ +static ossl_inline int ktls_enable(int fd) +{ + return 1; +} + +/* + * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer + * as using TLS. If successful, then data sent using this socket will + * be encrypted and encapsulated in TLS records using the tls_en + * provided here. + * + * The TCP_RXTLS_ENABLE socket option marks the incoming socket buffer + * as using TLS. If successful, then data received for this socket will + * be authenticated and decrypted using the tls_en provided here. + */ +static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *tls_en, int is_tx) +{ + if (is_tx) + return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, + tls_en, sizeof(*tls_en)) ? 0 : 1; +# ifndef OPENSSL_NO_KTLS_RX + return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, + sizeof(*tls_en)) ? 0 : 1; +# else + return 0; +# endif +} + +/* + * Send a TLS record using the tls_en provided in ktls_start and use + * record_type instead of the default SSL3_RT_APPLICATION_DATA. + * When the socket is non-blocking, then this call either returns EAGAIN or + * the entire record is pushed to TCP. It is impossible to send a partial + * record using this control message. + */ +static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, + const void *data, size_t length) +{ + struct msghdr msg = { 0 }; + int cmsg_len = sizeof(record_type); + struct cmsghdr *cmsg; + char buf[CMSG_SPACE(cmsg_len)]; + struct iovec msg_iov; /* Vector of data to send/receive into */ + + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_TCP; + cmsg->cmsg_type = TLS_SET_RECORD_TYPE; + cmsg->cmsg_len = CMSG_LEN(cmsg_len); + *((unsigned char *)CMSG_DATA(cmsg)) = record_type; + msg.msg_controllen = cmsg->cmsg_len; + + msg_iov.iov_base = (void *)data; + msg_iov.iov_len = length; + msg.msg_iov = &msg_iov; + msg.msg_iovlen = 1; + + return sendmsg(fd, &msg, 0); +} + +# ifdef OPENSSL_NO_KTLS_RX + +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + return -1; +} + +# else /* !defined(OPENSSL_NO_KTLS_RX) */ + +/* + * Receive a TLS record using the tls_en provided in ktls_start. The + * kernel strips any explicit IV and authentication tag, but provides + * the TLS record header via a control message. If there is an error + * with the TLS record such as an invalid header, invalid padding, or + * authentication failure recvmsg() will fail with an error. + */ +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + struct msghdr msg = { 0 }; + int cmsg_len = sizeof(struct tls_get_record); + struct tls_get_record *tgr; + struct cmsghdr *cmsg; + char buf[CMSG_SPACE(cmsg_len)]; + struct iovec msg_iov; /* Vector of data to send/receive into */ + int ret; + unsigned char *p = data; + const size_t prepend_length = SSL3_RT_HEADER_LENGTH; + + if (length <= prepend_length) { + errno = EINVAL; + return -1; + } + + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + + msg_iov.iov_base = p + prepend_length; + msg_iov.iov_len = length - prepend_length; + msg.msg_iov = &msg_iov; + msg.msg_iovlen = 1; + + ret = recvmsg(fd, &msg, 0); + if (ret <= 0) + return ret; + + if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) { + errno = EMSGSIZE; + return -1; + } + + if (msg.msg_controllen == 0) { + errno = EBADMSG; + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD + || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) { + errno = EBADMSG; + return -1; + } + + tgr = (struct tls_get_record *)CMSG_DATA(cmsg); + p[0] = tgr->tls_type; + p[1] = tgr->tls_vmajor; + p[2] = tgr->tls_vminor; + *(uint16_t *)(p + 3) = htons(ret); + + return ret + prepend_length; +} + +# endif /* OPENSSL_NO_KTLS_RX */ + +/* + * KTLS enables the sendfile system call to send data from a file over + * TLS. + */ +static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, + size_t size, int flags) +{ + off_t sbytes = 0; + int ret; + + ret = sendfile(fd, s, off, size, NULL, &sbytes, flags); + if (ret == -1 && sbytes == 0) + return -1; + return sbytes; +} + +# endif /* __FreeBSD__ */ + +# if defined(OPENSSL_SYS_LINUX) + +# include +# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) +# define OPENSSL_NO_KTLS_RX +# ifndef PEDANTIC +# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" +# warning "Skipping Compilation of KTLS receive data path" +# endif +# endif +# define OPENSSL_KTLS_AES_GCM_128 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) +# define OPENSSL_KTLS_AES_GCM_256 +# define OPENSSL_KTLS_TLS13 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) +# define OPENSSL_KTLS_AES_CCM_128 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +# ifndef OPENSSL_NO_CHACHA +# define OPENSSL_KTLS_CHACHA20_POLY1305 +# endif +# endif +# endif +# endif + +# include +# include +# include +# include +# include +# include + +# ifndef SOL_TLS +# define SOL_TLS 282 +# endif + +# ifndef TCP_ULP +# define TCP_ULP 31 +# endif + +# ifndef TLS_RX +# define TLS_RX 2 +# endif + +struct tls_crypto_info_all { + union { +# ifdef OPENSSL_KTLS_AES_GCM_128 + struct tls12_crypto_info_aes_gcm_128 gcm128; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + struct tls12_crypto_info_aes_gcm_256 gcm256; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + struct tls12_crypto_info_aes_ccm_128 ccm128; +# endif +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + struct tls12_crypto_info_chacha20_poly1305 chacha20poly1305; +# endif + }; + size_t tls_crypto_info_len; +}; + +typedef struct tls_crypto_info_all ktls_crypto_info_t; + +/* + * When successful, this socket option doesn't change the behaviour of the + * TCP socket, except changing the TCP setsockopt handler to enable the + * processing of SOL_TLS socket options. All other functionality remains the + * same. + */ +static ossl_inline int ktls_enable(int fd) +{ + return setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) ? 0 : 1; +} + +/* + * The TLS_TX socket option changes the send/sendmsg handlers of the TCP socket. + * If successful, then data sent using this socket will be encrypted and + * encapsulated in TLS records using the crypto_info provided here. + * The TLS_RX socket option changes the recv/recvmsg handlers of the TCP socket. + * If successful, then data received using this socket will be decrypted, + * authenticated and decapsulated using the crypto_info provided here. + */ +static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *crypto_info, + int is_tx) +{ + return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, + crypto_info, crypto_info->tls_crypto_info_len) ? 0 : 1; +} + +/* + * Send a TLS record using the crypto_info provided in ktls_start and use + * record_type instead of the default SSL3_RT_APPLICATION_DATA. + * When the socket is non-blocking, then this call either returns EAGAIN or + * the entire record is pushed to TCP. It is impossible to send a partial + * record using this control message. + */ +static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, + const void *data, size_t length) +{ + struct msghdr msg; + int cmsg_len = sizeof(record_type); + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(unsigned char))]; + } cmsgbuf; + struct iovec msg_iov; /* Vector of data to send/receive into */ + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_TLS; + cmsg->cmsg_type = TLS_SET_RECORD_TYPE; + cmsg->cmsg_len = CMSG_LEN(cmsg_len); + *((unsigned char *)CMSG_DATA(cmsg)) = record_type; + msg.msg_controllen = cmsg->cmsg_len; + + msg_iov.iov_base = (void *)data; + msg_iov.iov_len = length; + msg.msg_iov = &msg_iov; + msg.msg_iovlen = 1; + + return sendmsg(fd, &msg, 0); +} + +/* + * KTLS enables the sendfile system call to send data from a file over TLS. + * @flags are ignored on Linux. (placeholder for FreeBSD sendfile) + * */ +static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) +{ + return sendfile(s, fd, &off, size); +} + +# ifdef OPENSSL_NO_KTLS_RX + + +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + return -1; +} + +# else /* !defined(OPENSSL_NO_KTLS_RX) */ + +/* + * Receive a TLS record using the crypto_info provided in ktls_start. + * The kernel strips the TLS record header, IV and authentication tag, + * returning only the plaintext data or an error on failure. + * We add the TLS record header here to satisfy routines in rec_layer_s3.c + */ +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(unsigned char))]; + } cmsgbuf; + struct iovec msg_iov; + int ret; + unsigned char *p = data; + const size_t prepend_length = SSL3_RT_HEADER_LENGTH; + + if (length < prepend_length + EVP_GCM_TLS_TAG_LEN) { + errno = EINVAL; + return -1; + } + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + + msg_iov.iov_base = p + prepend_length; + msg_iov.iov_len = length - prepend_length - EVP_GCM_TLS_TAG_LEN; + msg.msg_iov = &msg_iov; + msg.msg_iovlen = 1; + + ret = recvmsg(fd, &msg, 0); + if (ret < 0) + return ret; + + if (msg.msg_controllen > 0) { + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg->cmsg_type == TLS_GET_RECORD_TYPE) { + p[0] = *((unsigned char *)CMSG_DATA(cmsg)); + p[1] = TLS1_2_VERSION_MAJOR; + p[2] = TLS1_2_VERSION_MINOR; + /* returned length is limited to msg_iov.iov_len above */ + p[3] = (ret >> 8) & 0xff; + p[4] = ret & 0xff; + ret += prepend_length; + } + } + + return ret; +} + +# endif /* OPENSSL_NO_KTLS_RX */ + +# endif /* OPENSSL_SYS_LINUX */ +# endif /* OPENSSL_NO_KTLS */ +#endif /* HEADER_INTERNAL_KTLS */ -- cgit v1.2.3