Coverage Report

Created: 2023-03-26 07:33

/src/gnutls/lib/constate.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2017 Red Hat, Inc.
4
 *
5
 * Author: Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* Functions that are supposed to run after the handshake procedure is
25
 * finished. These functions activate the established security parameters.
26
 */
27
28
#include "gnutls_int.h"
29
#include <constate.h>
30
#include "errors.h"
31
#include "fips.h"
32
#include <kx.h>
33
#include <algorithms.h>
34
#include <num.h>
35
#include <datum.h>
36
#include <state.h>
37
#include <hello_ext.h>
38
#include <buffers.h>
39
#include "dtls.h"
40
#include "secrets.h"
41
#include "handshake.h"
42
#include "crypto-api.h"
43
#include "locks.h"
44
45
static const char keyexp[] = "key expansion";
46
static const int keyexp_length = sizeof(keyexp) - 1;
47
48
static int
49
_tls13_init_record_state(gnutls_cipher_algorithm_t algo,
50
       record_state_st * state);
51
52
/* This function is to be called after handshake, when master_secret,
53
 *  client_random and server_random have been initialized. 
54
 * This function creates the keys and stores them into pending session.
55
 * (session->cipher_specs)
56
 */
57
static int
58
_gnutls_set_keys(gnutls_session_t session, record_parameters_st * params,
59
     unsigned hash_size, unsigned IV_size, unsigned key_size)
60
0
{
61
0
  uint8_t rnd[2 * GNUTLS_RANDOM_SIZE];
62
0
  int pos, ret;
63
0
  int block_size;
64
0
  char buf[4 * MAX_HASH_SIZE + 4 * MAX_CIPHER_KEY_SIZE +
65
0
     4 * MAX_CIPHER_BLOCK_SIZE];
66
  /* avoid using malloc */
67
0
  uint8_t key_block[2 * MAX_HASH_SIZE + 2 * MAX_CIPHER_KEY_SIZE +
68
0
        2 * MAX_CIPHER_BLOCK_SIZE];
69
0
  record_state_st *client_write, *server_write;
70
71
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
72
0
    client_write = &params->write;
73
0
    server_write = &params->read;
74
0
  } else {
75
0
    client_write = &params->read;
76
0
    server_write = &params->write;
77
0
  }
78
79
0
  block_size = 2 * hash_size + 2 * key_size;
80
0
  block_size += 2 * IV_size;
81
82
0
  memcpy(rnd, session->security_parameters.server_random,
83
0
         GNUTLS_RANDOM_SIZE);
84
0
  memcpy(&rnd[GNUTLS_RANDOM_SIZE],
85
0
         session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
86
87
0
  _gnutls_memory_mark_defined(session->security_parameters.master_secret,
88
0
            GNUTLS_MASTER_SIZE);
89
#ifdef ENABLE_SSL3
90
  if (get_num_version(session) == GNUTLS_SSL3) {  /* SSL 3 */
91
    ret =
92
        _gnutls_ssl3_generate_random
93
        (session->security_parameters.master_secret,
94
         GNUTLS_MASTER_SIZE, rnd, 2 * GNUTLS_RANDOM_SIZE,
95
         block_size, key_block);
96
  } else      /* TLS 1.0+ */
97
#endif
98
0
    ret =
99
0
        _gnutls_PRF(session,
100
0
        session->security_parameters.master_secret,
101
0
        GNUTLS_MASTER_SIZE, keyexp, keyexp_length,
102
0
        rnd, 2 * GNUTLS_RANDOM_SIZE, block_size,
103
0
        key_block);
104
105
0
  if (ret < 0) {
106
0
    _gnutls_memory_mark_undefined(session->
107
0
                security_parameters.master_secret,
108
0
                GNUTLS_MASTER_SIZE);
109
0
    return gnutls_assert_val(ret);
110
0
  }
111
112
0
  _gnutls_hard_log("INT: KEY BLOCK[%d]: %s\n", block_size,
113
0
       _gnutls_bin2hex(key_block, block_size, buf,
114
0
           sizeof(buf), NULL));
115
116
0
  pos = 0;
117
0
  if (hash_size > 0) {
118
0
    assert(hash_size <= sizeof(client_write->mac_key));
119
0
    client_write->mac_key_size = hash_size;
120
0
    memcpy(client_write->mac_key, &key_block[pos], hash_size);
121
122
0
    pos += hash_size;
123
124
0
    server_write->mac_key_size = hash_size;
125
0
    memcpy(server_write->mac_key, &key_block[pos], hash_size);
126
127
0
    pos += hash_size;
128
129
0
    _gnutls_hard_log("INT: CLIENT MAC KEY [%d]: %s\n",
130
0
         client_write->mac_key_size,
131
0
         _gnutls_bin2hex(client_write->mac_key,
132
0
             hash_size,
133
0
             buf, sizeof(buf), NULL));
134
135
0
    _gnutls_hard_log("INT: SERVER MAC KEY [%d]: %s\n",
136
0
         server_write->mac_key_size,
137
0
         _gnutls_bin2hex(server_write->mac_key,
138
0
             hash_size,
139
0
             buf, sizeof(buf), NULL));
140
0
  }
141
142
0
  if (key_size > 0) {
143
0
    assert(key_size <= sizeof(client_write->key));
144
0
    client_write->key_size = key_size;
145
0
    memcpy(client_write->key, &key_block[pos], key_size);
146
147
0
    pos += key_size;
148
149
0
    server_write->key_size = key_size;
150
0
    memcpy(server_write->key, &key_block[pos], key_size);
151
152
0
    pos += key_size;
153
154
0
    _gnutls_hard_log("INT: CLIENT WRITE KEY [%d]: %s\n",
155
0
         key_size,
156
0
         _gnutls_bin2hex(client_write->key,
157
0
             key_size,
158
0
             buf, sizeof(buf), NULL));
159
160
0
    _gnutls_hard_log("INT: SERVER WRITE KEY [%d]: %s\n",
161
0
         key_size,
162
0
         _gnutls_bin2hex(server_write->key,
163
0
             key_size,
164
0
             buf, sizeof(buf), NULL));
165
166
0
  }
167
168
  /* IV generation in export and non export ciphers.
169
   */
170
0
  if (IV_size > 0) {
171
0
    assert(IV_size <= sizeof(client_write->iv));
172
173
0
    client_write->iv_size = IV_size;
174
0
    memcpy(client_write->iv, &key_block[pos], IV_size);
175
176
0
    pos += IV_size;
177
178
0
    server_write->iv_size = IV_size;
179
0
    memcpy(server_write->iv, &key_block[pos], IV_size);
180
181
0
    _gnutls_hard_log("INT: CLIENT WRITE IV [%d]: %s\n",
182
0
         client_write->iv_size,
183
0
         _gnutls_bin2hex(client_write->iv,
184
0
             client_write->iv_size,
185
0
             buf, sizeof(buf), NULL));
186
187
0
    _gnutls_hard_log("INT: SERVER WRITE IV [%d]: %s\n",
188
0
         server_write->iv_size,
189
0
         _gnutls_bin2hex(server_write->iv,
190
0
             server_write->iv_size,
191
0
             buf, sizeof(buf), NULL));
192
0
  }
193
194
0
  return 0;
195
0
}
196
197
static int
198
_tls13_update_keys(gnutls_session_t session, hs_stage_t stage,
199
       record_parameters_st * params,
200
       unsigned iv_size, unsigned key_size)
