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