Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/system/ktls.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2021 Free Software Foundation, Inc.
3
 *
4
 * Author: Fratnišek Krenželok
5
 *
6
 * This file is part of GnuTLS.
7
 *
8
 * The GnuTLS is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
#include "config.h"
24
#include "system/ktls.h"
25
26
#ifdef ENABLE_KTLS
27
28
#include <sys/socket.h>
29
#include <netinet/tcp.h>
30
#include <unistd.h>
31
#include <errno.h>
32
#include "record.h"
33
34
#if defined(__FreeBSD__)
35
#include <sys/ktls.h>
36
#include <sys/types.h>
37
#include <netinet/in.h>
38
#include <crypto/cryptodev.h>
39
40
#else
41
#include <linux/tls.h>
42
#include "ext/session_ticket.h"
43
#include <sys/sendfile.h>
44
#include <sys/utsname.h>
45
#endif
46
47
/**
48
 * gnutls_transport_is_ktls_enabled:
49
 * @session: is a #gnutls_session_t type.
50
 *
51
 * Checks if KTLS is now enabled and was properly inicialized.
52
 *
53
 * Returns: %GNUTLS_KTLS_RECV, %GNUTLS_KTLS_SEND, %GNUTLS_KTLS_DUPLEX, otherwise 0
54
 *
55
 * Since: 3.7.3
56
 **/
57
gnutls_transport_ktls_enable_flags_t
58
gnutls_transport_is_ktls_enabled(gnutls_session_t session)
59
{
60
  if (unlikely(!session->internals.initial_negotiation_completed)) {
61
    _gnutls_debug_log("Initial negotiation is not yet complete\n");
62
    return 0;
63
  }
64
65
  return session->internals.ktls_enabled;
66
}
67
68
void _gnutls_ktls_enable(gnutls_session_t session)
69
{
70
#if defined(__FreeBSD__)
71
  session->internals.ktls_enabled |= GNUTLS_KTLS_RECV;
72
  session->internals.ktls_enabled |= GNUTLS_KTLS_SEND;
73
#else
74
  int sockin, sockout;
75
76
  gnutls_transport_get_int2(session, &sockin, &sockout);
77
78
  if (setsockopt(sockin, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) == 0) {
79
    session->internals.ktls_enabled |= GNUTLS_KTLS_RECV;
80
    if (sockin == sockout) {
81
      session->internals.ktls_enabled |= GNUTLS_KTLS_SEND;
82
    }
83
  } else {
84
    _gnutls_record_log(
85
      "Unable to set TCP_ULP for read socket: %d\n", errno);
86
  }
87
88
  if (sockin != sockout) {
89
    if (setsockopt(sockout, SOL_TCP, TCP_ULP, "tls",
90
             sizeof("tls")) == 0) {
91
      session->internals.ktls_enabled |= GNUTLS_KTLS_SEND;
92
    } else {
93
      _gnutls_record_log(
94
        "Unable to set TCP_ULP for write socket: %d\n",
95
        errno);
96
    }
97
  }
98
#endif
99
}
100
101
#if defined(__FreeBSD__)
102
103
int _gnutls_ktls_set_keys(gnutls_session_t session,
104
        gnutls_transport_ktls_enable_flags_t in)