201
0
{
202
0
  uint8_t key_block[MAX_CIPHER_KEY_SIZE];
203
0
  uint8_t iv_block[MAX_CIPHER_IV_SIZE];
204
0
  char buf[65];
205
0
  record_state_st *upd_state;
206
0
  record_parameters_st *prev = NULL;
207
0
  int ret;
208
209
  /* generate new keys for direction needed and copy old from previous epoch */
210
211
0
  if (stage == STAGE_UPD_OURS) {
212
0
    upd_state = &params->write;
213
214
0
    ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &prev);
215
0
    if (ret < 0)
216
0
      return gnutls_assert_val(ret);
217
0
    assert(prev != NULL);
218
219
0
    params->read.sequence_number = prev->read.sequence_number;
220
221
0
    params->read.key_size = prev->read.key_size;
222
0
    memcpy(params->read.key, prev->read.key, prev->read.key_size);
223
224
0
    _gnutls_hard_log("INT: READ KEY [%d]: %s\n",
225
0
         params->read.key_size,
226
0
         _gnutls_bin2hex(params->read.key,
227
0
             params->read.key_size, buf,
228
0
             sizeof(buf), NULL));
229
230
0
    params->read.iv_size = prev->read.iv_size;
231
0
    memcpy(params->read.iv, prev->read.iv, prev->read.key_size);
232
233
0
    _gnutls_hard_log("INT: READ IV [%d]: %s\n",
234
0
         params->read.iv_size,
235
0
         _gnutls_bin2hex(params->read.iv,
236
0
             params->read.iv_size, buf,
237
0
             sizeof(buf), NULL));
238
0
  } else {
239
0
    upd_state = &params->read;
240
241
0
    ret = _gnutls_epoch_get(session, EPOCH_WRITE_CURRENT, &prev);
242
0
    if (ret < 0)
243
0
      return gnutls_assert_val(ret);
244
0
    assert(prev != NULL);
245
246
0
    params->write.sequence_number = prev->write.sequence_number;
247
248
0
    params->write.key_size = prev->write.key_size;
249
0
    memcpy(params->write.key, prev->write.key,
250
0
           prev->write.key_size);
251
252
0
    _gnutls_hard_log("INT: WRITE KEY [%d]: %s\n",
253
0
         params->write.key_size,
254
0
         _gnutls_bin2hex(params->write.key,
255
0
             params->write.key_size, buf,
256
0
             sizeof(buf), NULL));
257
258
0
    params->write.iv_size = prev->write.iv_size;
259
0
    memcpy(params->write.iv, prev->write.iv, prev->write.iv_size);
260
261
0
    _gnutls_hard_log("INT: WRITE IV [%d]: %s\n",
262
0
         params->write.iv_size,
263
0
         _gnutls_bin2hex(params->write.iv,
264
0
             params->write.iv_size, buf,
265
0
             sizeof(buf), NULL));
266
0
  }
267
268
0
  if ((session->security_parameters.entity == GNUTLS_CLIENT
269
0
       && stage == STAGE_UPD_OURS)
270
0
      || (session->security_parameters.entity == GNUTLS_SERVER
271
0
    && stage == STAGE_UPD_PEERS)) {
272
273
    /* client keys */
274
0
    ret = _tls13_expand_secret(session, APPLICATION_TRAFFIC_UPDATE,
275
0
             sizeof(APPLICATION_TRAFFIC_UPDATE) -
276
0
             1, NULL, 0,
277
0
             session->key.proto.tls13.ap_ckey,
278
0
             session->security_parameters.
279
0
             prf->output_size,
280
0
             session->key.proto.tls13.ap_ckey);
281
0
    if (ret < 0)
282
0
      return gnutls_assert_val(ret);
283
284
0
    ret =
285
0
        _tls13_expand_secret(session, "key", 3, NULL, 0,
286
0
           session->key.proto.tls13.ap_ckey,
287
0
           key_size, key_block);
288
0
    if (ret < 0)
289
0
      return gnutls_assert_val(ret);
290
291
0
    ret =
292
0
        _tls13_expand_secret(session, "iv", 2, NULL, 0,
293
0
           session->key.proto.tls13.ap_ckey,
294
0
           iv_size, iv_block);
295
0
    if (ret < 0)
296
0
      return gnutls_assert_val(ret);
297
0
  } else {
298
0
    ret = _tls13_expand_secret(session, APPLICATION_TRAFFIC_UPDATE,
299
0
             sizeof(APPLICATION_TRAFFIC_UPDATE) -
300
0
             1, NULL, 0,
301
0
             session->key.proto.tls13.ap_skey,
302
0
             session->security_parameters.
303
0
             prf->output_size,
304
0
             session->key.proto.tls13.ap_skey);
305
0
    if (ret < 0)
306
0
      return gnutls_assert_val(ret);
307
308
0
    ret =
309
0
        _tls13_expand_secret(session, "key", 3, NULL, 0,
310
0
           session->key.proto.tls13.ap_skey,
311
0
           key_size, key_block);
312
0
    if (ret < 0)
313
0
      return gnutls_assert_val(ret);
314
315
0
    ret =
316
0
        _tls13_expand_secret(session, "iv", 2, NULL, 0,
317
0
           session->key.proto.tls13.ap_skey,
318
0
           iv_size, iv_block);
319
0
    if (ret < 0)
320
0
      return gnutls_assert_val(ret);
321
0
  }
322
323
0
  upd_state->mac_key_size = 0;
324
325
0
  assert(key_size <= sizeof(upd_state->key));
326
0
  memcpy(upd_state->key, key_block, key_size);
327
0
  upd_state->key_size = key_size;
328
329
0
  _gnutls_hard_log("INT: NEW %s KEY [%d]: %s\n",
330
0
       (upd_state == &params->read) ? "READ" : "WRITE",
331
0
       key_size,
332
0
       _gnutls_bin2hex(key_block, key_size,
333
0
           buf, sizeof(buf), NULL));
334
335
0
  if (iv_size > 0) {
336
0
    assert(iv_size <= sizeof(upd_state->iv));
337
0
    memcpy(upd_state->iv, iv_block, iv_size);
338
0
    upd_state->iv_size = iv_size;
339
340
0
    _gnutls_hard_log("INT: NEW %s IV [%d]: %s\n",
341
0
         (upd_state ==
342
0
          &params->read) ? "READ" : "WRITE", iv_size,
343
0
         _gnutls_bin2hex(iv_block, iv_size, buf,
344
0
             sizeof(buf), NULL));
345
0
  }
