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