105
{
106
  gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(session);
107
  gnutls_datum_t mac_key;
108
  gnutls_datum_t iv;
109
  gnutls_datum_t cipher_key;
110
  unsigned char seq_number[12];
111
  int sockin, sockout;
112
  int ret;
113
114
  gnutls_transport_get_int2(session, &sockin, &sockout);
115
  /* check whether or not cipher suite supports ktls
116
   */
117
  int version = gnutls_protocol_get_version(session);
118
  if ((version != GNUTLS_TLS1_3 && version != GNUTLS_TLS1_2) ||
119
      (cipher != GNUTLS_CIPHER_AES_128_GCM &&
120
       cipher != GNUTLS_CIPHER_AES_256_GCM &&
121
       cipher != GNUTLS_CIPHER_CHACHA20_POLY1305)) {
122
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
123
  }
124
125
  ret = gnutls_record_get_state(session, 1, &mac_key, &iv, &cipher_key,
126
              seq_number);
127
  if (ret < 0) {
128
    return ret;
129
  }
130
131
  in &= session->internals.ktls_enabled;
132
133
  if (in & GNUTLS_KTLS_RECV) {
134
    struct tls_enable crypto_info;
135
    memset(&crypto_info, 0, sizeof(crypto_info));
136
    switch (cipher) {
137
    case GNUTLS_CIPHER_AES_128_GCM: {
138
      crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
139
      assert(cipher_key.size == AES_128_GMAC_KEY_LEN);
140
141
      if (version == GNUTLS_TLS1_2) {
142
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
143
        crypto_info.tls_vminor = TLS_MINOR_VER_TWO;
144
        crypto_info.iv =
145
          gnutls_malloc(TLS_AEAD_GCM_LEN);
146
        if (!crypto_info.iv) {
147
          gnutls_assert();
148
          return GNUTLS_E_MEMORY_ERROR;
149
        }
150
        crypto_info.iv_len = TLS_AEAD_GCM_LEN;
151
        memcpy(crypto_info.iv, seq_number,
152
               TLS_AEAD_GCM_LEN);
153
      } else {
154
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
155
        crypto_info.tls_vminor = TLS_MINOR_VER_THREE;
156
        assert(iv.size == TLS_1_3_GCM_IV_LEN);
157
158
        crypto_info.iv =
159
          gnutls_malloc(TLS_1_3_GCM_IV_LEN);
160
        if (!crypto_info.iv) {
161
          gnutls_assert();
162
          return GNUTLS_E_MEMORY_ERROR;
163
        }
164
        crypto_info.iv_len = TLS_1_3_GCM_IV_LEN;
165
        memcpy(crypto_info.iv, iv.data,
166
               TLS_1_3_GCM_IV_LEN);
167
      }
168
169
      memcpy(crypto_info.rec_seq, seq_number, 8);
170
171
      crypto_info.cipher_key_len = AES_128_GMAC_KEY_LEN;
172
      crypto_info.cipher_key =
173
        gnutls_malloc(AES_128_GMAC_KEY_LEN);
174
      if (!crypto_info.cipher_key) {
175
        gnutls_assert();
176
        return GNUTLS_E_MEMORY_ERROR;
177
      }
178
      memcpy(crypto_info.cipher_key, cipher_key.data,
179
             AES_128_GMAC_KEY_LEN);
180
181
      if (setsockopt(sockin, IPPROTO_TCP, TCP_RXTLS_ENABLE,
182
               &crypto_info, sizeof(crypto_info))) {
183
        session->internals.ktls_enabled &=
184
          ~GNUTLS_KTLS_RECV;
185
        return gnutls_assert_val(
186
          GNUTLS_E_INTERNAL_ERROR);
187
      }
188
    } break;
189
    case GNUTLS_CIPHER_AES_256_GCM: {
190
      crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
191
      assert(cipher_key.size == AES_256_GMAC_KEY_LEN);
192
193
      if (version == GNUTLS_TLS1_2) {
194
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
195
        crypto_info.tls_vminor = TLS_MINOR_VER_TWO;
196
        crypto_info.iv =
197
          gnutls_malloc(TLS_AEAD_GCM_LEN);
198
        if (!crypto_info.iv) {
199
          gnutls_assert();
200
          return GNUTLS_E_MEMORY_ERROR;
201
        }
202
        crypto_info.iv_len = TLS_AEAD_GCM_LEN;
203
        memcpy(crypto_info.iv, seq_number,
204
               TLS_AEAD_GCM_LEN);
205
      } else {
206
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
207
        crypto_info.tls_vminor = TLS_MINOR_VER_THREE;
208
        assert(iv.size == TLS_1_3_GCM_IV_LEN);
209
210
        crypto_info.iv =
211
          gnutls_malloc(TLS_1_3_GCM_IV_LEN);
212
        if (!crypto_info.iv) {
213
          gnutls_assert();
214
          return GNUTLS_E_MEMORY_ERROR;
215
        }
216
        crypto_info.iv_len = TLS_1_3_GCM_IV_LEN;
217
        memcpy(crypto_info.iv, iv.data,
218
               TLS_1_3_GCM_IV_LEN);
219
      }
220
221
      memcpy(crypto_info.rec_seq, seq_number, 8);
222
223
      crypto_info.cipher_key_len = AES_256_GMAC_KEY_LEN;
224
      crypto_info.cipher_key =
225
        gnutls_malloc(AES_256_GMAC_KEY_LEN);
226
      if (!crypto_info.cipher_key) {
227
        gnutls_assert();
228
        return GNUTLS_E_MEMORY_ERROR;
229
      }
230
      memcpy(crypto_info.cipher_key, cipher_key.data,
231
             AES_256_GMAC_KEY_LEN);
232
233
      if (setsockopt(sockin, IPPROTO_TCP, TCP_RXTLS_ENABLE,
234
               &crypto_info, sizeof(crypto_info))) {
235
        session->internals.ktls_enabled &=
236
          ~GNUTLS_KTLS_RECV;
237
        return gnutls_assert_val(
238
          GNUTLS_E_INTERNAL_ERROR);
239
      }
240
241
    } break;
242
    case GNUTLS_CIPHER_CHACHA20_POLY1305: {
243
      crypto_info.cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
244
      assert(cipher_key.size == POLY1305_KEY_LEN);
245
246
      if (version == GNUTLS_TLS1_2) {
247
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
248
        crypto_info.tls_vminor = TLS_MINOR_VER_TWO;
249
      } else {
250
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
251
        crypto_info.tls_vminor = TLS_MINOR_VER_THREE;
252
      }
253
254
      assert(iv.size == CHACHA20_POLY1305_IV_LEN);
255
      crypto_info.iv =
256
        gnutls_malloc(CHACHA20_POLY1305_IV_LEN);
257
      if (!crypto_info.iv) {
258
        gnutls_assert();
259
        return GNUTLS_E_MEMORY_ERROR;
260
      }
261
      crypto_info.iv_len = TLS_CHACHA20_IV_LEN;
262
      memcpy(crypto_info.iv, iv.data, TLS_CHACHA20_IV_LEN);
263
264
      memcpy(crypto_info.rec_seq, seq_number, 8);
265
266
      crypto_info.cipher_key_len = POLY1305_KEY_LEN;
267
      crypto_info.cipher_key =
268
        gnutls_malloc(POLY1305_KEY_LEN);
269
      if (!crypto_info.cipher_key) {
270
        gnutls_assert();
271
        return GNUTLS_E_MEMORY_ERROR;
272
      }
273
      memcpy(crypto_info.cipher_key, cipher_key.data,
274
             POLY1305_KEY_LEN);
275
276
      if (setsockopt(sockin, IPPROTO_TCP, TCP_RXTLS_ENABLE,
277
               &crypto_info, sizeof(crypto_info))) {
278
        session->internals.ktls_enabled &=
279
          ~GNUTLS_KTLS_RECV;
280
        return gnutls_assert_val(
281
          GNUTLS_E_INTERNAL_ERROR);
282
      }
283
284
    } break;
285
    default:
286
      assert(0);
287
    }
288
  }
289
290
  ret = gnutls_record_get_state(session, 0, &mac_key, &iv, &cipher_key,
291
              seq_number);
292
  if (ret < 0) {
293
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
294
  }
295
296
  if (in & GNUTLS_KTLS_SEND) {
297
    struct tls_enable crypto_info;
298
    memset(&crypto_info, 0, sizeof(crypto_info));
299
    switch (cipher) {
300
    case GNUTLS_CIPHER_AES_128_GCM: {
301
      crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
302
      assert(cipher_key.size == AES_128_GMAC_KEY_LEN);
303
304
      if (version == GNUTLS_TLS1_2) {
305
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
306
        crypto_info.tls_vminor = TLS_MINOR_VER_TWO;
307
        crypto_info.iv =
308
          gnutls_malloc(TLS_AEAD_GCM_LEN);
309
        if (!crypto_info.iv) {
310
          gnutls_assert();
311
          return GNUTLS_E_MEMORY_ERROR;
312
        }
313
        crypto_info.iv_len = TLS_AEAD_GCM_LEN;
314
        memcpy(crypto_info.iv, seq_number,
315
               TLS_AEAD_GCM_LEN);
316
      } else {
317
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
318
        crypto_info.tls_vminor = TLS_MINOR_VER_THREE;
319
        assert(iv.size == TLS_1_3_GCM_IV_LEN);
320
321
        crypto_info.iv =
322
          gnutls_malloc(TLS_1_3_GCM_IV_LEN);
323
        if (!crypto_info.iv) {
324
          gnutls_assert();
325
          return GNUTLS_E_MEMORY_ERROR;
326
        }
327
        crypto_info.iv_len = TLS_1_3_GCM_IV_LEN;
328
        memcpy(crypto_info.iv, iv.data,
329
               TLS_1_3_GCM_IV_LEN);
330
      }
331
332
      memcpy(crypto_info.rec_seq, seq_number, 8);
333
334
      crypto_info.cipher_key_len = AES_128_GMAC_KEY_LEN;
335
      crypto_info.cipher_key =
336
        gnutls_malloc(AES_128_GMAC_KEY_LEN);
337
      if (!crypto_info.cipher_key) {
338
        gnutls_assert();
339
        return GNUTLS_E_MEMORY_ERROR;
340
      }
341
      memcpy(crypto_info.cipher_key, cipher_key.data,
342
             AES_128_GMAC_KEY_LEN);
343
344
      if (setsockopt(sockin, IPPROTO_TCP, TCP_TXTLS_ENABLE,
345
               &crypto_info, sizeof(crypto_info))) {
346
        session->internals.ktls_enabled &=
347
          ~GNUTLS_KTLS_SEND;
348
        return gnutls_assert_val(
349
          GNUTLS_E_INTERNAL_ERROR);
350
      }
351
    } break;
352
    case GNUTLS_CIPHER_AES_256_GCM: {
353
      crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
354
      assert(cipher_key.size == AES_256_GMAC_KEY_LEN);
355
356
      if (version == GNUTLS_TLS1_2) {
357
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
358
        crypto_info.tls_vminor = TLS_MINOR_VER_TWO;
359
        crypto_info.iv =
360
          gnutls_malloc(TLS_AEAD_GCM_LEN);
361
        if (!crypto_info.iv) {
362
          gnutls_assert();
363
          return GNUTLS_E_MEMORY_ERROR;
364
        }
365
        crypto_info.iv_len = TLS_AEAD_GCM_LEN;
366
        memcpy(crypto_info.iv, seq_number,
367
               TLS_AEAD_GCM_LEN);
368
      } else {
369
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
370
        crypto_info.tls_vminor = TLS_MINOR_VER_THREE;
371
        assert(iv.size == TLS_1_3_GCM_IV_LEN);
372
373
        crypto_info.iv =
374
          gnutls_malloc(TLS_1_3_GCM_IV_LEN);
375
        if (!crypto_info.iv) {
376
          gnutls_assert();
377
          return GNUTLS_E_MEMORY_ERROR;
378
        }
379
        crypto_info.iv_len = TLS_1_3_GCM_IV_LEN;
380
        memcpy(crypto_info.iv, iv.data,
381
               TLS_1_3_GCM_IV_LEN);
382
      }
383
384
      memcpy(crypto_info.rec_seq, seq_number, 8);
385
386
      crypto_info.cipher_key_len = AES_256_GMAC_KEY_LEN;
387
      crypto_info.cipher_key =
388
        gnutls_malloc(AES_256_GMAC_KEY_LEN);
389
      if (!crypto_info.cipher_key) {
390
        gnutls_assert();
391
        return GNUTLS_E_MEMORY_ERROR;
392
      }
393
      memcpy(crypto_info.cipher_key, cipher_key.data,
394
             AES_256_GMAC_KEY_LEN);
395
396
      if (setsockopt(sockin, IPPROTO_TCP, TCP_TXTLS_ENABLE,
397
               &crypto_info, sizeof(crypto_info))) {
398
        session->internals.ktls_enabled &=
399
          ~GNUTLS_KTLS_SEND;
400
        return gnutls_assert_val(
401
          GNUTLS_E_INTERNAL_ERROR);
402
      }
403
404
    } break;
405
    case GNUTLS_CIPHER_CHACHA20_POLY1305: {
406
      crypto_info.cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
407
      assert(cipher_key.size == POLY1305_KEY_LEN);
408
409
      if (version == GNUTLS_TLS1_2) {
410
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
411
        crypto_info.tls_vminor = TLS_MINOR_VER_TWO;
412
      } else {
413
        crypto_info.tls_vmajor = TLS_MAJOR_VER_ONE;
414
        crypto_info.tls_vminor = TLS_MINOR_VER_THREE;
415
      }
416
417
      assert(iv.size == CHACHA20_POLY1305_IV_LEN);
418
      crypto_info.iv =
419
        gnutls_malloc(CHACHA20_POLY1305_IV_LEN);
420
      if (!crypto_info.iv) {
421
        gnutls_assert();
422
        return GNUTLS_E_MEMORY_ERROR;
423
      }
424
      crypto_info.iv_len = TLS_CHACHA20_IV_LEN;
425
      memcpy(crypto_info.iv, iv.data, TLS_CHACHA20_IV_LEN);
426
427
      memcpy(crypto_info.rec_seq, seq_number, 8);
428
429
      crypto_info.cipher_key_len = POLY1305_KEY_LEN;
430
      crypto_info.cipher_key =
431
        gnutls_malloc(POLY1305_KEY_LEN);
432
      if (!crypto_info.cipher_key) {
433
        gnutls_assert();
434
        return GNUTLS_E_MEMORY_ERROR;
435
      }
436
      memcpy(crypto_info.cipher_key, cipher_key.data,
437
             POLY1305_KEY_LEN);
438
439
      if (setsockopt(sockin, IPPROTO_TCP, TCP_TXTLS_ENABLE,
440
               &crypto_info, sizeof(crypto_info))) {
441
        session->internals.ktls_enabled &=
442
          ~GNUTLS_KTLS_SEND;
443
        return gnutls_assert_val(
444
          GNUTLS_E_INTERNAL_ERROR);
445
      }
446
447
    } break;
448
    default:
449
      assert(0);
450
    }
451
452
    // set callback for sending handshake messages
453
    gnutls_handshake_set_read_function(
454
      session, _gnutls_ktls_send_handshake_msg);
455
456
    // set callback for sending alert messages
457
    gnutls_alert_set_read_function(session,
458
                 _gnutls_ktls_send_alert_msg);
459
  }
460
461
  return in;
462
}
463
#else
464
465
int _gnutls_ktls_set_keys(gnutls_session_t session,
466
        gnutls_transport_ktls_enable_flags_t in)