346
347
0
  return 0;
348
0
}
349
350
static int
351
_tls13_set_early_keys(gnutls_session_t session,
352
          record_parameters_st * params,
353
          unsigned iv_size, unsigned key_size)
354
0
{
355
0
  uint8_t key_block[MAX_CIPHER_KEY_SIZE];
356
0
  uint8_t iv_block[MAX_CIPHER_IV_SIZE];
357
0
  char buf[65];
358
0
  record_state_st *early_state;
359
0
  int ret;
360
361
0
  if (session->security_parameters.entity == GNUTLS_CLIENT &&
362
0
      !(session->internals.hsk_flags & HSK_TLS13_TICKET_SENT)) {
363
0
    return GNUTLS_E_INVALID_REQUEST;
364
0
  }
365
366
0
  ret =
367
0
      _tls13_expand_secret2(session->internals.
368
0
          resumed_security_parameters.prf, "key", 3,
369
0
          NULL, 0, session->key.proto.tls13.e_ckey,
370
0
          key_size, key_block);
371
0
  if (ret < 0)
372
0
    return gnutls_assert_val(ret);
373
374
0
  ret =
375
0
      _tls13_expand_secret2(session->internals.
376
0
          resumed_security_parameters.prf, "iv", 2,
377
0
          NULL, 0, session->key.proto.tls13.e_ckey,
378
0
          iv_size, iv_block);
379
0
  if (ret < 0)
380
0
    return gnutls_assert_val(ret);
381
382
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
383
0
    early_state = &params->write;
384
0
  } else {
385
0
    early_state = &params->read;
386
0
  }
387
388
0
  early_state->mac_key_size = 0;
389
390
0
  assert(key_size <= sizeof(early_state->key));
391
0
  memcpy(early_state->key, key_block, key_size);
392
0
  early_state->key_size = key_size;
393
394
0
  _gnutls_hard_log("INT: EARLY KEY [%d]: %s\n",
395
0
       key_size,
396
0
       _gnutls_bin2hex(key_block, key_size,
397
0
           buf, sizeof(buf), NULL));
398
399
0
  if (iv_size > 0) {
400
0
    assert(iv_size <= sizeof(early_state->iv));
401
0
    memcpy(early_state->iv, iv_block, iv_size);
402
0
    early_state->iv_size = iv_size;
403
404
0
    _gnutls_hard_log("INT: EARLY IV [%d]: %s\n",
405
0
         iv_size,
406
0
         _gnutls_bin2hex(iv_block, iv_size,
407
0
             buf, sizeof(buf), NULL));
408
0
  }
409
410
0
  return 0;
411
0
}
412
413
static int
414
_tls13_set_keys(gnutls_session_t session, hs_stage_t stage,
415
    record_parameters_st * params,
416
    unsigned iv_size, unsigned key_size)
417
0
{
418
0
  uint8_t ckey_block[MAX_CIPHER_KEY_SIZE];
419
0
  uint8_t civ_block[MAX_CIPHER_IV_SIZE];
420
0
  uint8_t skey_block[MAX_CIPHER_KEY_SIZE];
421
0
  uint8_t siv_block[MAX_CIPHER_IV_SIZE];
422
0
  char buf[65];
423
0
  record_state_st *client_write, *server_write;
424
0
  const char *label;
425
0
  unsigned label_size, hsk_len;
426
0
  const char *keylog_label;
427
0
  void *ckey, *skey;
428
0
  int ret;
429
430
0
  if (stage == STAGE_UPD_OURS || stage == STAGE_UPD_PEERS)
431
0
    return _tls13_update_keys(session, stage,
432
0
            params, iv_size, key_size);
433
434
0
  else if (stage == STAGE_EARLY)
435
0
    return _tls13_set_early_keys(session,
436
0
               params, iv_size, key_size);
437
438
0
  else if (stage == STAGE_HS) {
439
0
    label = HANDSHAKE_CLIENT_TRAFFIC_LABEL;
440
0
    label_size = sizeof(HANDSHAKE_CLIENT_TRAFFIC_LABEL) - 1;
441
0
    hsk_len = session->internals.handshake_hash_buffer.length;
442
0
    keylog_label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
443
0
    ckey = session->key.proto.tls13.hs_ckey;
444
0
  } else {
445
0
    label = APPLICATION_CLIENT_TRAFFIC_LABEL;
446
0
    label_size = sizeof(APPLICATION_CLIENT_TRAFFIC_LABEL) - 1;
447
0
    hsk_len =
448
0
        session->
449
0
        internals.handshake_hash_buffer_server_finished_len;
450
0
    keylog_label = "CLIENT_TRAFFIC_SECRET_0";
451
0
    ckey = session->key.proto.tls13.ap_ckey;
452
0
  }
453
454
0
  ret = _tls13_derive_secret(session, label, label_size,
455
0
           session->internals.
456
0
           handshake_hash_buffer.data, hsk_len,
457
0
           session->key.proto.tls13.temp_secret, ckey);
458
0
  if (ret < 0)
459
0
    return gnutls_assert_val(ret);
460
461
0
  ret = _gnutls_call_keylog_func(session, keylog_label,
462
0
               ckey,
463
0
               session->security_parameters.
464
0
               prf->output_size);
465
0
  if (ret < 0)
466
0
    return gnutls_assert_val(ret);
467
468
  /* client keys */
469
0
  ret =
470
0
      _tls13_expand_secret(session, "key", 3, NULL, 0, ckey, key_size,
471
0
         ckey_block);
472
0
  if (ret < 0)
473
0
    return gnutls_assert_val(ret);
474
475
0
  ret =
476
0
      _tls13_expand_secret(session, "iv", 2, NULL, 0, ckey, iv_size,
477
0
         civ_block);
478
0
  if (ret < 0)
479
0
    return gnutls_assert_val(ret);
480
481
  /* server keys */
482
0
  if (stage == STAGE_HS) {
483
0
    label = HANDSHAKE_SERVER_TRAFFIC_LABEL;
484
0
    label_size = sizeof(HANDSHAKE_SERVER_TRAFFIC_LABEL) - 1;
485
0
    keylog_label = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
486
0
    skey = session->key.proto.tls13.hs_skey;
487
0
  } else {
488
0
    label = APPLICATION_SERVER_TRAFFIC_LABEL;
489
0
    label_size = sizeof(APPLICATION_SERVER_TRAFFIC_LABEL) - 1;
490
0
    keylog_label = "SERVER_TRAFFIC_SECRET_0";
491
0
    skey = session->key.proto.tls13.ap_skey;
492
0
  }
493
494
0
  ret = _tls13_derive_secret(session, label, label_size,
495
0
           session->internals.
496
0
           handshake_hash_buffer.data, hsk_len,
497
0
           session->key.proto.tls13.temp_secret, skey);
498
499
0
  if (ret < 0)
500
0
    return gnutls_assert_val(ret);
501
502
0
  ret = _gnutls_call_keylog_func(session, keylog_label,
503
0
               skey,
504
0
               session->security_parameters.
505
0
               prf->output_size);
506
0
  if (ret < 0)
507
0
    return gnutls_assert_val(ret);
508
509
0
  ret =
510
0
      _tls13_expand_secret(session, "key", 3, NULL, 0, skey, key_size,
511
0
         skey_block);
512
0
  if (ret < 0)
513
0
    return gnutls_assert_val(ret);
514
515
0
  ret =
516
0
      _tls13_expand_secret(session, "iv", 2, NULL, 0, skey, iv_size,
517
0
         siv_block);
518
0
  if (ret < 0)
519
0
    return gnutls_assert_val(ret);
520
521
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
522
0
    client_write = &params->write;
523
0
    server_write = &params->read;
524
0
  } else {
525
0
    client_write = &params->read;
526
0
    server_write = &params->write;
527
0
  }
