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