Coverage Report

Created: 2024-06-20 06:28

/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
  /* setsockopt(SOL_TLS, TLS_RX) support added in 5.10 */
499
  if (major < 5 || (major == 5 && minor < 10)) {
500
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
501
  }
502
503
  /* check whether or not cipher suite supports ktls
504
   */
505
  switch (cipher) {
506
  case GNUTLS_CIPHER_AES_128_GCM:
507
  case GNUTLS_CIPHER_AES_256_GCM:
508
    break;
509
  case GNUTLS_CIPHER_AES_128_CCM:
510
  case GNUTLS_CIPHER_CHACHA20_POLY1305:
511
    /* AES-128-CCM and CHACHA20-POLY1305 can only be set
512
     * using setsockopt since 5.11.
513
     */
514
    if (major < 5 || (major == 5 && minor < 11)) {
515
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
516
    }
517
    break;
518
  default:
519
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
520
  }
521
522
  if (version < GNUTLS_TLS1_2) {
523
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
524
  }
525
526
  gnutls_transport_get_int2(session, &sockin, &sockout);
527
528
  ret = gnutls_record_get_state(session, 1, &mac_key, &iv, &cipher_key,
529
              seq_number);
530
  if (ret < 0) {
531
    return ret;
532
  }
533
534
  in &= session->internals.ktls_enabled;