528
529
0
  client_write->mac_key_size = 0;
530
0
  server_write->mac_key_size = 0;
531
532
0
  assert(key_size <= sizeof(client_write->key));
533
0
  memcpy(client_write->key, ckey_block, key_size);
534
0
  client_write->key_size = key_size;
535
536
0
  _gnutls_hard_log("INT: CLIENT WRITE KEY [%d]: %s\n",
537
0
       key_size,
538
0
       _gnutls_bin2hex(ckey_block, key_size,
539
0
           buf, sizeof(buf), NULL));
540
541
0
  memcpy(server_write->key, skey_block, key_size);
542
0
  server_write->key_size = key_size;
543
544
0
  _gnutls_hard_log("INT: SERVER WRITE KEY [%d]: %s\n",
545
0
       key_size,
546
0
       _gnutls_bin2hex(skey_block, key_size,
547
0
           buf, sizeof(buf), NULL));
548
549
0
  if (iv_size > 0) {
550
0
    assert(iv_size <= sizeof(client_write->iv));
551
0
    memcpy(client_write->iv, civ_block, iv_size);
552
0
    client_write->iv_size = iv_size;
553
554
0
    _gnutls_hard_log("INT: CLIENT WRITE IV [%d]: %s\n",
555
0
         iv_size,
556
0
         _gnutls_bin2hex(civ_block, iv_size,
557
0
             buf, sizeof(buf), NULL));
558
559
0
    memcpy(server_write->iv, siv_block, iv_size);
560
0
    server_write->iv_size = iv_size;
561
562
0
    _gnutls_hard_log("INT: SERVER WRITE IV [%d]: %s\n",
563
0
         iv_size,
564
0
         _gnutls_bin2hex(siv_block, iv_size,
565
0
             buf, sizeof(buf), NULL));
566
0
  }
567
568
0
  client_write->level = server_write->level = stage == STAGE_HS ?
569
0
      GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE :
570
0
      GNUTLS_ENCRYPTION_LEVEL_APPLICATION;
571
572
0
  return 0;
573
0
}
574
575
static int
576
_gnutls_init_record_state(record_parameters_st * params,
577
        const version_entry_st * ver, int read,
578
        record_state_st * state)
579
0
{
580
0
  int ret;
581
0
  gnutls_datum_t *iv = NULL, _iv;
582
0
  gnutls_datum_t key;
583
0
  gnutls_datum_t mac;
584
585
0
  _iv.data = state->iv;
586
0
  _iv.size = state->iv_size;
587
588
0
  key.data = state->key;
589
0
  key.size = state->key_size;
590
591
0
  mac.data = state->mac_key;
592
0
  mac.size = state->mac_key_size;
593
594
0
  if (_gnutls_cipher_type(params->cipher) == CIPHER_BLOCK) {
595
0
    if (!_gnutls_version_has_explicit_iv(ver))
596
0
      iv = &_iv;
597
0
  } else if (_gnutls_cipher_type(params->cipher) == CIPHER_STREAM) {
598
    /* To handle GOST ciphersuites */
599
0
    if (_gnutls_cipher_get_implicit_iv_size(params->cipher))
600
0
      iv = &_iv;
601
0
  }
602
603
0
  ret = _gnutls_auth_cipher_init(&state->ctx.tls12,
604
0
               params->cipher, &key, iv,
605
0
               params->mac, &mac, params->etm,
606
#ifdef ENABLE_SSL3
607
               (ver->id == GNUTLS_SSL3) ? 1 : 0,
608
#endif
609
0
               1 - read /*1==encrypt */ );
610
0
  if (ret < 0 && params->cipher->id != GNUTLS_CIPHER_NULL) {
611
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
612
0
    return gnutls_assert_val(ret);
613
0
  }
614
615
0
  if (is_cipher_algo_allowed(params->cipher->id))
616
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
617
0
  else
618
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
619
620
0
  return 0;
621
0
}
622
623
int
624
_gnutls_set_cipher_suite2(gnutls_session_t session,
625
        const gnutls_cipher_suite_entry_st * cs)
626
0
{
627
0
  const cipher_entry_st *cipher_algo;
628
0
  const mac_entry_st *mac_algo;
629
0
  record_parameters_st *params;
630
0
  int ret;
631
0
  const version_entry_st *ver = get_version(session);
632
633
0
  ret = _gnutls_epoch_get(session, EPOCH_NEXT, &params);
634
0
  if (ret < 0)
635
0
    return gnutls_assert_val(ret);
636
637
0
  cipher_algo = cipher_to_entry(cs->block_algorithm);
638
0
  mac_algo = mac_to_entry(cs->mac_algorithm);
639
640
0
  if (ver->tls13_sem && (session->internals.hsk_flags & HSK_HRR_SENT)) {
641
0
    if (params->initialized && (params->cipher != cipher_algo ||
642
0
              params->mac != mac_algo
643
0
              || cs !=
644
0
              session->security_parameters.cs))
645
0
      return
646
0
          gnutls_assert_val
647
0
          (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
648
649
0
    return 0;
650
0
  }
651
652
  /* The params shouldn't have been initialized at this point, unless we
653
   * are doing trial encryption/decryption of early data.
654
   */
655
0
  if (unlikely
656
0
      (!((session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT &&
657
0
    !IS_SERVER(session)) ||
658
0
         (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED &&
659
0
    IS_SERVER(session))) &&
660
0
       (params->initialized
661
0
        || params->cipher != NULL || params->mac != NULL))) {
662
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
663
0
  }
664
665
0
  if (_gnutls_cipher_is_ok(cipher_algo) == 0
666
0
      || _gnutls_mac_is_ok(mac_algo) == 0)
667
0
    return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
668
669
0
  if (_gnutls_version_has_selectable_prf(get_version(session))) {
670
0
    if (cs->prf == GNUTLS_MAC_UNKNOWN ||
671
0
        _gnutls_mac_is_ok(mac_to_entry(cs->prf)) == 0)
672
0
      return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
673
0
    session->security_parameters.prf = mac_to_entry(cs->prf);
674
0
  } else {
675
0
    session->security_parameters.prf =
676
0
        mac_to_entry(GNUTLS_MAC_MD5_SHA1);
677
0
  }
678
679
0
  session->security_parameters.cs = cs;
680
0
  params->cipher = cipher_algo;
681
0
  params->mac = mac_algo;
682
683
0
  return 0;
684
0
}
685
686
/* Sets the next epoch to be a clone of the current one.
687
 * The keys are not cloned, only the cipher and MAC.
688
 */
689
int _gnutls_epoch_dup(gnutls_session_t session, unsigned int epoch_rel)
690
0
{
691
0
  record_parameters_st *prev;
692
0
  record_parameters_st *next;
693
0
  int ret;
694
695
0
  ret = _gnutls_epoch_get(session, epoch_rel, &prev);
696
0
  if (ret < 0)
697
0
    return gnutls_assert_val(ret);
698
699
0
  ret = _gnutls_epoch_get(session, EPOCH_NEXT, &next);
700
0
  if (ret < 0) {
701
0
    ret = _gnutls_epoch_setup_next(session, 0, &next);
702
0
    if (ret < 0)
703
0
      return gnutls_assert_val(ret);
704
0
  }
705
706
0
  if (next->initialized || next->cipher != NULL || next->mac != NULL)
707
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
708
709
0
  next->cipher = prev->cipher;
710
0
  next->mac = prev->mac;
711
712
0
  return 0;
713
0
}
714
715
int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch,
716
         hs_stage_t stage)