467
{
468
  gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(session);
469
  int version = gnutls_protocol_get_version(session);
470
  struct utsname utsname;
471
  char *endptr;
472
  long major, minor;
473
  gnutls_datum_t mac_key;
474
  gnutls_datum_t iv;
475
  gnutls_datum_t cipher_key;
476
  unsigned char seq_number[12];
477
  int sockin, sockout;
478
  int ret;
479
480
  ret = uname(&utsname);
481
  if (unlikely(ret < 0)) {
482
    return GNUTLS_E_INTERNAL_ERROR;
483
  }
484
485
  if (strcmp(utsname.sysname, "Linux") != 0) {
486
    return GNUTLS_E_INTERNAL_ERROR;
487
  }
488
489
  major = strtol(utsname.release, &endptr, 10);
490
  if (major < 0 || major == LONG_MAX || *endptr != '.') {
491
    return GNUTLS_E_INTERNAL_ERROR;
492
  }
493
  minor = strtol(endptr + 1, &endptr, 10);
494
  if (minor < 0 || minor == LONG_MAX || *endptr != '.') {
495
    return GNUTLS_E_INTERNAL_ERROR;
496
  }
497
498
  _gnutls_debug_log("Linux kernel version %lu.%lu has been detected\n",
499
        major, minor);
500
501
  /* setsockopt(SOL_TLS, TLS_RX) support added in 5.10 */
502
  if (major < 5 || (major == 5 && minor < 10)) {
503
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
504
  }
505
506
  /* check whether or not cipher suite supports ktls
507
   */
508
  switch (cipher) {
509
  case GNUTLS_CIPHER_AES_128_GCM:
510
  case GNUTLS_CIPHER_AES_256_GCM:
511
    break;
512
  case GNUTLS_CIPHER_AES_128_CCM:
513
  case GNUTLS_CIPHER_CHACHA20_POLY1305:
514
    /* AES-128-CCM and CHACHA20-POLY1305 can only be set
515
     * using setsockopt since 5.11.
516
     */
517
    if (major < 5 || (major == 5 && minor < 11)) {
518
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
519
    }
520
    break;
521
  default:
522
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
523
  }
524
525
  if (version < GNUTLS_TLS1_2) {
526
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
527
  }
528
529
  gnutls_transport_get_int2(session, &sockin, &sockout);
530
531
  ret = gnutls_record_get_state(session, 1, &mac_key, &iv, &cipher_key,
532
              seq_number);
533
  if (ret < 0) {
534
    return ret;
535
  }
536
537
  in &= session->internals.ktls_enabled;
538
539
  if (in & GNUTLS_KTLS_RECV) {
540
    switch (cipher) {
541
    case GNUTLS_CIPHER_AES_128_GCM: {
542
      struct tls12_crypto_info_aes_gcm_128 crypto_info;
543
      memset(&crypto_info, 0, sizeof(crypto_info));
544
545
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
546
      assert(cipher_key.size ==
547
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
548
549
      /* for TLS 1.2 IV is generated in kernel */
550
      if (version == GNUTLS_TLS1_2) {
551
        crypto_info.info.version = TLS_1_2_VERSION;
552
        memcpy(crypto_info.iv, seq_number,
553
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
554
      } else {
555
        crypto_info.info.version = TLS_1_3_VERSION;
556
        assert(iv.size ==
557
               TLS_CIPHER_AES_GCM_128_SALT_SIZE +
558
                 TLS_CIPHER_AES_GCM_128_IV_SIZE);
559
560
        memcpy(crypto_info.iv,
561
               iv.data +
562
                 TLS_CIPHER_AES_GCM_128_SALT_SIZE,
563
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
564
      }
565
566
      memcpy(crypto_info.salt, iv.data,
567
             TLS_CIPHER_AES_GCM_128_SALT_SIZE);
568
      memcpy(crypto_info.rec_seq, seq_number,
569
             TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
570
      memcpy(crypto_info.key, cipher_key.data,
571
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
572
573
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
574
               sizeof(crypto_info))) {
575
        session->internals.ktls_enabled &=
576
          ~GNUTLS_KTLS_RECV;
577
        return gnutls_assert_val(
578
          GNUTLS_E_INTERNAL_ERROR);
579
      }
580
    } break;
581
    case GNUTLS_CIPHER_AES_256_GCM: {
582
      struct tls12_crypto_info_aes_gcm_256 crypto_info;
583
      memset(&crypto_info, 0, sizeof(crypto_info));
584
585
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256;
586
      assert(cipher_key.size ==
587
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
588
589
      /* for TLS 1.2 IV is generated in kernel */
590
      if (version == GNUTLS_TLS1_2) {
591
        crypto_info.info.version = TLS_1_2_VERSION;
592
        memcpy(crypto_info.iv, seq_number,
593
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
594
      } else {
595
        crypto_info.info.version = TLS_1_3_VERSION;
596
        assert(iv.size ==
597
               TLS_CIPHER_AES_GCM_256_SALT_SIZE +
598
                 TLS_CIPHER_AES_GCM_256_IV_SIZE);
599
600
        memcpy(crypto_info.iv,
601
               iv.data +
602
                 TLS_CIPHER_AES_GCM_256_SALT_SIZE,
603
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
604
      }
605
606
      memcpy(crypto_info.salt, iv.data,
607
             TLS_CIPHER_AES_GCM_256_SALT_SIZE);
608
      memcpy(crypto_info.rec_seq, seq_number,
609
             TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
610
      memcpy(crypto_info.key, cipher_key.data,
611
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
612
613
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
614
               sizeof(crypto_info))) {
615
        session->internals.ktls_enabled &=
616
          ~GNUTLS_KTLS_RECV;
617
        return gnutls_assert_val(
618
          GNUTLS_E_INTERNAL_ERROR);
619
      }
620
    } break;
621
    case GNUTLS_CIPHER_AES_128_CCM: {
622
      struct tls12_crypto_info_aes_ccm_128 crypto_info;
623
      memset(&crypto_info, 0, sizeof(crypto_info));
624
625
      crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128;
626
      assert(cipher_key.size ==
627
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
628
629
      /* for TLS 1.2 IV is generated in kernel */
630
      if (version == GNUTLS_TLS1_2) {
631
        crypto_info.info.version = TLS_1_2_VERSION;
632
        memcpy(crypto_info.iv, seq_number,
633
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
634
      } else {
635
        crypto_info.info.version = TLS_1_3_VERSION;
636
        assert(iv.size ==
637
               TLS_CIPHER_AES_CCM_128_SALT_SIZE +
638
                 TLS_CIPHER_AES_CCM_128_IV_SIZE);
639
640
        memcpy(crypto_info.iv,
641
               iv.data +
642
                 TLS_CIPHER_AES_CCM_128_SALT_SIZE,
643
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
644
      }
645
646
      memcpy(crypto_info.salt, iv.data,
647
             TLS_CIPHER_AES_CCM_128_SALT_SIZE);
648
      memcpy(crypto_info.rec_seq, seq_number,
649
             TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
650
      memcpy(crypto_info.key, cipher_key.data,
651
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
652
653
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
654
               sizeof(crypto_info))) {
655
        session->internals.ktls_enabled &=
656
          ~GNUTLS_KTLS_RECV;
657
        return gnutls_assert_val(
658
          GNUTLS_E_INTERNAL_ERROR);
659
      }
660
    } break;
661
    case GNUTLS_CIPHER_CHACHA20_POLY1305: {
662
      struct tls12_crypto_info_chacha20_poly1305 crypto_info;
663
      memset(&crypto_info, 0, sizeof(crypto_info));
664
665
      crypto_info.info.cipher_type =
666
        TLS_CIPHER_CHACHA20_POLY1305;
667
      assert(cipher_key.size ==
668
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
669
670
      /* for TLS 1.2 IV is generated in kernel */
671
      if (version == GNUTLS_TLS1_2) {
672
        crypto_info.info.version = TLS_1_2_VERSION;
673
        memcpy(crypto_info.iv, seq_number,
674
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
675
      } else {
676
        crypto_info.info.version = TLS_1_3_VERSION;
677
        assert(iv.size ==
678
               TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE +
679
                 TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
680
681
        memcpy(crypto_info.iv,
682
               iv.data +
683
                 TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
684
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
685
      }
686
687
      memcpy(crypto_info.salt, iv.data,
688
             TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE);
689
      memcpy(crypto_info.rec_seq, seq_number,
690
             TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
691
      memcpy(crypto_info.key, cipher_key.data,
692
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
693
694
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
695
               sizeof(crypto_info))) {
696
        session->internals.ktls_enabled &=
697
          ~GNUTLS_KTLS_RECV;
698
        return gnutls_assert_val(
699
          GNUTLS_E_INTERNAL_ERROR);
700
      }
701
    } break;
702
    default:
703
      assert(0);
704
    }
705
  }
706
707
  ret = gnutls_record_get_state(session, 0, &mac_key, &iv, &cipher_key,
708
              seq_number);
709
  if (ret < 0) {
710
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
711
  }
712
713
  if (in & GNUTLS_KTLS_SEND) {
714
    switch (cipher) {
715
    case GNUTLS_CIPHER_AES_128_GCM: {
716
      struct tls12_crypto_info_aes_gcm_128 crypto_info;
717
      memset(&crypto_info, 0, sizeof(crypto_info));
718
719
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
720
721
      assert(cipher_key.size ==
722
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
723
724
      /* for TLS 1.2 IV is generated in kernel */
725
      if (version == GNUTLS_TLS1_2) {
726
        crypto_info.info.version = TLS_1_2_VERSION;
727
        memcpy(crypto_info.iv, seq_number,
728
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
729
      } else {
730
        crypto_info.info.version = TLS_1_3_VERSION;
731
        assert(iv.size ==
732
               TLS_CIPHER_AES_GCM_128_SALT_SIZE +
733
                 TLS_CIPHER_AES_GCM_128_IV_SIZE);
734
735
        memcpy(crypto_info.iv,
736
               iv.data +
737
                 TLS_CIPHER_AES_GCM_128_SALT_SIZE,
738
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
739
      }
740
741
      memcpy(crypto_info.salt, iv.data,
742
             TLS_CIPHER_AES_GCM_128_SALT_SIZE);
743
      memcpy(crypto_info.rec_seq, seq_number,
744
             TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
745
      memcpy(crypto_info.key, cipher_key.data,
746
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
747
748
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
749
               sizeof(crypto_info))) {
750
        session->internals.ktls_enabled &=
751
          ~GNUTLS_KTLS_SEND;
752
        return gnutls_assert_val(
753
          GNUTLS_E_INTERNAL_ERROR);
754
      }
755
    } break;
756
    case GNUTLS_CIPHER_AES_256_GCM: {
757
      struct tls12_crypto_info_aes_gcm_256 crypto_info;
758
      memset(&crypto_info, 0, sizeof(crypto_info));
759
760
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256;
761
      assert(cipher_key.size ==
762
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
763
764
      /* for TLS 1.2 IV is generated in kernel */
765
      if (version == GNUTLS_TLS1_2) {
766
        crypto_info.info.version = TLS_1_2_VERSION;
767
        memcpy(crypto_info.iv, seq_number,
768
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
769
      } else {
770
        crypto_info.info.version = TLS_1_3_VERSION;
771
        assert(iv.size ==
772
               TLS_CIPHER_AES_GCM_256_SALT_SIZE +
773
                 TLS_CIPHER_AES_GCM_256_IV_SIZE);
774
775
        memcpy(crypto_info.iv,
776
               iv.data +
777
                 TLS_CIPHER_AES_GCM_256_SALT_SIZE,
778
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
779
      }
780
781
      memcpy(crypto_info.salt, iv.data,
782
             TLS_CIPHER_AES_GCM_256_SALT_SIZE);
783
      memcpy(crypto_info.rec_seq, seq_number,
784
             TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
785
      memcpy(crypto_info.key, cipher_key.data,
786
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
787
788
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
789
               sizeof(crypto_info))) {
790
        session->internals.ktls_enabled &=
791
          ~GNUTLS_KTLS_SEND;
792
        return gnutls_assert_val(
793
          GNUTLS_E_INTERNAL_ERROR);
794
      }
795
    } break;
796
    case GNUTLS_CIPHER_AES_128_CCM: {
797
      struct tls12_crypto_info_aes_ccm_128 crypto_info;
798
      memset(&crypto_info, 0, sizeof(crypto_info));
799
800
      crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128;
801
      assert(cipher_key.size ==
802
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
803
804
      /* for TLS 1.2 IV is generated in kernel */
805
      if (version == GNUTLS_TLS1_2) {
806
        crypto_info.info.version = TLS_1_2_VERSION;
807
        memcpy(crypto_info.iv, seq_number,
808
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
809
      } else {
810
        crypto_info.info.version = TLS_1_3_VERSION;
811
        assert(iv.size ==
812
               TLS_CIPHER_AES_CCM_128_SALT_SIZE +
813
                 TLS_CIPHER_AES_CCM_128_IV_SIZE);
814
815
        memcpy(crypto_info.iv,
816
               iv.data +
817
                 TLS_CIPHER_AES_CCM_128_SALT_SIZE,
818
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
819
      }
820
821
      memcpy(crypto_info.salt, iv.data,
822
             TLS_CIPHER_AES_CCM_128_SALT_SIZE);
823
      memcpy(crypto_info.rec_seq, seq_number,
824
             TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
825
      memcpy(crypto_info.key, cipher_key.data,
826
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
827
828
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
829
               sizeof(crypto_info))) {
830
        session->internals.ktls_enabled &=
831
          ~GNUTLS_KTLS_SEND;
832
        return gnutls_assert_val(
833
          GNUTLS_E_INTERNAL_ERROR);
834
      }
835
    } break;
836
    case GNUTLS_CIPHER_CHACHA20_POLY1305: {
837
      struct tls12_crypto_info_chacha20_poly1305 crypto_info;
838
      memset(&crypto_info, 0, sizeof(crypto_info));
839
840
      crypto_info.info.cipher_type =
841
        TLS_CIPHER_CHACHA20_POLY1305;
842
      assert(cipher_key.size ==
843
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
844
845
      /* for TLS 1.2 IV is generated in kernel */
846
      if (version == GNUTLS_TLS1_2) {
847
        crypto_info.info.version = TLS_1_2_VERSION;
848
        memcpy(crypto_info.iv, seq_number,
849
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
850
      } else {
851
        crypto_info.info.version = TLS_1_3_VERSION;
852
        assert(iv.size ==
853
               TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE +
854
                 TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
855
856
        memcpy(crypto_info.iv,
857
               iv.data +
858
                 TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
859
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
860
      }
861
862
      memcpy(crypto_info.salt, iv.data,
863
             TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE);
864
      memcpy(crypto_info.rec_seq, seq_number,
865
             TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
866
      memcpy(crypto_info.key, cipher_key.data,
867
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
868
869
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
870
               sizeof(crypto_info))) {
871
        session->internals.ktls_enabled &=
872
          ~GNUTLS_KTLS_SEND;
873
        return gnutls_assert_val(
874
          GNUTLS_E_INTERNAL_ERROR);
875
      }
876
    } break;
877
    default:
878
      assert(0);
879
    }
880
881
    // set callback for sending handshake messages
882
    gnutls_handshake_set_read_function(
883
      session, _gnutls_ktls_send_handshake_msg);
884
885
    // set callback for sending alert messages
886
    gnutls_alert_set_read_function(session,
887
                 _gnutls_ktls_send_alert_msg);
888
  }
889
890
  return in;
891
}
892
#endif
893
894
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd, off_t *offset,
895
             size_t count)
896
{
897
  ssize_t ret;
898
  int sockin, sockout;
899
900
  assert(session != NULL);
901
#if defined(__FreeBSD__)
902
  off_t sbytes = 0;
903
  assert(offset != NULL);
904
#endif
905
906
  gnutls_transport_get_int2(session, &sockin, &sockout);
907
#if defined(__FreeBSD__)
908
  ret = sendfile(fd, sockout, *offset, count, NULL, &sbytes, 0);
909
#else
910
  ret = sendfile(sockout, fd, offset, count);
911
#endif
912
  if (ret == -1) {
913
    switch (errno) {
914
    case EINTR:
915
      return GNUTLS_E_INTERRUPTED;
916
    case EAGAIN:
917
      return GNUTLS_E_AGAIN;
918
    default:
919
      return GNUTLS_E_PUSH_ERROR;
920
    }
921
  }
922
#if defined(__FreeBSD__)
923
  *offset += sbytes; /* follow linux sendfile behavior */
924
  return sbytes;
925
#else
926
  return ret;
927
#endif
928
}
929
930
int _gnutls_ktls_send_control_msg(gnutls_session_t session,
931
          unsigned char record_type, const void *data,
932
          size_t data_size)
933
{
934
  const char *buf = data;
935
  ssize_t ret;
936
  int sockin, sockout;
937
  size_t data_to_send = data_size;
938
939
  assert(session != NULL);
940
941
  gnutls_transport_get_int2(session, &sockin, &sockout);
942
943
  while (data_to_send > 0) {
944
    char cmsg[CMSG_SPACE(sizeof(unsigned char))];
945
    struct msghdr msg = { 0 };
946
    struct iovec msg_iov; /* Vector of data to send/receive into. */
947
    struct cmsghdr *hdr;
948
949
    msg.msg_control = cmsg;
950
    msg.msg_controllen = sizeof cmsg;
951
952
    hdr = CMSG_FIRSTHDR(&msg);
953
#if defined(__FreeBSD__)
954
    hdr->cmsg_level = IPPROTO_TCP;
955
#else
956
    hdr->cmsg_level = SOL_TLS;
957
#endif
958
    hdr->cmsg_type = TLS_SET_RECORD_TYPE;
959
    hdr->cmsg_len = CMSG_LEN(sizeof(unsigned char));
960
961
    // construct record header
962
    *CMSG_DATA(hdr) = record_type;
963
    msg.msg_controllen = hdr->cmsg_len;
964
965
    msg_iov.iov_base = (void *)buf;
966
    msg_iov.iov_len = data_to_send;
967
968
    msg.msg_iov = &msg_iov;
969
    msg.msg_iovlen = 1;
970
971
    ret = sendmsg(sockout, &msg, MSG_DONTWAIT);
972
973
    if (ret == -1) {
974
      switch (errno) {
975
      case EINTR:
976
        if (data_to_send < data_size) {
977
          return data_size - data_to_send;
978
        } else {
979
          return GNUTLS_E_INTERRUPTED;
980
        }
981
      case EAGAIN:
982
        if (data_to_send < data_size) {
983
          return data_size - data_to_send;
984
        } else {
985
          return GNUTLS_E_AGAIN;
986
        }
987
      default:
988
        return GNUTLS_E_PUSH_ERROR;
989
      }
990
    }
991
992
    buf += ret;
993
    data_to_send -= ret;
994
  }
995
996
  return data_size;
997
}
998
999
int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
1000
            gnutls_record_encryption_level_t level,
1001
            gnutls_handshake_description_t htype,
1002
            const void *data, size_t data_size)
1003
{
1004
  return _gnutls_ktls_send_control_msg(session, GNUTLS_HANDSHAKE, data,
1005
               data_size);
1006
}
1007
1008
int _gnutls_ktls_send_alert_msg(gnutls_session_t session,
1009
        gnutls_record_encryption_level_t level,
1010
        gnutls_alert_level_t alert_level,
1011
        gnutls_alert_description_t alert_desc)
1012
{
1013
  uint8_t data[2];
1014
  data[0] = (uint8_t)alert_level;
1015
  data[1] = (uint8_t)alert_desc;
1016
  return _gnutls_ktls_send_control_msg(session, GNUTLS_ALERT, data, 2);
1017
}
1018
1019
int _gnutls_ktls_recv_control_msg(gnutls_session_t session,
1020
          unsigned char *record_type, void *data,
1021
          size_t data_size)
1022
{
1023
  char *buf = data;
1024
  ssize_t ret;
1025
  int sockin, sockout;
1026
1027
  char cmsg[CMSG_SPACE(sizeof(unsigned char))];
1028
  struct msghdr msg = { 0 };
1029
  struct iovec msg_iov;
1030
  struct cmsghdr *hdr;
1031
1032
  assert(session != NULL);
1033
1034
  gnutls_transport_get_int2(session, &sockin, &sockout);
1035
1036
  if (session->internals.read_eof != 0) {
1037
    return 0;
1038
  } else if (session->internals.invalid_connection != 0 ||
1039
       session->internals.may_not_read != 0)
1040
    return GNUTLS_E_INVALID_SESSION;
1041
1042
  /* receive message */
1043
  msg.msg_control = cmsg;
1044
  msg.msg_controllen = sizeof cmsg;
1045
1046
  msg_iov.iov_base = buf;
1047
  msg_iov.iov_len = data_size;
1048
1049
  msg.msg_iov = &msg_iov;
1050
  msg.msg_iovlen = 1;
1051
1052
  ret = recvmsg(sockin, &msg, MSG_DONTWAIT);
1053
1054
  if (ret == -1) {
1055
    switch (errno) {
1056
    case EAGAIN:
1057
      return GNUTLS_E_AGAIN;
1058
    case EINVAL:
1059
      return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1060
    case EMSGSIZE:
1061
      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1062
    case EBADMSG:
1063
      return GNUTLS_E_DECRYPTION_FAILED;
1064
    default:
1065
      return GNUTLS_E_PULL_ERROR;
1066
    }
1067
  }
1068
1069
  /* connection closed */
1070
  if (ret == 0)
1071
    return 0;
1072
1073
  /* get record type from header */
1074
  hdr = CMSG_FIRSTHDR(&msg);
1075
  if (hdr == NULL) {
1076
    return GNUTLS_E_PULL_ERROR;
1077
  }
1078
#if defined(__FreeBSD__)
1079
  if (hdr->cmsg_level == IPPROTO_TCP && hdr->cmsg_type == TLS_GET_RECORD)
1080
#else
1081
  if (hdr->cmsg_level == SOL_TLS && hdr->cmsg_type == TLS_GET_RECORD_TYPE)
1082
#endif
1083
    *record_type = *(unsigned char *)CMSG_DATA(hdr);
1084
  else
1085
    *record_type = GNUTLS_APPLICATION_DATA;
1086
1087
  return ret;
1088
}
1089
1090
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type,
1091
        void *data, size_t data_size)
1092
{
1093
  unsigned char record_type;
1094
  int ret;
1095
1096
  ret = _gnutls_ktls_recv_control_msg(session, &record_type, data,
1097
              data_size);
1098
1099
  if (ret > 0) {
1100
    switch (record_type) {
1101
    case GNUTLS_CHANGE_CIPHER_SPEC:
1102
      return gnutls_assert_val(
1103
        GNUTLS_E_UNIMPLEMENTED_FEATURE);
1104
      break;
1105
    case GNUTLS_ALERT:
1106
      session_invalidate(session);
1107
      ret = 0;
1108
      break;
1109
    case GNUTLS_HANDSHAKE:
1110
      ret = gnutls_handshake_write(
1111
        session, GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
1112
        data, ret);
1113
1114
      if (ret < 0)
1115
        return gnutls_assert_val(ret);
1116
1117
      if (type != record_type)
1118
        return GNUTLS_E_AGAIN;
1119
      break;
1120
    case GNUTLS_APPLICATION_DATA:
1121
      if (type != record_type)
1122
        ret = GNUTLS_E_GOT_APPLICATION_DATA;
1123
      break;
1124
    case GNUTLS_HEARTBEAT:
1125
      break;
1126
    default:
1127
      gnutls_assert();
1128
      return GNUTLS_E_UNEXPECTED_PACKET;
1129
    }
1130
  }
1131
  return ret;
1132
}
1133
#else //ENABLE_KTLS
1134
gnutls_transport_ktls_enable_flags_t
1135
gnutls_transport_is_ktls_enabled(gnutls_session_t session)
1136
0
{
1137
0
  return 0;
1138
0
}
1139
1140
void _gnutls_ktls_enable(gnutls_session_t session)
1141
0
{
1142
0
}
1143
1144
int _gnutls_ktls_set_keys(gnutls_session_t sessioni,
1145
        gnutls_transport_ktls_enable_flags_t in)
1146
0
{
1147
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1148
0
}
1149
1150
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd, off_t *offset,
1151
             size_t count)
1152
0
{
1153
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1154
0
}
1155
1156
int _gnutls_ktls_send_control_msg(gnutls_session_t session,
1157
          unsigned char record_type, const void *data,
1158
          size_t data_size)
1159
0
{
1160
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1161
0
}
1162
1163
int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
1164
            gnutls_record_encryption_level_t level,
1165
            gnutls_handshake_description_t htype,
1166
            const void *data, size_t data_size)
1167
0
{
1168
0
  (void)level;
1169
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1170
0
}
1171
1172
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type,
1173
        void *data, size_t data_size)
1174
0
{
1175
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1176
0
}
1177
1178
#endif //ENABLE_KTLS