535
536
  if (in & GNUTLS_KTLS_RECV) {
537
    switch (cipher) {
538
    case GNUTLS_CIPHER_AES_128_GCM: {
539
      struct tls12_crypto_info_aes_gcm_128 crypto_info;
540
      memset(&crypto_info, 0, sizeof(crypto_info));
541
542
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
543
      assert(cipher_key.size ==
544
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
545
546
      /* for TLS 1.2 IV is generated in kernel */
547
      if (version == GNUTLS_TLS1_2) {
548
        crypto_info.info.version = TLS_1_2_VERSION;
549
        memcpy(crypto_info.iv, seq_number,
550
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
551
      } else {
552
        crypto_info.info.version = TLS_1_3_VERSION;
553
        assert(iv.size ==
554
               TLS_CIPHER_AES_GCM_128_SALT_SIZE +
555
                 TLS_CIPHER_AES_GCM_128_IV_SIZE);
556
557
        memcpy(crypto_info.iv,
558
               iv.data +
559
                 TLS_CIPHER_AES_GCM_128_SALT_SIZE,
560
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
561
      }
562
563
      memcpy(crypto_info.salt, iv.data,
564
             TLS_CIPHER_AES_GCM_128_SALT_SIZE);
565
      memcpy(crypto_info.rec_seq, seq_number,
566
             TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
567
      memcpy(crypto_info.key, cipher_key.data,
568
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
569
570
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
571
               sizeof(crypto_info))) {
572
        session->internals.ktls_enabled &=
573
          ~GNUTLS_KTLS_RECV;
574
        return gnutls_assert_val(
575
          GNUTLS_E_INTERNAL_ERROR);
576
      }
577
    } break;
578
    case GNUTLS_CIPHER_AES_256_GCM: {
579
      struct tls12_crypto_info_aes_gcm_256 crypto_info;
580
      memset(&crypto_info, 0, sizeof(crypto_info));
581
582
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256;
583
      assert(cipher_key.size ==
584
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
585
586
      /* for TLS 1.2 IV is generated in kernel */
587
      if (version == GNUTLS_TLS1_2) {
588
        crypto_info.info.version = TLS_1_2_VERSION;
589
        memcpy(crypto_info.iv, seq_number,
590
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
591
      } else {
592
        crypto_info.info.version = TLS_1_3_VERSION;
593
        assert(iv.size ==
594
               TLS_CIPHER_AES_GCM_256_SALT_SIZE +
595
                 TLS_CIPHER_AES_GCM_256_IV_SIZE);
596
597
        memcpy(crypto_info.iv,
598
               iv.data +
599
                 TLS_CIPHER_AES_GCM_256_SALT_SIZE,
600
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
601
      }
602
603
      memcpy(crypto_info.salt, iv.data,
604
             TLS_CIPHER_AES_GCM_256_SALT_SIZE);
605
      memcpy(crypto_info.rec_seq, seq_number,
606
             TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
607
      memcpy(crypto_info.key, cipher_key.data,
608
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
609
610
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
611
               sizeof(crypto_info))) {
612
        session->internals.ktls_enabled &=
613
          ~GNUTLS_KTLS_RECV;
614
        return gnutls_assert_val(
615
          GNUTLS_E_INTERNAL_ERROR);
616
      }
617
    } break;
618
    case GNUTLS_CIPHER_AES_128_CCM: {
619
      struct tls12_crypto_info_aes_ccm_128 crypto_info;
620
      memset(&crypto_info, 0, sizeof(crypto_info));
621
622
      crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128;
623
      assert(cipher_key.size ==
624
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
625
626
      /* for TLS 1.2 IV is generated in kernel */
627
      if (version == GNUTLS_TLS1_2) {
628
        crypto_info.info.version = TLS_1_2_VERSION;
629
        memcpy(crypto_info.iv, seq_number,
630
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
631
      } else {
632
        crypto_info.info.version = TLS_1_3_VERSION;
633
        assert(iv.size ==
634
               TLS_CIPHER_AES_CCM_128_SALT_SIZE +
635
                 TLS_CIPHER_AES_CCM_128_IV_SIZE);
636
637
        memcpy(crypto_info.iv,
638
               iv.data +
639
                 TLS_CIPHER_AES_CCM_128_SALT_SIZE,
640
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
641
      }
642
643
      memcpy(crypto_info.salt, iv.data,
644
             TLS_CIPHER_AES_CCM_128_SALT_SIZE);
645
      memcpy(crypto_info.rec_seq, seq_number,
646
             TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
647
      memcpy(crypto_info.key, cipher_key.data,
648
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
649
650
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
651
               sizeof(crypto_info))) {
652
        session->internals.ktls_enabled &=
653
          ~GNUTLS_KTLS_RECV;
654
        return gnutls_assert_val(
655
          GNUTLS_E_INTERNAL_ERROR);
656
      }
657
    } break;
658
    case GNUTLS_CIPHER_CHACHA20_POLY1305: {
659
      struct tls12_crypto_info_chacha20_poly1305 crypto_info;
660
      memset(&crypto_info, 0, sizeof(crypto_info));
661
662
      crypto_info.info.cipher_type =
663
        TLS_CIPHER_CHACHA20_POLY1305;
664
      assert(cipher_key.size ==
665
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
666
667
      /* for TLS 1.2 IV is generated in kernel */
668
      if (version == GNUTLS_TLS1_2) {
669
        crypto_info.info.version = TLS_1_2_VERSION;
670
        memcpy(crypto_info.iv, seq_number,
671
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
672
      } else {
673
        crypto_info.info.version = TLS_1_3_VERSION;
674
        assert(iv.size ==
675
               TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE +
676
                 TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
677
678
        memcpy(crypto_info.iv,
679
               iv.data +
680
                 TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
681
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
682
      }
683
684
      memcpy(crypto_info.salt, iv.data,
685
             TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE);
686
      memcpy(crypto_info.rec_seq, seq_number,
687
             TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
688
      memcpy(crypto_info.key, cipher_key.data,
689
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
690
691
      if (setsockopt(sockin, SOL_TLS, TLS_RX, &crypto_info,
692
               sizeof(crypto_info))) {
693
        session->internals.ktls_enabled &=
694
          ~GNUTLS_KTLS_RECV;
695
        return gnutls_assert_val(
696
          GNUTLS_E_INTERNAL_ERROR);
697
      }
698
    } break;
699
    default:
700
      assert(0);
701
    }
702
  }
703
704
  ret = gnutls_record_get_state(session, 0, &mac_key, &iv, &cipher_key,
705
              seq_number);
706
  if (ret < 0) {
707
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
708
  }
709
710
  if (in & GNUTLS_KTLS_SEND) {
711
    switch (cipher) {
712
    case GNUTLS_CIPHER_AES_128_GCM: {
713
      struct tls12_crypto_info_aes_gcm_128 crypto_info;
714
      memset(&crypto_info, 0, sizeof(crypto_info));
715
716
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
717
718
      assert(cipher_key.size ==
719
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
720
721
      /* for TLS 1.2 IV is generated in kernel */
722
      if (version == GNUTLS_TLS1_2) {
723
        crypto_info.info.version = TLS_1_2_VERSION;
724
        memcpy(crypto_info.iv, seq_number,
725
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
726
      } else {
727
        crypto_info.info.version = TLS_1_3_VERSION;
728
        assert(iv.size ==
729
               TLS_CIPHER_AES_GCM_128_SALT_SIZE +
730
                 TLS_CIPHER_AES_GCM_128_IV_SIZE);
731
732
        memcpy(crypto_info.iv,
733
               iv.data +
734
                 TLS_CIPHER_AES_GCM_128_SALT_SIZE,
735
               TLS_CIPHER_AES_GCM_128_IV_SIZE);
736
      }
737
738
      memcpy(crypto_info.salt, iv.data,
739
             TLS_CIPHER_AES_GCM_128_SALT_SIZE);
740
      memcpy(crypto_info.rec_seq, seq_number,
741
             TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
742
      memcpy(crypto_info.key, cipher_key.data,
743
             TLS_CIPHER_AES_GCM_128_KEY_SIZE);
744
745
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
746
               sizeof(crypto_info))) {
747
        session->internals.ktls_enabled &=
748
          ~GNUTLS_KTLS_SEND;
749
        return gnutls_assert_val(
750
          GNUTLS_E_INTERNAL_ERROR);
751
      }
752
    } break;
753
    case GNUTLS_CIPHER_AES_256_GCM: {
754
      struct tls12_crypto_info_aes_gcm_256 crypto_info;
755
      memset(&crypto_info, 0, sizeof(crypto_info));
756
757
      crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256;
758
      assert(cipher_key.size ==
759
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
760
761
      /* for TLS 1.2 IV is generated in kernel */
762
      if (version == GNUTLS_TLS1_2) {
763
        crypto_info.info.version = TLS_1_2_VERSION;
764
        memcpy(crypto_info.iv, seq_number,
765
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
766
      } else {
767
        crypto_info.info.version = TLS_1_3_VERSION;
768
        assert(iv.size ==
769
               TLS_CIPHER_AES_GCM_256_SALT_SIZE +
770
                 TLS_CIPHER_AES_GCM_256_IV_SIZE);
771
772
        memcpy(crypto_info.iv,
773
               iv.data +
774
                 TLS_CIPHER_AES_GCM_256_SALT_SIZE,
775
               TLS_CIPHER_AES_GCM_256_IV_SIZE);
776
      }
777
778
      memcpy(crypto_info.salt, iv.data,
779
             TLS_CIPHER_AES_GCM_256_SALT_SIZE);
780
      memcpy(crypto_info.rec_seq, seq_number,
781
             TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
782
      memcpy(crypto_info.key, cipher_key.data,
783
             TLS_CIPHER_AES_GCM_256_KEY_SIZE);
784
785
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
786
               sizeof(crypto_info))) {
787
        session->internals.ktls_enabled &=
788
          ~GNUTLS_KTLS_SEND;
789
        return gnutls_assert_val(
790
          GNUTLS_E_INTERNAL_ERROR);
791
      }
792
    } break;
793
    case GNUTLS_CIPHER_AES_128_CCM: {
794
      struct tls12_crypto_info_aes_ccm_128 crypto_info;
795
      memset(&crypto_info, 0, sizeof(crypto_info));
796
797
      crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128;
798
      assert(cipher_key.size ==
799
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
800
801
      /* for TLS 1.2 IV is generated in kernel */
802
      if (version == GNUTLS_TLS1_2) {
803
        crypto_info.info.version = TLS_1_2_VERSION;
804
        memcpy(crypto_info.iv, seq_number,
805
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
806
      } else {
807
        crypto_info.info.version = TLS_1_3_VERSION;
808
        assert(iv.size ==
809
               TLS_CIPHER_AES_CCM_128_SALT_SIZE +
810
                 TLS_CIPHER_AES_CCM_128_IV_SIZE);
811
812
        memcpy(crypto_info.iv,
813
               iv.data +
814
                 TLS_CIPHER_AES_CCM_128_SALT_SIZE,
815
               TLS_CIPHER_AES_CCM_128_IV_SIZE);
816
      }
817
818
      memcpy(crypto_info.salt, iv.data,
819
             TLS_CIPHER_AES_CCM_128_SALT_SIZE);
820
      memcpy(crypto_info.rec_seq, seq_number,
821
             TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
822
      memcpy(crypto_info.key, cipher_key.data,
823
             TLS_CIPHER_AES_CCM_128_KEY_SIZE);
824
825
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
826
               sizeof(crypto_info))) {
827
        session->internals.ktls_enabled &=
828
          ~GNUTLS_KTLS_SEND;
829
        return gnutls_assert_val(
830
          GNUTLS_E_INTERNAL_ERROR);
831
      }
832
    } break;
833
    case GNUTLS_CIPHER_CHACHA20_POLY1305: {
834
      struct tls12_crypto_info_chacha20_poly1305 crypto_info;
835
      memset(&crypto_info, 0, sizeof(crypto_info));
836
837
      crypto_info.info.cipher_type =
838
        TLS_CIPHER_CHACHA20_POLY1305;
839
      assert(cipher_key.size ==
840
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
841
842
      /* for TLS 1.2 IV is generated in kernel */
843
      if (version == GNUTLS_TLS1_2) {
844
        crypto_info.info.version = TLS_1_2_VERSION;
845
        memcpy(crypto_info.iv, seq_number,
846
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
847
      } else {
848
        crypto_info.info.version = TLS_1_3_VERSION;
849
        assert(iv.size ==
850
               TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE +
851
                 TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
852
853
        memcpy(crypto_info.iv,
854
               iv.data +
855
                 TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
856
               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
857
      }
858
859
      memcpy(crypto_info.salt, iv.data,
860
             TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE);
861
      memcpy(crypto_info.rec_seq, seq_number,
862
             TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
863
      memcpy(crypto_info.key, cipher_key.data,
864
             TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
865
866
      if (setsockopt(sockout, SOL_TLS, TLS_TX, &crypto_info,
867
               sizeof(crypto_info))) {
868
        session->internals.ktls_enabled &=
869
          ~GNUTLS_KTLS_SEND;
870
        return gnutls_assert_val(
871
          GNUTLS_E_INTERNAL_ERROR);
872
      }
873
    } break;
874
    default:
875
      assert(0);
876
    }
877
878
    // set callback for sending handshake messages
879
    gnutls_handshake_set_read_function(
880
      session, _gnutls_ktls_send_handshake_msg);
881
882
    // set callback for sending alert messages
883
    gnutls_alert_set_read_function(session,
884
                 _gnutls_ktls_send_alert_msg);
885
  }
886
887
  return in;
888
}
889
#endif
890
891
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd, off_t *offset,
892
             size_t count)
893
{
894
  ssize_t ret;
895
  int sockin, sockout;
896
897
  assert(session != NULL);
898
#if defined(__FreeBSD__)
899
  off_t sbytes = 0;
900
  assert(offset != NULL);
901
#endif
902
903
  gnutls_transport_get_int2(session, &sockin, &sockout);
904
#if defined(__FreeBSD__)
905
  ret = sendfile(fd, sockout, *offset, count, NULL, &sbytes, 0);
906
#else
907
  ret = sendfile(sockout, fd, offset, count);
908
#endif
909
  if (ret == -1) {
910
    switch (errno) {
911
    case EINTR:
912
      return GNUTLS_E_INTERRUPTED;
913
    case EAGAIN:
914
      return GNUTLS_E_AGAIN;
915
    default:
916
      return GNUTLS_E_PUSH_ERROR;
917
    }
918
  }
919
#if defined(__FreeBSD__)
920
  *offset += sbytes; /* follow linux sendfile behavior */
921
  return sbytes;
922
#else
923
  return ret;
924
#endif
925
}
926
927
int _gnutls_ktls_send_control_msg(gnutls_session_t session,
928
          unsigned char record_type, const void *data,
929
          size_t data_size)
930
{
931
  const char *buf = data;
932
  ssize_t ret;
933
  int sockin, sockout;
934
  size_t data_to_send = data_size;
935
936
  assert(session != NULL);
937
938
  gnutls_transport_get_int2(session, &sockin, &sockout);
939
940
  while (data_to_send > 0) {
941
    char cmsg[CMSG_SPACE(sizeof(unsigned char))];
942
    struct msghdr msg = { 0 };
943
    struct iovec msg_iov; /* Vector of data to send/receive into. */
944
    struct cmsghdr *hdr;
945
946
    msg.msg_control = cmsg;
947
    msg.msg_controllen = sizeof cmsg;
948
949
    hdr = CMSG_FIRSTHDR(&msg);
950
#if defined(__FreeBSD__)
951
    hdr->cmsg_level = IPPROTO_TCP;
952
#else
953
    hdr->cmsg_level = SOL_TLS;
954
#endif
955
    hdr->cmsg_type = TLS_SET_RECORD_TYPE;
956
    hdr->cmsg_len = CMSG_LEN(sizeof(unsigned char));
957
958
    // construct record header
959
    *CMSG_DATA(hdr) = record_type;
960
    msg.msg_controllen = hdr->cmsg_len;
961
962
    msg_iov.iov_base = (void *)buf;
963
    msg_iov.iov_len = data_to_send;
964
965
    msg.msg_iov = &msg_iov;
966
    msg.msg_iovlen = 1;
967
968
    ret = sendmsg(sockout, &msg, MSG_DONTWAIT);
969
970
    if (ret == -1) {
971
      switch (errno) {
972
      case EINTR:
973
        if (data_to_send < data_size) {
974
          return data_size - data_to_send;
975
        } else {
976
          return GNUTLS_E_INTERRUPTED;
977
        }
978
      case EAGAIN:
979
        if (data_to_send < data_size) {
980
          return data_size - data_to_send;
981
        } else {
982
          return GNUTLS_E_AGAIN;
983
        }
984
      default:
985
        return GNUTLS_E_PUSH_ERROR;
986
      }
987
    }
988
989
    buf += ret;
990
    data_to_send -= ret;
991
  }
992
993
  return data_size;
994
}
995
996
int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
997
            gnutls_record_encryption_level_t level,
998
            gnutls_handshake_description_t htype,
999
            const void *data, size_t data_size)
1000
{
1001
  return _gnutls_ktls_send_control_msg(session, GNUTLS_HANDSHAKE, data,
1002
               data_size);
1003
}
1004
1005
int _gnutls_ktls_send_alert_msg(gnutls_session_t session,
1006
        gnutls_record_encryption_level_t level,
1007
        gnutls_alert_level_t alert_level,
1008
        gnutls_alert_description_t alert_desc)
1009
{
1010
  uint8_t data[2];
1011
  data[0] = (uint8_t)alert_level;
1012
  data[1] = (uint8_t)alert_desc;
1013
  return _gnutls_ktls_send_control_msg(session, GNUTLS_ALERT, data, 2);
1014
}
1015
1016
int _gnutls_ktls_recv_control_msg(gnutls_session_t session,
1017
          unsigned char *record_type, void *data,
1018
          size_t data_size)
1019
{
1020
  char *buf = data;
1021
  ssize_t ret;
1022
  int sockin, sockout;
1023
1024
  char cmsg[CMSG_SPACE(sizeof(unsigned char))];
1025
  struct msghdr msg = { 0 };
1026
  struct iovec msg_iov;
1027
  struct cmsghdr *hdr;
1028
1029
  assert(session != NULL);
1030
1031
  gnutls_transport_get_int2(session, &sockin, &sockout);
1032
1033
  if (session->internals.read_eof != 0) {
1034
    return 0;
1035
  } else if (session->internals.invalid_connection != 0 ||
1036
       session->internals.may_not_read != 0)
1037
    return GNUTLS_E_INVALID_SESSION;
1038
1039
  /* receive message */
1040
  msg.msg_control = cmsg;
1041
  msg.msg_controllen = sizeof cmsg;
1042
1043
  msg_iov.iov_base = buf;
1044
  msg_iov.iov_len = data_size;
1045
1046
  msg.msg_iov = &msg_iov;
1047
  msg.msg_iovlen = 1;
1048
1049
  ret = recvmsg(sockin, &msg, MSG_DONTWAIT);
1050
1051
  if (ret == -1) {
1052
    switch (errno) {
1053
    case EAGAIN:
1054
      return GNUTLS_E_AGAIN;
1055
    case EINVAL:
1056
      return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1057
    case EMSGSIZE:
1058
      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1059
    case EBADMSG:
1060
      return GNUTLS_E_DECRYPTION_FAILED;
1061
    default:
1062
      return GNUTLS_E_PULL_ERROR;
1063
    }
1064
  }
1065
1066
  /* connection closed */
1067
  if (ret == 0)
1068
    return 0;
1069
1070
  /* get record type from header */
1071
  hdr = CMSG_FIRSTHDR(&msg);
1072
  if (hdr == NULL) {
1073
    return GNUTLS_E_PULL_ERROR;
1074
  }
1075
#if defined(__FreeBSD__)
1076
  if (hdr->cmsg_level == IPPROTO_TCP && hdr->cmsg_type == TLS_GET_RECORD)
1077
#else
1078
  if (hdr->cmsg_level == SOL_TLS && hdr->cmsg_type == TLS_GET_RECORD_TYPE)
1079
#endif
1080
    *record_type = *(unsigned char *)CMSG_DATA(hdr);
1081
  else
1082
    *record_type = GNUTLS_APPLICATION_DATA;
1083
1084
  return ret;
1085
}
1086
1087
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type,
1088
        void *data, size_t data_size)
1089
{
1090
  unsigned char record_type;
1091
  int ret;
1092
1093
  ret = _gnutls_ktls_recv_control_msg(session, &record_type, data,
1094
              data_size);
1095
1096
  if (ret > 0) {
1097
    switch (record_type) {
1098
    case GNUTLS_CHANGE_CIPHER_SPEC:
1099
      return gnutls_assert_val(
1100
        GNUTLS_E_UNIMPLEMENTED_FEATURE);
1101
      break;
1102
    case GNUTLS_ALERT:
1103
      session_invalidate(session);
1104
      ret = 0;
1105
      break;
1106
    case GNUTLS_HANDSHAKE:
1107
      ret = gnutls_handshake_write(
1108
        session, GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
1109
        data, ret);
1110
1111
      if (ret < 0)
1112
        return gnutls_assert_val(ret);
1113
1114
      if (type != record_type)
1115
        return GNUTLS_E_AGAIN;
1116
      break;
1117
    case GNUTLS_APPLICATION_DATA:
1118
      if (type != record_type)
1119
        ret = GNUTLS_E_GOT_APPLICATION_DATA;
1120
      break;
1121
    case GNUTLS_HEARTBEAT:
1122
      break;
1123
    default:
1124
      gnutls_assert();
1125
      return GNUTLS_E_UNEXPECTED_PACKET;
1126
    }
1127
  }
1128
  return ret;
1129
}
1130
#else //ENABLE_KTLS
1131
gnutls_transport_ktls_enable_flags_t
1132
gnutls_transport_is_ktls_enabled(gnutls_session_t session)
1133
0
{
1134
0
  return 0;
1135
0
}
1136
1137
void _gnutls_ktls_enable(gnutls_session_t session)
1138
0
{
1139
0
}
1140
1141
int _gnutls_ktls_set_keys(gnutls_session_t sessioni,
1142
        gnutls_transport_ktls_enable_flags_t in)
1143
0
{
1144
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1145
0
}
1146
1147
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd, off_t *offset,
1148
             size_t count)
1149
0
{
1150
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1151
0
}
1152
1153
int _gnutls_ktls_send_control_msg(gnutls_session_t session,
1154
          unsigned char record_type, const void *data,
1155
          size_t data_size)
1156
0
{
1157
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1158
0
}
1159
1160
int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
1161
            gnutls_record_encryption_level_t level,
1162
            gnutls_handshake_description_t htype,
1163
            const void *data, size_t data_size)
1164
0
{
1165
0
  (void)level;
1166
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1167
0
}
1168
1169
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type,
1170
        void *data, size_t data_size)
1171
0
{
1172
0
  return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1173
0
}
1174
1175
#endif //ENABLE_KTLS