717
0
{
718
0
  int hash_size;
719
0
  int IV_size;
720
0
  int key_size;
721
0
  record_parameters_st *params;
722
0
  int ret;
723
0
  const version_entry_st *ver =
724
0
      stage == STAGE_EARLY && !IS_SERVER(session) ?
725
0
      session->internals.resumed_security_parameters.pversion :
726
0
      get_version(session);
727
728
0
  if (unlikely(ver == NULL))
729
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
730
731
0
  ret = _gnutls_epoch_get(session, epoch, &params);
732
0
  if (ret < 0)
733
0
    return gnutls_assert_val(ret);
734
735
0
  if (params->initialized)
736
0
    return 0;
737
738
0
  _gnutls_record_log
739
0
      ("REC[%p]: Initializing epoch #%u\n", session, params->epoch);
740
741
0
  if (_gnutls_cipher_is_ok(params->cipher) == 0 ||
742
0
      _gnutls_mac_is_ok(params->mac) == 0)
743
0
    return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
744
745
0
  if (_gnutls_version_has_explicit_iv(ver) &&
746
0
      (_gnutls_cipher_type(params->cipher) != CIPHER_BLOCK)) {
747
0
    IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
748
0
  } else {
749
0
    IV_size = _gnutls_cipher_get_iv_size(params->cipher);
750
0
  }
751
752
0
  key_size = _gnutls_cipher_get_key_size(params->cipher);
753
0
  hash_size = _gnutls_mac_get_key_size(params->mac);
754
0
  params->etm = session->security_parameters.etm;
755
756
0
  if (ver->tls13_sem) {
757
0
    ret = _tls13_set_keys
758
0
        (session, stage, params, IV_size, key_size);
759
0
    if (ret < 0)
760
0
      return gnutls_assert_val(ret);
761
762
0
    if (stage != STAGE_EARLY ||
763
0
        session->security_parameters.entity == GNUTLS_SERVER) {
764
0
      ret =
765
0
          _tls13_init_record_state(params->cipher->id,
766
0
                 &params->read);
767
0
      if (ret < 0)
768
0
        return gnutls_assert_val(ret);
769
0
    }
770
771
0
    if (stage != STAGE_EARLY ||
772
0
        session->security_parameters.entity == GNUTLS_CLIENT) {
773
0
      ret =
774
0
          _tls13_init_record_state(params->cipher->id,
775
0
                 &params->write);
776
0
      if (ret < 0)
777
0
        return gnutls_assert_val(ret);
778
0
    }
779
0
  } else {
780
0
    ret = _gnutls_set_keys
781
0
        (session, params, hash_size, IV_size, key_size);
782
0
    if (ret < 0)
783
0
      return gnutls_assert_val(ret);
784
785
0
    ret = _gnutls_init_record_state(params, ver, 1, &params->read);
786
0
    if (ret < 0)
787
0
      return gnutls_assert_val(ret);
788
789
0
    ret = _gnutls_init_record_state(params, ver, 0, &params->write);
790
0
    if (ret < 0)
791
0
      return gnutls_assert_val(ret);
792
0
  }
793
794
  /* The TLS1.3 limit of 256 additional bytes is also enforced under CBC
795
   * ciphers to ensure we interoperate with gnutls 2.12.x which could add padding
796
   * data exceeding the maximum. */
797
0
  if (ver->tls13_sem
798
0
      || _gnutls_cipher_type(params->cipher) == CIPHER_BLOCK) {
799
0
    session->internals.max_recv_size = 256;
800
0
  } else {
801
0
    session->internals.max_recv_size = 0;
802
0
  }
803
804
0
  if (!ver->tls13_sem) {
805
0
    session->internals.max_recv_size +=
806
0
        _gnutls_record_overhead(ver, params->cipher, params->mac,
807
0
              1);
808
0
    if (session->internals.allow_large_records != 0)
809
0
      session->internals.max_recv_size += EXTRA_COMP_SIZE;
810
0
  }
811
812
0
  session->internals.max_recv_size +=
813
0
      session->security_parameters.max_record_recv_size +
814
0
      RECORD_HEADER_SIZE(session);
815
816
0
  _dtls_reset_window(params);
817
818
0
  _gnutls_record_log("REC[%p]: Epoch #%u ready\n", session,
819
0
         params->epoch);
820
821
0
  params->initialized = 1;
822
0
  return 0;
823
0
}
824
825
void _gnutls_set_resumed_parameters(gnutls_session_t session)
826
0
{
827
0
  security_parameters_st *src =
828
0
      &session->internals.resumed_security_parameters;
829
0
  security_parameters_st *dst = &session->security_parameters;
830
0
  const version_entry_st *ver = get_version(session);
831
832
  /* Under TLS 1.3, these values are items which are not
833
   * negotiated on the subsequent session. */
834
0
  if (!ver->tls13_sem) {
835
0
    dst->cs = src->cs;
836
0
    _gnutls_memory_mark_defined(dst->master_secret,
837
0
              GNUTLS_MASTER_SIZE);
838
0
    memcpy(dst->master_secret, src->master_secret,
839
0
           GNUTLS_MASTER_SIZE);
840
0
    _gnutls_memory_mark_defined(dst->client_random,
841
0
              GNUTLS_RANDOM_SIZE);
842
0
    memcpy(dst->client_random, src->client_random,
843
0
           GNUTLS_RANDOM_SIZE);
844
0
    _gnutls_memory_mark_defined(dst->server_random,
845
0
              GNUTLS_RANDOM_SIZE);
846
0
    memcpy(dst->server_random, src->server_random,
847
0
           GNUTLS_RANDOM_SIZE);
848
0
    dst->ext_master_secret = src->ext_master_secret;
849
0
    dst->etm = src->etm;
850
0
    dst->prf = src->prf;
851
0
    dst->grp = src->grp;
852
0
    dst->pversion = src->pversion;
853
0
  }
854
0
  memcpy(dst->session_id, src->session_id, GNUTLS_MAX_SESSION_ID_SIZE);
855
0
  dst->session_id_size = src->session_id_size;
856
0
  dst->timestamp = src->timestamp;
857
0
  dst->client_ctype = src->client_ctype;
858
0
  dst->server_ctype = src->server_ctype;
859
0
  dst->client_auth_type = src->client_auth_type;
860
0
  dst->server_auth_type = src->server_auth_type;
861
862
0
  if (!ver->tls13_sem &&
863
0
      !(session->
864
0
        internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED)) {
865
0
    dst->max_record_recv_size = src->max_record_recv_size;
866
0
    dst->max_record_send_size = src->max_record_send_size;
867
0
  }
868
0
}
869
870
/* Sets the current connection session to conform with the
871
 * Security parameters(pending session), and initializes encryption.
872
 * Actually it initializes and starts encryption ( so it needs
873
 * secrets and random numbers to have been negotiated)
874
 * This is to be called after sending the Change Cipher Spec packet.
875
 */
876
int _gnutls_connection_state_init(gnutls_session_t session)
877
0
{
878
0
  int ret;
879
880
/* Setup the master secret 
881
 */
882
0
  if ((ret = _gnutls_generate_master(session, 0)) < 0)
883
0
    return gnutls_assert_val(ret);
884
885
0
  return 0;
886
0
}
887
888
/* Initializes the read connection session
889
 * (read encrypted data)
890
 */
891
int _gnutls_read_connection_state_init(gnutls_session_t session)
892
0
{
893
0
  const uint16_t epoch_next = session->security_parameters.epoch_next;
894
0
  int ret;
895
896
  /* Update internals from CipherSuite selected.
897
   * If we are resuming just copy the connection session
898
   */
899
0
  if (session->internals.resumed &&
900
0
      session->security_parameters.entity == GNUTLS_CLIENT)
901
0
    _gnutls_set_resumed_parameters(session);
902
903
0
  ret = _gnutls_epoch_set_keys(session, epoch_next, 0);
904
0
  if (ret < 0)
905
0
    return ret;
906
907
0
  _gnutls_handshake_log("HSK[%p]: Cipher Suite: %s\n",
908
0
            session, session->security_parameters.cs->name);
909
910
0
  session->security_parameters.epoch_read = epoch_next;
911
912
0
  return 0;
913
0
}
914
915
/* Initializes the write connection session
916
 * (write encrypted data)
917
 */
918
int _gnutls_write_connection_state_init(gnutls_session_t session)
919
0
{
920
0
  const uint16_t epoch_next = session->security_parameters.epoch_next;
921
0
  int ret;
922
923
  /* reset max_record_send_size if it was negotiated in the
924
   * previous handshake using the record_size_limit extension */
925
0
  if (!(session->internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED)
926
0
      && session->security_parameters.entity == GNUTLS_SERVER)
927
0
    session->security_parameters.max_record_send_size =
928
0
        session->security_parameters.max_user_record_send_size;
929
930
/* Update internals from CipherSuite selected.
931
 * If we are resuming just copy the connection session
932
 */
933
0
  if (session->internals.resumed &&
934
0
      session->security_parameters.entity == GNUTLS_SERVER)
935
0
    _gnutls_set_resumed_parameters(session);
936
937
0
  ret = _gnutls_epoch_set_keys(session, epoch_next, 0);
938
0
  if (ret < 0)
939
0
    return gnutls_assert_val(ret);
940
941
0
  _gnutls_handshake_log("HSK[%p]: Cipher Suite: %s\n", session,
942
0
            session->security_parameters.cs->name);
943
944
0
  _gnutls_handshake_log
945
0
      ("HSK[%p]: Initializing internal [write] cipher sessions\n",
946
0
       session);
947
948
0
  session->security_parameters.epoch_write = epoch_next;
949
950
0
  return 0;
951
0
}
952
953
static inline int
954
epoch_resolve(gnutls_session_t session,
955
        unsigned int epoch_rel, uint16_t * epoch_out)
956
0
{
957
0
  switch (epoch_rel) {
958
0
  case EPOCH_READ_CURRENT:
959
0
    *epoch_out = session->security_parameters.epoch_read;
960
0
    return 0;
961
962
0
  case EPOCH_WRITE_CURRENT:
963
0
    *epoch_out = session->security_parameters.epoch_write;
964
0
    return 0;
965
966
0
  case EPOCH_NEXT:
967
0
    *epoch_out = session->security_parameters.epoch_next;
968
0
    return 0;
969
970
0
  default:
971
0
    if (epoch_rel > 0xffffu)
972
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
973
974
0
    *epoch_out = epoch_rel;
975
0
    return 0;
976
0
  }
977
0
}
978
979
static inline record_parameters_st **epoch_get_slot(gnutls_session_t
980
                session, uint16_t epoch)
981
0
{
982
0
  uint16_t epoch_index = epoch - session->security_parameters.epoch_min;
983
984
0
  if (epoch_index >= MAX_EPOCH_INDEX) {
985
0
    _gnutls_handshake_log
986
0
        ("Epoch %d out of range (idx: %d, max: %d)\n",
987
0
         (int)epoch, (int)epoch_index, MAX_EPOCH_INDEX);
988
0
    gnutls_assert();
989
0
    return NULL;
990
0
  }
991
  /* The slot may still be empty (NULL) */
992
0
  return &session->record_parameters[epoch_index];
993
0
}
994
995
int
996
_gnutls_epoch_get(gnutls_session_t session, unsigned int epoch_rel,
997
      record_parameters_st ** params_out)
998
0
{
999
0
  uint16_t epoch;
1000
0
  record_parameters_st **params;
1001
0
  int ret;
1002
1003
0
  gnutls_mutex_lock(&session->internals.epoch_lock);
1004
1005
0
  ret = epoch_resolve(session, epoch_rel, &epoch);
1006
0
  if (ret < 0) {
1007
0
    gnutls_assert();
1008
0
    goto cleanup;
1009
0
  }
1010
1011
0
  params = epoch_get_slot(session, epoch);
1012
0
  if (params == NULL || *params == NULL) {
1013
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1014
0
    goto cleanup;
1015
0
  }
1016
1017
0
  if (params_out)
1018
0
    *params_out = *params;
1019
1020
0
  ret = 0;
1021
1022
0
 cleanup:
1023
0
  gnutls_mutex_unlock(&session->internals.epoch_lock);
1024
0
  return ret;
1025
0
}
1026
1027
/* Ensures that the next epoch is setup. When an epoch will null ciphers
1028
 * is to be setup, call with @null_epoch set to true. In that case
1029
 * the epoch is fully initialized after call.
1030
 */
1031
int
1032
_gnutls_epoch_setup_next(gnutls_session_t session, unsigned null_epoch,
1033
       record_parameters_st ** newp)
1034
0
{
1035
0
  record_parameters_st **slot;
1036
1037
0
  slot = epoch_get_slot(session, session->security_parameters.epoch_next);
1038
1039
  /* If slot out of range or not empty. */
1040
0
  if (slot == NULL)
1041
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1042
1043
0
  if (*slot != NULL) { /* already initialized */
1044
0
    if (unlikely(null_epoch && !(*slot)->initialized))
1045
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1046
1047
0
    if (unlikely
1048
0
        ((*slot)->epoch != session->security_parameters.epoch_next))
1049
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1050
1051
0
    goto finish;
1052
0
  }
1053
1054
0
  _gnutls_record_log("REC[%p]: Allocating epoch #%u\n", session,
1055
0
         session->security_parameters.epoch_next);
1056
1057
0
  *slot = gnutls_calloc(1, sizeof(record_parameters_st));
1058
0
  if (*slot == NULL)
1059
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1060
1061
0
  (*slot)->epoch = session->security_parameters.epoch_next;
1062
1063
0
  if (null_epoch) {
1064
0
    (*slot)->cipher = cipher_to_entry(GNUTLS_CIPHER_NULL);
1065
0
    (*slot)->mac = mac_to_entry(GNUTLS_MAC_NULL);
1066
0
    (*slot)->initialized = 1;
1067
0
  } else {
1068
0
    (*slot)->cipher = NULL;
1069
0
    (*slot)->mac = NULL;
1070
0
  }
1071
1072
0
  if (IS_DTLS(session)) {
1073
0
    uint64_t seq = (*slot)->write.sequence_number;
1074
0
    seq &= UINT64_C(0xffffffffffff);
1075
0
    seq |=
1076
0
        ((uint64_t) session->security_parameters.epoch_next) << 48;
1077
0
    (*slot)->write.sequence_number = seq;
1078
0
  }
1079
1080
0
 finish:
1081
0
  if (newp != NULL)
1082
0
    *newp = *slot;
1083
1084
0
  return 0;
1085
0
}
1086
1087
static inline int
1088
epoch_is_active(gnutls_session_t session, record_parameters_st * params)
1089
0
{
1090
0
  const security_parameters_st *sp = &session->security_parameters;
1091
1092
0
  if (params->epoch == sp->epoch_read)
1093
0
    return 1;
1094
1095
0
  if (params->epoch == sp->epoch_write)
1096
0
    return 1;
1097
1098
0
  if (params->epoch == sp->epoch_next)
1099
0
    return 1;
1100
1101
0
  return 0;
1102
0
}
1103
1104
static inline int
1105
epoch_alive(gnutls_session_t session, record_parameters_st * params)
1106
0
{
1107
0
  if (params->usage_cnt > 0)
1108
0
    return 1;
1109
1110
0
  return epoch_is_active(session, params);
1111
0
}
1112
1113
void _gnutls_epoch_gc(gnutls_session_t session)
1114
0
{
1115
0
  int i, j;
1116
0
  unsigned int min_index = 0;
1117
1118
0
  _gnutls_record_log("REC[%p]: Start of epoch cleanup\n", session);
1119
1120
0
  gnutls_mutex_lock(&session->internals.epoch_lock);
1121
1122
  /* Free all dead cipher state */
1123
0
  for (i = 0; i < MAX_EPOCH_INDEX; i++) {
1124
0
    if (session->record_parameters[i] != NULL) {
1125
0
      if (!epoch_is_active
1126
0
          (session, session->record_parameters[i])
1127
0
          && session->record_parameters[i]->usage_cnt)
1128
0
        _gnutls_record_log
1129
0
            ("REC[%p]: Note inactive epoch %d has %d users\n",
1130
0
             session,
1131
0
             session->record_parameters[i]->epoch,
1132
0
             session->record_parameters[i]->usage_cnt);
1133
0
      if (!epoch_alive
1134
0
          (session, session->record_parameters[i])) {
1135
0
        _gnutls_epoch_free(session,
1136
0
               session->record_parameters
1137
0
               [i]);
1138
0
        session->record_parameters[i] = NULL;
1139
0
      }
1140
0
    }
1141
0
  }
1142
1143
  /* Look for contiguous NULLs at the start of the array */
1144
0
  for (i = 0;
1145
0
       i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL;
1146
0
       i++) ;
1147
0
  min_index = i;
1148
1149
  /* Pick up the slack in the epoch window. */
1150
0
  if (min_index != 0) {
1151
0
    for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++) {
1152
0
      session->record_parameters[i] =
1153
0
          session->record_parameters[j];
1154
0
      session->record_parameters[j] = NULL;
1155
0
    }
1156
0
  }
1157
1158
  /* Set the new epoch_min */
1159
0
  if (session->record_parameters[0] != NULL)
1160
0
    session->security_parameters.epoch_min =
1161
0
        session->record_parameters[0]->epoch;
1162
1163
0
  gnutls_mutex_unlock(&session->internals.epoch_lock);
1164
1165
0
  _gnutls_record_log("REC[%p]: End of epoch cleanup\n", session);
1166
0
}
1167
1168
static inline void free_record_state(record_state_st * state)
1169
0
{
1170
0
  zeroize_temp_key(state->mac_key, state->mac_key_size);
1171
0
  zeroize_temp_key(state->iv, state->iv_size);
1172
0
  zeroize_temp_key(state->key, state->key_size);
1173
1174
0
  if (state->is_aead)
1175
0
    _gnutls_aead_cipher_deinit(&state->ctx.aead);
1176
0
  else
1177
0
    _gnutls_auth_cipher_deinit(&state->ctx.tls12);
1178
0
}
1179
1180
void _gnutls_epoch_free(gnutls_session_t session, record_parameters_st * params)
1181
0
{
1182
0
  _gnutls_record_log("REC[%p]: Epoch #%u freed\n", session,
1183
0
         params->epoch);
1184
1185
0
  free_record_state(&params->read);
1186
0
  free_record_state(&params->write);
1187
1188
0
  gnutls_free(params);
1189
0
}
1190
1191
static int
1192
_gnutls_call_secret_func(gnutls_session_t session,
1193
       hs_stage_t stage, bool for_read, bool for_write)
1194
0
{
1195
0
  const mac_entry_st *prf = NULL;
1196
0
  gnutls_record_encryption_level_t level;
1197
0
  void *secret_read = NULL, *secret_write = NULL;
1198
1199
0
  if (session->internals.h_secret_func == NULL)
1200
0
    return 0;
1201
1202
0
  switch (stage) {
1203
0
  case STAGE_EARLY:
1204
0
    prf = session->key.binders[0].prf;
1205
0
    level = GNUTLS_ENCRYPTION_LEVEL_EARLY;
1206
0
    if (for_read) {
1207
0
      if (unlikely
1208
0
          (session->security_parameters.entity ==
1209
0
           GNUTLS_CLIENT))
1210
0
        return
1211
0
            gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1212
0
      secret_read = session->key.proto.tls13.e_ckey;
1213
0
    }
1214
0
    if (for_write) {
1215
0
      if (unlikely
1216
0
          (session->security_parameters.entity ==
1217
0
           GNUTLS_SERVER))
1218
0
        return
1219
0
            gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1220
0
      secret_write = session->key.proto.tls13.e_ckey;
1221
0
    }
1222
0
    break;
1223
0
  case STAGE_HS:
1224
0
    prf = session->security_parameters.prf;
1225
0
    level = GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE;
1226
0
    if (for_read)
1227
0
      secret_read =
1228
0
          session->security_parameters.entity ==
1229
0
          GNUTLS_CLIENT ? session->key.proto.
1230
0
          tls13.hs_skey : session->key.proto.tls13.hs_ckey;
1231
0
    if (for_write)
1232
0
      secret_write =
1233
0
          session->security_parameters.entity ==
1234
0
          GNUTLS_CLIENT ? session->key.proto.
1235
0
          tls13.hs_ckey : session->key.proto.tls13.hs_skey;
1236
0
    break;
1237
0
  case STAGE_APP:
1238
0
  case STAGE_UPD_OURS:
1239
0
  case STAGE_UPD_PEERS:
1240
0
    prf = session->security_parameters.prf;
1241
0
    level = GNUTLS_ENCRYPTION_LEVEL_APPLICATION;
1242
0
    if (for_read)
1243
0
      secret_read =
1244
0
          session->security_parameters.entity ==
1245
0
          GNUTLS_CLIENT ? session->key.proto.
1246
0
          tls13.ap_skey : session->key.proto.tls13.ap_ckey;
1247
0
    if (for_write)
1248
0
      secret_write =
1249
0
          session->security_parameters.entity ==
1250
0
          GNUTLS_CLIENT ? session->key.proto.
1251
0
          tls13.ap_ckey : session->key.proto.tls13.ap_skey;
1252
0
    break;
1253
0
  default:
1254
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1255
0
  }
1256
1257
0
  return session->internals.h_secret_func(session, level,
1258
0
            secret_read, secret_write,
1259
0
            prf->output_size);
1260
0
}
1261
1262
int _tls13_connection_state_init(gnutls_session_t session, hs_stage_t stage)
1263
0
{
1264
0
  const uint16_t epoch_next = session->security_parameters.epoch_next;
1265
0
  int ret;
1266
1267
0
  ret = _gnutls_epoch_set_keys(session, epoch_next, stage);
1268
0
  if (ret < 0)
1269
0
    return ret;
1270
1271
0
  _gnutls_handshake_log("HSK[%p]: TLS 1.3 re-key with cipher suite: %s\n",
1272
0
            session, session->security_parameters.cs->name);
1273
1274
0
  session->security_parameters.epoch_read = epoch_next;
1275
0
  session->security_parameters.epoch_write = epoch_next;
1276
1277
0
  ret = _gnutls_call_secret_func(session, stage, 1, 1);
1278
0
  if (ret < 0)
1279
0
    return gnutls_assert_val(ret);
1280
1281
0
  return 0;
1282
0
}
1283
1284
int _tls13_read_connection_state_init(gnutls_session_t session,
1285
              hs_stage_t stage)
1286
0
{
1287
0
  const uint16_t epoch_next = session->security_parameters.epoch_next;
1288
0
  int ret;
1289
1290
0
  if (unlikely(stage == STAGE_EARLY && !IS_SERVER(session))) {
1291
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1292
0
  }
1293
1294
0
  ret = _gnutls_epoch_set_keys(session, epoch_next, stage);
1295
0
  if (ret < 0)
1296
0
    return ret;
1297
1298
0
  _gnutls_handshake_log
1299
0
      ("HSK[%p]: TLS 1.3 set read key with cipher suite: %s\n", session,
1300
0
       stage ==
1301
0
       STAGE_EARLY ? session->internals.resumed_security_parameters.
1302
0
       cs->name : session->security_parameters.cs->name);
1303
1304
0
  session->security_parameters.epoch_read = epoch_next;
1305
1306
0
  ret = _gnutls_call_secret_func(session, stage, 1, 0);
1307
0
  if (ret < 0)
1308
0
    return gnutls_assert_val(ret);
1309
1310
0
  return 0;
1311
0
}
1312
1313
int _tls13_write_connection_state_init(gnutls_session_t session,
1314
               hs_stage_t stage)
1315
0
{
1316
0
  const uint16_t epoch_next = session->security_parameters.epoch_next;
1317
0
  int ret;
1318
1319
0
  if (unlikely(stage == STAGE_EARLY && IS_SERVER(session))) {
1320
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1321
0
  }
1322
1323
0
  ret = _gnutls_epoch_set_keys(session, epoch_next, stage);
1324
0
  if (ret < 0)
1325
0
    return ret;
1326
1327
0
  _gnutls_handshake_log
1328
0
      ("HSK[%p]: TLS 1.3 set write key with cipher suite: %s\n", session,
1329
0
       stage ==
1330
0
       STAGE_EARLY ? session->internals.resumed_security_parameters.
1331
0
       cs->name : session->security_parameters.cs->name);
1332
1333
0
  session->security_parameters.epoch_write = epoch_next;
1334
1335
0
  ret = _gnutls_call_secret_func(session, stage, 0, 1);
1336
0
  if (ret < 0)
1337
0
    return gnutls_assert_val(ret);
1338
1339
0
  return 0;
1340
0
}
1341
1342
static int
1343
_tls13_init_record_state(gnutls_cipher_algorithm_t algo,
1344
       record_state_st * state)
1345
0
{
1346
0
  int ret;
1347
0
  gnutls_datum_t key;
1348
1349
0
  key.data = state->key;
1350
0
  key.size = state->key_size;
1351
1352
0
  ret = _gnutls_aead_cipher_init(&state->ctx.aead, algo, &key);
1353
0
  if (ret < 0) {
1354
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
1355
0
    return gnutls_assert_val(ret);
1356
0
  }
1357
1358
0
  if (is_cipher_algo_allowed(algo))
1359
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
1360
0
  else
1361
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
1362
1363
0
  state->aead_tag_size = gnutls_cipher_get_tag_size(algo);
1364
0
  state->is_aead = 1;
1365
1366
0
  return 0;
1367
0
}
1368
1369
/**
1370
 * gnutls_handshake_set_secret_function:
1371
 * @session: is a #gnutls_session_t type.
1372
 * @func: the secret func
1373
 *
1374
 * This function will set a callback to be called when a new traffic
1375
 * secret is installed.
1376
 *
1377
 * Since: 3.7.0
1378
 */
1379
void
1380
gnutls_handshake_set_secret_function(gnutls_session_t session,
1381
             gnutls_handshake_secret_func func)
1382
0
{
1383
0
  session->internals.h_secret_func = func;
1384
0
}